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 const MED_EN::medGeometryElement * getTypes(MED_EN::medEntityMesh Entity) const;
213 inline const CELLMODEL * getCellsTypes(MED_EN::medEntityMesh Entity) const;
215 const int * getGlobalNumberingIndex(MED_EN::medEntityMesh Entity) const;
217 inline int getNumberOfElements(MED_EN::medEntityMesh Entity,
218 MED_EN::medGeometryElement Type) const;
220 inline bool existConnectivity(MED_EN::medConnectivity ConnectivityType,
221 MED_EN::medEntityMesh Entity) const;
223 inline MED_EN::medGeometryElement getElementType(MED_EN::medEntityMesh Entity,
226 inline void calculateConnectivity(MED_EN::medModeSwitch Mode,
227 MED_EN::medConnectivity ConnectivityType,
228 MED_EN::medEntityMesh Entity) const ;
230 inline const CONNECTIVITY* getConnectivityptr() const;
232 inline const int * getConnectivity(MED_EN::medModeSwitch Mode,
233 MED_EN::medConnectivity ConnectivityType,
234 MED_EN::medEntityMesh Entity,
235 MED_EN::medGeometryElement Type) const;
237 inline const int * getConnectivityIndex(MED_EN::medConnectivity ConnectivityType,
238 MED_EN::medEntityMesh Entity) const;
240 inline const int * getReverseConnectivity(MED_EN::medConnectivity ConnectivityType,
241 MED_EN::medEntityMesh Entity=MED_EN::MED_CELL) const;
243 inline const int * getReverseConnectivityIndex(MED_EN::medConnectivity ConnectivityType,
244 MED_EN::medEntityMesh Entity=MED_EN::MED_CELL) const;
248 inline void setGridType(MED_EN::med_grid_type gridType);
250 friend class MED_MESH_RDONLY_DRIVER;
251 friend class MED_MESH_WRONLY_DRIVER;
256 //----------------------------------//
257 // Inline Methods Implementation
258 //----------------------------------//
260 inline MED_EN::med_grid_type GRID::getGridType() const
264 //=======================================================================
265 //function : getNodeNumber
267 //=======================================================================
269 inline int GRID::getNodeNumber(const int i, const int j, const int k) const
271 return 1 + i + _iArrayLength * j + _iArrayLength * _jArrayLength * k;
274 //=======================================================================
275 //function : getCellNumber
277 //=======================================================================
279 inline int GRID::getCellNumber(const int i, const int j, const int k) const
281 return 1 + i + (_iArrayLength-1) * j + (_iArrayLength-1) * (_jArrayLength-1) * k;
284 //=======================================================================
285 //function : makeUnstructured
286 //purpose : fill coordinates and connectivity of MESH
287 //=======================================================================
289 inline void GRID::makeUnstructured()
295 //=======================================================================
296 //function : setGridType
297 //purpose : set the _gridType field od the class GRID
298 //=======================================================================
300 inline void GRID::setGridType(MED_EN::med_grid_type gridType)
302 _gridType = gridType;
305 /*! Get the COORDINATES object. Use it only if you need COORDINATES informations not provided by the GRID class via the MESH class.*/
306 inline const COORDINATE * GRID::getCoordinateptr() const
312 /*! Get the whole coordinates array in a given interlacing mode. The interlacing mode are :
313 - MED_NO_INTERLACE : X1 X2 Y1 Y2 Z1 Z2
314 - MED_FULL_INTERLACE : X1 Y1 Z1 X2 Y2 Z2
316 inline const double * GRID::getCoordinates(MED_EN::medModeSwitch Mode) const
319 return _coordinate->getCoordinates(Mode);
322 /*! Get the coordinate n° number on axis n°axis*/
323 inline const double GRID::getCoordinate(int number, int axis) const
326 return _coordinate->getCoordinate(number,axis);
329 /*! Get the number of different geometric types for a given entity type.
331 medEntityMesh entity : MED_CELL, MED_FACE, MED_EDGE, MED_NODE,
335 inline int GRID::getNumberOfTypes(MED_EN::medEntityMesh entity) const
337 MESSAGE("GRID::getNumberOfTypes(medEntityMesh entity) : "<<entity);
338 return 1; // a grid has one type
342 Get the whole list of CELLMODEL used by cells of given type (medEntityMesh).
344 REMARK : Don't use MED_NODE as medEntityMesh
346 inline const CELLMODEL * GRID::getCellsTypes(MED_EN::medEntityMesh Entity) const
350 if (_connectivity != NULL)
351 return _connectivity->getCellsTypes(Entity);
352 throw MEDEXCEPTION(LOCALIZED("GRID::getCellsTypes( medEntityMesh ) : Connectivity not defined !"));
355 /*! Return an array of size NumbreOfTypes+1 which contains, for each
356 geometric type of the given entity, the first global element number
359 For exemple, if we have a mesh with 5 triangles and 4 quadrangle :
360 - size of GlobalNumberingIndex is 3
361 - GlobalNumberingIndex[0]=1 (the first type)
362 - GlobalNumberingIndex[1]=6 (the second type)
363 - GlobalNumberingIndex[2]=10
365 inline const int * GRID::getGlobalNumberingIndex(MED_EN::medEntityMesh entity) const
369 if (_connectivity != NULL)
370 return _connectivity->getGlobalNumberingIndex(entity);
371 throw MEDEXCEPTION(LOCALIZED("GRID::getNumberOfTypes( medEntityMesh ) : Connectivity not defined !"));
375 Return the number of element of given geometric type of given entity. Return 0 if query is not defined.
377 inline int GRID::getNumberOfElements(MED_EN::medEntityMesh entity, MED_EN::medGeometryElement Type) const
379 int numberOfElements=0;
381 // Cas où le nombre d'éléments n'est pas nul
382 if (entity==MED_EN::MED_FACE && (Type==MED_EN::MED_QUAD4 || Type==MED_EN::MED_ALL_ELEMENTS) && _spaceDimension>2)
383 numberOfElements=(_iArrayLength-1)*(_jArrayLength-1);
385 else if (entity==MED_EN::MED_EDGE && (Type==MED_EN::MED_SEG2 || Type==MED_EN::MED_ALL_ELEMENTS) && _spaceDimension>1)
386 numberOfElements=_iArrayLength-1;
388 else if (entity==MED_EN::MED_NODE && (Type==MED_EN::MED_NONE || Type==MED_EN::MED_ALL_ELEMENTS) && _spaceDimension>0)
389 numberOfElements=_numberOfNodes;
391 else if (entity==MED_EN::MED_CELL && _spaceDimension==3 && (Type==MED_EN::MED_HEXA8 || Type==MED_EN::MED_ALL_ELEMENTS) )
392 numberOfElements=(_iArrayLength-1)*(_jArrayLength-1)*(_kArrayLength-1);
394 else if (entity==MED_EN::MED_CELL && _spaceDimension==2 && (Type==MED_EN::MED_QUAD4 || Type==MED_EN::MED_ALL_ELEMENTS))
395 numberOfElements=(_iArrayLength-1)*(_jArrayLength-1);
397 else if (entity==MED_EN::MED_CELL && _spaceDimension==1 && (Type==MED_EN::MED_SEG2 || Type==MED_EN::MED_ALL_ELEMENTS) )
398 numberOfElements=_iArrayLength-1;
400 MESSAGE("GRID::getNumberOfElements - entity=" << entity << " Type=" << Type);
401 MESSAGE("_spaceDimension=" << _spaceDimension << " numberOfElements=" << numberOfElements);
403 return numberOfElements;
408 Return true if the wanted connectivity exist, else return false
409 (to use before a getSomething method).
411 inline bool GRID::existConnectivity(MED_EN::medConnectivity connectivityType, MED_EN::medEntityMesh entity) const
415 if (_connectivity==(CONNECTIVITY*)NULL)
416 throw MEDEXCEPTION("GRID::existConnectivity(medConnectivity,medEntityMesh) : no connectivity defined !");
417 return _connectivity->existConnectivity(connectivityType,entity);
421 Return the geometric type of global element Number of entity Entity.
423 Throw an exception if Entity is not defined or Number are wrong (too big).
425 inline MED_EN::medGeometryElement GRID::getElementType(MED_EN::medEntityMesh Entity,int Number) const
429 if (_connectivity==(CONNECTIVITY*)NULL)
430 throw MEDEXCEPTION("GRID::getElementType(medEntityMesh,int) : no connectivity defined !");
431 return _connectivity->getElementType(Entity,Number);
435 Calculate the ask connectivity. Return an exception if this could not be
436 done. Do nothing if connectivity already exist.
439 inline void GRID::calculateConnectivity(MED_EN::medModeSwitch Mode,MED_EN::medConnectivity ConnectivityType,MED_EN::medEntityMesh entity) const
443 if (Mode==MED_EN::MED_FULL_INTERLACE)
444 _connectivity->calculateConnectivity(ConnectivityType,entity);
446 throw MEDEXCEPTION(LOCALIZED("GRID::calculateConnectivity : only for MED_FULL_INTERLACE mode"));
449 inline const CONNECTIVITY* GRID::getConnectivityptr() const
453 return _connectivity;
457 Return the required connectivity in the right mode for the given
458 geometric type of the given entity.
460 To get connectivity for all geometric type, use Mode=MED_FULL_INTERLACE
461 and Type=MED_ALL_ELEMENTS.
462 You must also get the corresponding index array.
464 inline const int * GRID::getConnectivity(MED_EN::medModeSwitch Mode,MED_EN::medConnectivity ConnectivityType,MED_EN::medEntityMesh entity, MED_EN::medGeometryElement Type) const
468 if (Mode==MED_EN::MED_FULL_INTERLACE)
469 return _connectivity->getConnectivity(ConnectivityType,entity,Type);
470 throw MEDEXCEPTION(LOCALIZED("GRID::getConnectivity : only for MED_FULL_INTERLACE mode"));
474 Return the required index array for a connectivity received in
475 MED_FULL_ENTERLACE mode and MED_ALL_ELEMENTS type.
477 This array allow to find connectivity of each elements.
479 Example : Connectivity of i^{th} elements (1<=i<=NumberOfElement) begin
480 at index ConnectivityIndex[i-1] and end at index ConnectivityIndex[i]-1
481 in Connectivity array (Connectivity[ConnectivityIndex[i-1]-1] is the
484 inline const int * GRID::getConnectivityIndex(MED_EN::medConnectivity ConnectivityType,MED_EN::medEntityMesh entity) const
488 return _connectivity->getConnectivityIndex(ConnectivityType, entity);
492 Return the reverse connectivity required by ConnectivityType :
493 - If ConnectivityType=MED_NODAL : return connectivity node-cell
494 - If ConnectivityType=MED_DESCENDING : return connectivity face-cell
496 You must get ReverseConnectivityIndex array to use it.
498 inline const int * GRID::getReverseConnectivity(MED_EN::medConnectivity ConnectivityType,MED_EN::medEntityMesh Entity/*=MED_CELL*/) const
502 if (NULL==_connectivity)
503 throw MEDEXCEPTION("GRID::getReverseConnectivity : no connectivity defined in MESH !");
505 return _connectivity->getReverseConnectivity(ConnectivityType,Entity);
509 Return the index array required by ConnectivityType.
511 This array allow to find reverse connectivity of each elements.
513 Example : Reverse connectivity of i^{th} elements (1<=i<=NumberOfElement)
514 begin at index ReverseConnectivityIndex[i-1] and end at index
515 ReverseConnectivityIndex[i]-1
516 in ReverseConnectivity array (
517 ReverseConnectivity[ReverseConnectivityIndex[i-1]-1]
520 inline const int * GRID::getReverseConnectivityIndex(MED_EN::medConnectivity ConnectivityType,MED_EN::medEntityMesh Entity/*=MED_CELL*/) const
524 if (NULL==_connectivity)
525 throw MEDEXCEPTION("GRID::getReverseConnectivityIndex : no connectivity defined in MESH !");
527 return _connectivity->getReverseConnectivityIndex(ConnectivityType,Entity);