1 // File : MEDMEM_Grid.hxx
2 // Created : Wed Dec 18 08:35:26 2002
3 // Descr : class containing structured mesh data
5 // Author : Edward AGAPOV (eap)
6 // Project : SALOME Pro
8 // Copyright : Open CASCADE
11 #ifndef MEDMEM_Grid_HeaderFile
12 #define MEDMEM_Grid_HeaderFile
14 #include "MEDMEM_Mesh.hxx"
16 // class containing structured mesh data
19 class GRID: public MESH
22 //-----------------------//
24 //-----------------------//
26 // 1. grid type: MED_CARTESIAN, MED_POLAR, MED_BODY_FITTED
27 MED_EN::med_grid_type _gridType;
29 // 2. node coordinates
30 // For MED_BODY_FITTED MESH::_coordinate is used
32 // 2.1. i component array: X for MED_CARTESIAN, R for MED_POLAR
35 // 2.2. j component array: Y for MED_CARTESIAN, Theta for MED_POLAR
38 // 2.3. k component array: Z for both MED_CARTESIAN and MED_POLAR
42 // 3. flags to know that _coordinates and _connectivity of MESH are filled
43 bool _is_coordinates_filled;
44 bool _is_connectivity_filled;
46 //-----------------------//
48 //-----------------------//
50 CONNECTIVITY * makeConnectivity (const MED_EN::medEntityMesh Entity, const MED_EN::medGeometryElement Geometry,
51 const int NbEntities, int NbNodes, int nbMeshNodes,
52 const int * NodeNumbers) const ;
53 // creates nodal connectivity
56 // Suppose a READ Driver to do the following except filling _[ijk]Array's
57 // 1) fill MESH fields:
61 // * _numberOfNodesFamilies, _numberOfCellsFamilies, ect
62 // * _familyNode, _familyCell, etc
63 // * _numberOfNodesGroups, _numberOfCellsGroups, etc
64 // * _groupNode, _groupCell, etc
66 // 2) create MESH::_coordinate without setting _coordinate->_coordinate and set:
67 // * _coordinate->_coordinateSystem
68 // * _coordinate->_coordinateName
69 // * _coordinate->_coordinateUnit
73 //-----------------------//
75 //-----------------------//
78 GRID(const MED_EN::med_grid_type type);
80 GRID( driverTypes driverType, const string & fileName="",const string & meshName="");
81 GRID(const std::vector<std::vector<double> >& xyz_array,const std::vector<std::string>& coord_name,
82 const std::vector<std::string>& coord_unit, const MED_EN::med_grid_type type=MED_EN::MED_CARTESIAN);
83 GRID & operator=(const GRID &m);
87 void fillCoordinates() const ;
88 void fillConnectivity() const ;
89 // fill _coordinates and _connectivity of MESH if not yet done
91 inline void makeUnstructured();
92 // fill both coordinates and connectivity of MESH
94 void fillMeshAfterRead();
95 // fill some fields (_numberOfNodes, etc.) after reading
97 void writeUnstructured(int index=0, const string & driverName = "");
98 // write a Grid as an Unstructured mesh
100 void read(int index=0);
102 // API Methods returning fields of MESH that are filled while reading.
103 // So they need not to be redefined
105 // string getName() const;
106 // int getSpaceDimension();
107 // int getMeshDimension();
108 // string getCoordinatesSystem();
109 // int getNumberOfNodes();
110 // string * getCoordinatesNames();
111 // string * getCoordinatesUnits();
112 // int getNumberOfFamilies(medEntityMesh Entity);
113 // vector<FAMILY*> getFamilies(medEntityMesh Entity);
114 // FAMILY* getFamily(medEntityMesh Entity,int i);
115 // int getNumberOfGroups(medEntityMesh Entity);
116 // vector<GROUP*> getGroups(medEntityMesh Entity);
117 // GROUP* getGroup(medEntityMesh Entity,int i);
120 // Since a MESH itself knows if it is a GRID, it calls fillConnectivity()
121 // or fillCoordinates() whenever needed. So no redifinition of the following methods
123 // const double * getCoordinates(medModeSwitch Mode);
124 // COORDINATE * getCoordinateptr();
125 // const double getCoordinate(int Number,int Axis);
126 // int getNumberOfTypes(medEntityMesh Entity);
127 // medGeometryElement * getTypes(medEntityMesh Entity);
128 // CELLMODEL * getCellsTypes(medEntityMesh Entity);
129 // medGeometryElement getElementType(medEntityMesh Entity,int Number) ;
130 // int getNumberOfElements(medEntityMesh Entity,medGeometryElement Type);
131 // int getElementNumber(medConnectivity ConnectivityType, medEntityMesh Entity, medGeometryElement Type, int * connectivity) ;
132 // int * getGlobalNumberingIndex(medEntityMesh Entity);
133 // int * getConnectivity(medModeSwitch Mode,medConnectivity ConnectivityType,medEntityMesh Entity, medGeometryElement Type);
134 // int * getConnectivityIndex(medConnectivity ConnectivityType,medEntityMesh Entity);
135 // int * getReverseConnectivity(medConnectivity ConnectivityType);
136 // int * getReverseConnectivityIndex(medConnectivity ConnectivityType);
137 // bool existConnectivity(medConnectivity ConnectivityType,medEntityMesh Entity);
138 // void calculateConnectivity(medModeSwitch Mode,medConnectivity ConnectivityType,medEntityMesh Entity);
139 // FIELD<double>* getVolume(const SUPPORT * Support) throw (MEDEXCEPTION) ;
140 // FIELD<double>* getArea(const SUPPORT * Support) throw (MEDEXCEPTION) ;
141 // FIELD<double>* getLength(const SUPPORT * Support) throw (MEDEXCEPTION) ;
142 // FIELD<double>* getNormal(const SUPPORT * Support) throw (MEDEXCEPTION) ;
143 // FIELD<double>* getBarycenter(const SUPPORT * Support) throw (MEDEXCEPTION) ;
146 // Specific GRID methods
148 inline int getNodeNumber(const int i, const int j=0, const int k=0) const;
149 // return a NODE number by its position in the grid.
150 // WARNING: be carefull, there is no check that i,j,k are within a good range
151 // A good range is: 0 <= X < getArrayLength( X_Axis )
152 inline int getCellNumber(const int i, const int j=0, const int k=0) const ;
153 // return a CELL number by its position in the grid.
154 // WARNING: be carefull, there is no check that i,j,k are within a good range
155 // A good range is: 0 <= X < (getArrayLength( X_Axis )-1)
157 int getEdgeNumber(const int Axis, const int i, const int j=0, const int k=0) const throw (MEDEXCEPTION) ;
158 // return an EDGE number by its position in the grid.
159 // Axis [1,2,3] means one of directions: along i, j or k.
160 // It selects an edge of ones having same (i,j,k):
161 // * an EDGE going along given Axis.
162 // Exception for Axis out of range or when there is no edges in the grid (1D)
163 // WARNING: be carefull, there is no check that i,j,k are within a good range
165 // 0 <= X < (getArrayLength( X_Axis )-1)
166 // 0 <= X < getArrayLength( NOT_X_Axis )
168 int getFaceNumber(const int Axis, const int i, const int j=0, const int k=0) const throw (MEDEXCEPTION) ;
169 // return a FACE number by its position in the grid.
170 // Axis [1,2,3] means one of directions: along i, j or k.
171 // It selects a face of ones having same (i,j,k):
172 // * a FACE which is normal to given Axis
173 // Exception for Axis out of range or when there is no faces in the grid (1,2D)
174 // WARNING: be carefull, there is no check that i,j,k are within a good range
176 // 0 <= X < (getArrayLength( NOT_X_Axis )-1)
177 // 0 <= X < getArrayLength( X_Axis )
180 void getNodePosition(const int Number, int& i, int& j, int& k) const throw (MEDEXCEPTION) ;
181 void getCellPosition(const int Number, int& i, int& j, int& k) const throw (MEDEXCEPTION) ;
182 void getEdgePosition(const int Number, int& Axis, int& i, int& j, int& k) const throw (MEDEXCEPTION) ;
183 void getFacePosition(const int Number, int& Axis, int& i, int& j, int& k) const throw (MEDEXCEPTION) ;
184 // return position (i,j,k) of an entity #Number
185 // Axis: [1,2,3], see get*Number for details
186 // Exception for Number out of range
191 inline MED_EN::med_grid_type getGridType() const;
192 // return MED_CARTESIAN, MED_POLAR or MED_BODY_FITTED
194 int getArrayLength( const int Axis ) const throw (MEDEXCEPTION);
195 // return array length. Axis = [1,2,3] meaning [i,j,k],
196 // exception if Axis out of [1-3] range
198 const double getArrayValue (const int Axis, const int i) const throw (MEDEXCEPTION) ;
199 // return i-th array component. Axis = [1,2,3] meaning [i,j,k],
200 // exception if Axis out of [1 - 3] range
201 // exception if i is out of range [0 - (getArrayLength(Axis)-1)];
203 inline const COORDINATE * getCoordinateptr() const;
205 inline const double * getCoordinates(MED_EN::medModeSwitch Mode) const;
207 inline const double getCoordinate(int Number,int Axis) const;
209 inline int getNumberOfTypes(MED_EN::medEntityMesh Entity) const;
211 inline int getNumberOfTypesWithPoly(MED_EN::medEntityMesh Entity) const;
213 inline const MED_EN::medGeometryElement * getTypes(MED_EN::medEntityMesh Entity) const;
215 MED_EN::medGeometryElement * getTypesWithPoly(MED_EN::medEntityMesh Entity) const;
217 inline const CELLMODEL * getCellsTypes(MED_EN::medEntityMesh Entity) const;
219 const int * getGlobalNumberingIndex(MED_EN::medEntityMesh Entity) const;
221 inline int getNumberOfElements(MED_EN::medEntityMesh Entity,
222 MED_EN::medGeometryElement Type) const;
224 inline int getNumberOfElementsWithPoly(MED_EN::medEntityMesh Entity,
225 MED_EN::medGeometryElement Type) const;
227 inline bool existConnectivity(MED_EN::medConnectivity ConnectivityType,
228 MED_EN::medEntityMesh Entity) const;
230 inline MED_EN::medGeometryElement getElementType(MED_EN::medEntityMesh Entity,
233 inline MED_EN::medGeometryElement getElementTypeWithPoly(MED_EN::medEntityMesh Entity,
236 inline void calculateConnectivity(MED_EN::medModeSwitch Mode,
237 MED_EN::medConnectivity ConnectivityType,
238 MED_EN::medEntityMesh Entity) const ;
240 inline const CONNECTIVITY* getConnectivityptr() const;
242 inline const int * getConnectivity(MED_EN::medModeSwitch Mode,
243 MED_EN::medConnectivity ConnectivityType,
244 MED_EN::medEntityMesh Entity,
245 MED_EN::medGeometryElement Type) const;
247 inline const int * getConnectivityIndex(MED_EN::medConnectivity ConnectivityType,
248 MED_EN::medEntityMesh Entity) const;
250 inline const int * getReverseConnectivity(MED_EN::medConnectivity ConnectivityType,
251 MED_EN::medEntityMesh Entity=MED_EN::MED_CELL) const;
253 inline const int * getReverseConnectivityIndex(MED_EN::medConnectivity ConnectivityType,
254 MED_EN::medEntityMesh Entity=MED_EN::MED_CELL) const;
258 inline void setGridType(MED_EN::med_grid_type gridType);
260 friend class IMED_MESH_RDONLY_DRIVER;
261 friend class IMED_MESH_WRONLY_DRIVER;
262 friend class MED_MESH_RDONLY_DRIVER21;
263 friend class MED_MESH_WRONLY_DRIVER21;
264 friend class MED_MESH_RDONLY_DRIVER22;
265 friend class MED_MESH_WRONLY_DRIVER22;
269 //----------------------------------//
270 // Inline Methods Implementation
271 //----------------------------------//
273 inline MED_EN::med_grid_type GRID::getGridType() const
277 //=======================================================================
278 //function : getNodeNumber
280 //=======================================================================
282 inline int GRID::getNodeNumber(const int i, const int j, const int k) const
284 return 1 + i + _iArrayLength * j + _iArrayLength * _jArrayLength * k;
287 //=======================================================================
288 //function : getCellNumber
290 //=======================================================================
292 inline int GRID::getCellNumber(const int i, const int j, const int k) const
294 return 1 + i + (_iArrayLength-1) * j + (_iArrayLength-1) * (_jArrayLength-1) * k;
297 //=======================================================================
298 //function : makeUnstructured
299 //purpose : fill coordinates and connectivity of MESH
300 //=======================================================================
302 inline void GRID::makeUnstructured()
308 //=======================================================================
309 //function : setGridType
310 //purpose : set the _gridType field od the class GRID
311 //=======================================================================
313 inline void GRID::setGridType(MED_EN::med_grid_type gridType)
315 _gridType = gridType;
318 /*! Get the COORDINATES object. Use it only if you need COORDINATES informations not provided by the GRID class via the MESH class.*/
319 inline const COORDINATE * GRID::getCoordinateptr() const
325 /*! Get the whole coordinates array in a given interlacing mode. The interlacing mode are :
326 - MED_NO_INTERLACE : X1 X2 Y1 Y2 Z1 Z2
327 - MED_FULL_INTERLACE : X1 Y1 Z1 X2 Y2 Z2
329 inline const double * GRID::getCoordinates(MED_EN::medModeSwitch Mode) const
332 return _coordinate->getCoordinates(Mode);
335 /*! Get the coordinate n° number on axis n°axis*/
336 inline const double GRID::getCoordinate(int number, int axis) const
339 return _coordinate->getCoordinate(number,axis);
342 /*! Get the number of different geometric types for a given entity type.
344 medEntityMesh entity : MED_CELL, MED_FACE, MED_EDGE, MED_NODE,
348 inline int GRID::getNumberOfTypes(MED_EN::medEntityMesh entity) const
350 MESSAGE("GRID::getNumberOfTypes(medEntityMesh entity) : "<<entity);
351 return 1; // a grid has one type
355 inline int GRID::getNumberOfTypesWithPoly(MED_EN::medEntityMesh entity) const
357 MESSAGE("GRID::getNumberOfTypes(medEntityMesh entity) : "<<entity);
358 return 1; // a grid has one type
362 Get the whole list of CELLMODEL used by cells of given type (medEntityMesh).
364 REMARK : Don't use MED_NODE as medEntityMesh
366 inline const CELLMODEL * GRID::getCellsTypes(MED_EN::medEntityMesh Entity) const
370 if (_connectivity != NULL)
371 return _connectivity->getCellsTypes(Entity);
372 throw MEDEXCEPTION(LOCALIZED("GRID::getCellsTypes( medEntityMesh ) : Connectivity not defined !"));
375 /*! Return an array of size NumbreOfTypes+1 which contains, for each
376 geometric type of the given entity, the first global element number
379 For exemple, if we have a mesh with 5 triangles and 4 quadrangle :
380 - size of GlobalNumberingIndex is 3
381 - GlobalNumberingIndex[0]=1 (the first type)
382 - GlobalNumberingIndex[1]=6 (the second type)
383 - GlobalNumberingIndex[2]=10
385 inline const int * GRID::getGlobalNumberingIndex(MED_EN::medEntityMesh entity) const
389 if (_connectivity != NULL)
390 return _connectivity->getGlobalNumberingIndex(entity);
391 throw MEDEXCEPTION(LOCALIZED("GRID::getNumberOfTypes( medEntityMesh ) : Connectivity not defined !"));
395 Return the number of element of given geometric type of given entity. Return 0 if query is not defined.
397 inline int GRID::getNumberOfElements(MED_EN::medEntityMesh entity, MED_EN::medGeometryElement Type) const
399 int numberOfElements=0;
401 // Cas où le nombre d'éléments n'est pas nul
402 if (entity==MED_EN::MED_FACE && (Type==MED_EN::MED_QUAD4 || Type==MED_EN::MED_ALL_ELEMENTS) && _spaceDimension>2)
403 numberOfElements=(_iArrayLength-1)*(_jArrayLength-1);
405 else if (entity==MED_EN::MED_EDGE && (Type==MED_EN::MED_SEG2 || Type==MED_EN::MED_ALL_ELEMENTS) && _spaceDimension>1)
406 numberOfElements=_iArrayLength-1;
408 else if (entity==MED_EN::MED_NODE && (Type==MED_EN::MED_NONE || Type==MED_EN::MED_ALL_ELEMENTS) && _spaceDimension>0)
409 numberOfElements=_numberOfNodes;
411 else if (entity==MED_EN::MED_CELL && _spaceDimension==3 && (Type==MED_EN::MED_HEXA8 || Type==MED_EN::MED_ALL_ELEMENTS) )
412 numberOfElements=(_iArrayLength-1)*(_jArrayLength-1)*(_kArrayLength-1);
414 else if (entity==MED_EN::MED_CELL && _spaceDimension==2 && (Type==MED_EN::MED_QUAD4 || Type==MED_EN::MED_ALL_ELEMENTS))
415 numberOfElements=(_iArrayLength-1)*(_jArrayLength-1);
417 else if (entity==MED_EN::MED_CELL && _spaceDimension==1 && (Type==MED_EN::MED_SEG2 || Type==MED_EN::MED_ALL_ELEMENTS) )
418 numberOfElements=_iArrayLength-1;
420 MESSAGE("GRID::getNumberOfElements - entity=" << entity << " Type=" << Type);
421 MESSAGE("_spaceDimension=" << _spaceDimension << " numberOfElements=" << numberOfElements);
423 return numberOfElements;
426 int GRID::getNumberOfElementsWithPoly(MED_EN::medEntityMesh entity, MED_EN::medGeometryElement Type) const
428 return getNumberOfElements(entity,Type);
433 Return true if the wanted connectivity exist, else return false
434 (to use before a getSomething method).
436 inline bool GRID::existConnectivity(MED_EN::medConnectivity connectivityType, MED_EN::medEntityMesh entity) const
440 if (_connectivity==(CONNECTIVITY*)NULL)
441 throw MEDEXCEPTION("GRID::existConnectivity(medConnectivity,medEntityMesh) : no connectivity defined !");
442 return _connectivity->existConnectivity(connectivityType,entity);
446 Return the geometric type of global element Number of entity Entity.
448 Throw an exception if Entity is not defined or Number are wrong (too big).
450 inline MED_EN::medGeometryElement GRID::getElementType(MED_EN::medEntityMesh Entity,int Number) const
454 if (_connectivity==(CONNECTIVITY*)NULL)
455 throw MEDEXCEPTION("GRID::getElementType(medEntityMesh,int) : no connectivity defined !");
456 return _connectivity->getElementType(Entity,Number);
459 inline MED_EN::medGeometryElement GRID::getElementTypeWithPoly(MED_EN::medEntityMesh Entity,int Number) const
461 return getElementType(Entity,Number);
465 Calculate the ask connectivity. Return an exception if this could not be
466 done. Do nothing if connectivity already exist.
469 inline void GRID::calculateConnectivity(MED_EN::medModeSwitch Mode,MED_EN::medConnectivity ConnectivityType,MED_EN::medEntityMesh entity) const
473 if (Mode==MED_EN::MED_FULL_INTERLACE)
474 _connectivity->calculateConnectivity(ConnectivityType,entity);
476 throw MEDEXCEPTION(LOCALIZED("GRID::calculateConnectivity : only for MED_FULL_INTERLACE mode"));
479 inline const CONNECTIVITY* GRID::getConnectivityptr() const
483 return _connectivity;
487 Return the required connectivity in the right mode for the given
488 geometric type of the given entity.
490 To get connectivity for all geometric type, use Mode=MED_FULL_INTERLACE
491 and Type=MED_ALL_ELEMENTS.
492 You must also get the corresponding index array.
494 inline const int * GRID::getConnectivity(MED_EN::medModeSwitch Mode,MED_EN::medConnectivity ConnectivityType,MED_EN::medEntityMesh entity, MED_EN::medGeometryElement Type) const
498 if (Mode==MED_EN::MED_FULL_INTERLACE)
499 return _connectivity->getConnectivity(ConnectivityType,entity,Type);
500 throw MEDEXCEPTION(LOCALIZED("GRID::getConnectivity : only for MED_FULL_INTERLACE mode"));
504 Return the required index array for a connectivity received in
505 MED_FULL_ENTERLACE mode and MED_ALL_ELEMENTS type.
507 This array allow to find connectivity of each elements.
509 Example : Connectivity of i^{th} elements (1<=i<=NumberOfElement) begin
510 at index ConnectivityIndex[i-1] and end at index ConnectivityIndex[i]-1
511 in Connectivity array (Connectivity[ConnectivityIndex[i-1]-1] is the
514 inline const int * GRID::getConnectivityIndex(MED_EN::medConnectivity ConnectivityType,MED_EN::medEntityMesh entity) const
518 return _connectivity->getConnectivityIndex(ConnectivityType, entity);
522 Return the reverse connectivity required by ConnectivityType :
523 - If ConnectivityType=MED_NODAL : return connectivity node-cell
524 - If ConnectivityType=MED_DESCENDING : return connectivity face-cell
526 You must get ReverseConnectivityIndex array to use it.
528 inline const int * GRID::getReverseConnectivity(MED_EN::medConnectivity ConnectivityType,MED_EN::medEntityMesh Entity/*=MED_CELL*/) const
532 if (NULL==_connectivity)
533 throw MEDEXCEPTION("GRID::getReverseConnectivity : no connectivity defined in MESH !");
535 return _connectivity->getReverseConnectivity(ConnectivityType,Entity);
539 Return the index array required by ConnectivityType.
541 This array allow to find reverse connectivity of each elements.
543 Example : Reverse connectivity of i^{th} elements (1<=i<=NumberOfElement)
544 begin at index ReverseConnectivityIndex[i-1] and end at index
545 ReverseConnectivityIndex[i]-1
546 in ReverseConnectivity array (
547 ReverseConnectivity[ReverseConnectivityIndex[i-1]-1]
550 inline const int * GRID::getReverseConnectivityIndex(MED_EN::medConnectivity ConnectivityType,MED_EN::medEntityMesh Entity/*=MED_CELL*/) const
554 if (NULL==_connectivity)
555 throw MEDEXCEPTION("GRID::getReverseConnectivityIndex : no connectivity defined in MESH !");
557 return _connectivity->getReverseConnectivityIndex(ConnectivityType,Entity);