1 // Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : MEDMEM_Grid.hxx
23 // Created : Wed Dec 18 08:35:26 2002
24 // Descr : class containing structured mesh data
25 // Author : Edward AGAPOV (eap)
26 // Project : SALOME Pro
29 #ifndef MEDMEM_Grid_HeaderFile
30 #define MEDMEM_Grid_HeaderFile
34 #include "MEDMEM_Mesh.hxx"
36 // class containing structured mesh data
39 class MEDMEM_EXPORT GRID: public MESH
42 //-----------------------//
44 //-----------------------//
46 // 1. grid type: MED_CARTESIAN, MED_POLAR, MED_BODY_FITTED
47 MED_EN::med_grid_type _gridType;
49 // 2. node coordinates
50 // For MED_BODY_FITTED MESH::_coordinate is used
52 // 2.1. i component array: X for MED_CARTESIAN, R for MED_POLAR
55 // 2.2. j component array: Y for MED_CARTESIAN, Theta for MED_POLAR
58 // 2.3. k component array: Z for both MED_CARTESIAN and MED_POLAR
62 // 3. flags to know that _coordinates and _connectivity of MESH are filled
63 bool _is_coordinates_filled;
64 bool _is_connectivity_filled;
66 // 4. is _gridType a true value or just a default one
67 bool _is_default_gridType;
69 //-----------------------//
71 //-----------------------//
73 CONNECTIVITY * makeConnectivity (const MED_EN::medEntityMesh Entity, const MED_EN::medGeometryElement Geometry,
74 const int NbEntities, int NbNodes, int nbMeshNodes,
75 const int * NodeNumbers) const ;
76 // creates nodal connectivity
79 // Suppose a READ Driver to do the following except filling _[ijk]Array's
80 // 1) fill MESH fields:
84 // * _numberOfNodesFamilies, _numberOfCellsFamilies, ect
85 // * _familyNode, _familyCell, etc
86 // * _numberOfNodesGroups, _numberOfCellsGroups, etc
87 // * _groupNode, _groupCell, etc
89 // 2) create MESH::_coordinate without setting _coordinate->_coordinate and set:
90 // * _coordinate->_coordinateSystem
91 // * _coordinate->_coordinateName
92 // * _coordinate->_coordinateUnit
96 //-----------------------//
98 //-----------------------//
101 GRID(const MED_EN::med_grid_type type);
103 GRID( driverTypes driverType, const string & fileName="",const string & meshName="");
104 GRID(const std::vector<std::vector<double> >& xyz_array,
105 const std::vector<std::string>& coord_name,
106 const std::vector<std::string>& coord_unit,
107 const MED_EN::med_grid_type type=MED_EN::MED_CARTESIAN);
108 GRID & operator=(const GRID &m);
112 void fillCoordinates() const ;
113 void fillConnectivity() const ;
114 // fill _coordinates and _connectivity of MESH if not yet done
116 inline void makeUnstructured();
117 // fill both coordinates and connectivity of MESH
119 void fillMeshAfterRead();
120 // fill some fields (_numberOfNodes, etc.) after reading
122 void writeUnstructured(int index=0, const string & driverName = "");
123 // write a Grid as an Unstructured mesh
125 void read(int index=0);
127 // API Methods returning fields of MESH that are filled while reading.
128 // So they need not to be redefined
130 // string getName() const;
131 // int getSpaceDimension();
132 // int getMeshDimension();
133 // string getCoordinatesSystem();
134 // int getNumberOfNodes();
135 // string * getCoordinatesNames();
136 // string * getCoordinatesUnits();
137 // int getNumberOfFamilies(medEntityMesh Entity);
138 // vector<FAMILY*> getFamilies(medEntityMesh Entity);
139 // FAMILY* getFamily(medEntityMesh Entity,int i);
140 // int getNumberOfGroups(medEntityMesh Entity);
141 // vector<GROUP*> getGroups(medEntityMesh Entity);
142 // GROUP* getGroup(medEntityMesh Entity,int i);
145 // Since a MESH itself knows if it is a GRID, it calls fillConnectivity()
146 // or fillCoordinates() whenever needed. So no redifinition of the following methods
148 // const double * getCoordinates(medModeSwitch Mode);
149 // COORDINATE * getCoordinateptr();
150 // const double getCoordinate(int Number,int Axis);
151 // int getNumberOfTypes(medEntityMesh Entity);
152 // medGeometryElement * getTypes(medEntityMesh Entity);
153 // CELLMODEL * getCellsTypes(medEntityMesh Entity);
154 // medGeometryElement getElementType(medEntityMesh Entity,int Number) ;
155 // int getNumberOfElements(medEntityMesh Entity,medGeometryElement Type);
156 // int getElementNumber(medConnectivity ConnectivityType, medEntityMesh Entity, medGeometryElement Type, int * connectivity) ;
157 // int * getGlobalNumberingIndex(medEntityMesh Entity);
158 // int * getConnectivity(medModeSwitch Mode,medConnectivity ConnectivityType,medEntityMesh Entity, medGeometryElement Type);
159 // int * getConnectivityIndex(medConnectivity ConnectivityType,medEntityMesh Entity);
160 // int * getReverseConnectivity(medConnectivity ConnectivityType);
161 // int * getReverseConnectivityIndex(medConnectivity ConnectivityType);
162 // bool existConnectivity(medConnectivity ConnectivityType,medEntityMesh Entity);
163 // void calculateConnectivity(medModeSwitch Mode,medConnectivity ConnectivityType,medEntityMesh Entity);
164 // FIELD<double>* getVolume(const SUPPORT * Support) throw (MEDEXCEPTION) ;
165 // FIELD<double>* getArea(const SUPPORT * Support) throw (MEDEXCEPTION) ;
166 // FIELD<double>* getLength(const SUPPORT * Support) throw (MEDEXCEPTION) ;
167 // FIELD<double>* getNormal(const SUPPORT * Support) throw (MEDEXCEPTION) ;
168 // FIELD<double>* getBarycenter(const SUPPORT * Support) throw (MEDEXCEPTION) ;
171 // Specific GRID methods
173 inline int getNodeNumber(const int i, const int j=0, const int k=0) const;
174 // return a NODE number by its position in the grid.
175 // WARNING: be carefull, there is no check that i,j,k are within a good range
176 // A good range is: 0 <= X < getArrayLength( X_Axis )
177 inline int getCellNumber(const int i, const int j=0, const int k=0) const ;
178 // return a CELL number by its position in the grid.
179 // WARNING: be carefull, there is no check that i,j,k are within a good range
180 // A good range is: 0 <= X < (getArrayLength( X_Axis )-1)
182 int getEdgeNumber(const int Axis, const int i, const int j=0, const int k=0) const throw (MEDEXCEPTION) ;
183 // return an EDGE number by its position in the grid.
184 // Axis [1,2,3] means one of directions: along i, j or k.
185 // It selects an edge of ones having same (i,j,k):
186 // * an EDGE going along given Axis.
187 // Exception for Axis out of range or when there is no edges in the grid (1D)
188 // WARNING: be carefull, there is no check that i,j,k are within a good range
190 // 0 <= X < (getArrayLength( X_Axis )-1)
191 // 0 <= X < getArrayLength( NOT_X_Axis )
193 int getFaceNumber(const int Axis, const int i, const int j=0, const int k=0) const throw (MEDEXCEPTION) ;
194 // return a FACE number by its position in the grid.
195 // Axis [1,2,3] means one of directions: along i, j or k.
196 // It selects a face of ones having same (i,j,k):
197 // * a FACE which is normal to given Axis
198 // Exception for Axis out of range or when there is no faces in the grid (1,2D)
199 // WARNING: be carefull, there is no check that i,j,k are within a good range
201 // 0 <= X < (getArrayLength( NOT_X_Axis )-1)
202 // 0 <= X < getArrayLength( X_Axis )
205 void getNodePosition(const int Number, int& i, int& j, int& k) const throw (MEDEXCEPTION) ;
206 void getCellPosition(const int Number, int& i, int& j, int& k) const throw (MEDEXCEPTION) ;
207 void getEdgePosition(const int Number, int& Axis, int& i, int& j, int& k) const throw (MEDEXCEPTION) ;
208 void getFacePosition(const int Number, int& Axis, int& i, int& j, int& k) const throw (MEDEXCEPTION) ;
209 // return position (i,j,k) of an entity #Number
210 // Axis: [1,2,3], see get*Number for details
211 // Exception for Number out of range
216 inline MED_EN::med_grid_type getGridType() const;
217 // return MED_CARTESIAN, MED_POLAR or MED_BODY_FITTED
219 int getArrayLength( const int Axis ) const throw (MEDEXCEPTION);
220 // return array length. Axis = [1,2,3] meaning [i,j,k],
221 // exception if Axis out of [1-3] range
223 const double getArrayValue (const int Axis, const int i) const throw (MEDEXCEPTION) ;
224 // return i-th array component. Axis = [1,2,3] meaning [i,j,k],
225 // exception if Axis out of [1 - 3] range
226 // exception if i is out of range [0 - (getArrayLength(Axis)-1)];
228 inline const COORDINATE * getCoordinateptr() const;
230 inline const double * getCoordinates(MED_EN::medModeSwitch Mode) const;
232 inline const double getCoordinate(int Number,int Axis) const;
234 inline int getNumberOfTypes(MED_EN::medEntityMesh Entity) const;
236 inline int getNumberOfTypesWithPoly(MED_EN::medEntityMesh Entity) const;
238 const MED_EN::medGeometryElement * getTypes(MED_EN::medEntityMesh Entity) const;
240 MED_EN::medGeometryElement * getTypesWithPoly(MED_EN::medEntityMesh Entity) const;
242 inline const CELLMODEL * getCellsTypes(MED_EN::medEntityMesh Entity) const;
244 const int * getGlobalNumberingIndex(MED_EN::medEntityMesh Entity) const;
246 inline int getNumberOfElements(MED_EN::medEntityMesh Entity,
247 MED_EN::medGeometryElement Type) const;
249 inline int getNumberOfElementsWithPoly(MED_EN::medEntityMesh Entity,
250 MED_EN::medGeometryElement Type) const;
252 inline bool existConnectivity(MED_EN::medConnectivity ConnectivityType,
253 MED_EN::medEntityMesh Entity) const;
255 inline MED_EN::medGeometryElement getElementType(MED_EN::medEntityMesh Entity,
258 inline MED_EN::medGeometryElement getElementTypeWithPoly(MED_EN::medEntityMesh Entity,
261 inline void calculateConnectivity(MED_EN::medModeSwitch Mode,
262 MED_EN::medConnectivity ConnectivityType,
263 MED_EN::medEntityMesh Entity) const ;
265 inline const CONNECTIVITY* getConnectivityptr() const;
267 inline const int * getConnectivity(MED_EN::medModeSwitch Mode,
268 MED_EN::medConnectivity ConnectivityType,
269 MED_EN::medEntityMesh Entity,
270 MED_EN::medGeometryElement Type) const;
272 inline const int * getConnectivityIndex(MED_EN::medConnectivity ConnectivityType,
273 MED_EN::medEntityMesh Entity) const;
275 inline const int * getReverseConnectivity(MED_EN::medConnectivity ConnectivityType,
276 MED_EN::medEntityMesh Entity=MED_EN::MED_CELL) const;
278 inline const int * getReverseConnectivityIndex(MED_EN::medConnectivity ConnectivityType,
279 MED_EN::medEntityMesh Entity=MED_EN::MED_CELL) const;
283 inline void setGridType(MED_EN::med_grid_type gridType);
285 friend class IMED_MESH_RDONLY_DRIVER;
286 friend class IMED_MESH_WRONLY_DRIVER;
287 friend class MED_MESH_RDONLY_DRIVER21;
288 friend class MED_MESH_WRONLY_DRIVER21;
289 friend class MED_MESH_RDONLY_DRIVER22;
290 friend class MED_MESH_WRONLY_DRIVER22;
291 friend class ENSIGHT_MESH_RDONLY_DRIVER;
295 //----------------------------------//
296 // Inline Methods Implementation
297 //----------------------------------//
299 inline MED_EN::med_grid_type GRID::getGridType() const
303 //=======================================================================
304 //function : getNodeNumber
306 //=======================================================================
308 inline int GRID::getNodeNumber(const int i, const int j, const int k) const
310 return 1 + i + _iArrayLength * j + _iArrayLength * _jArrayLength * k;
313 //=======================================================================
314 //function : getCellNumber
316 //=======================================================================
318 inline int GRID::getCellNumber(const int i, const int j, const int k) const
320 return 1 + i + (_iArrayLength-1) * j + (_iArrayLength-1) * (_jArrayLength-1) * k;
323 //=======================================================================
324 //function : makeUnstructured
325 //purpose : fill coordinates and connectivity of MESH
326 //=======================================================================
328 inline void GRID::makeUnstructured()
334 //=======================================================================
335 //function : setGridType
336 //purpose : set the _gridType field od the class GRID
337 //=======================================================================
339 inline void GRID::setGridType(MED_EN::med_grid_type gridType)
341 _gridType = gridType;
344 /*! Get the COORDINATES object. Use it only if you need COORDINATES informations not provided by the GRID class via the MESH class.*/
345 inline const COORDINATE * GRID::getCoordinateptr() const
351 /*! Get the whole coordinates array in a given interlacing mode. The interlacing mode are :
352 - MED_NO_INTERLACE : X1 X2 Y1 Y2 Z1 Z2
353 - MED_FULL_INTERLACE : X1 Y1 Z1 X2 Y2 Z2
355 inline const double * GRID::getCoordinates(MED_EN::medModeSwitch Mode) const
358 return _coordinate->getCoordinates(Mode);
361 /*! Get the coordinate n° number on axis n°axis*/
362 inline const double GRID::getCoordinate(int number, int axis) const
365 return _coordinate->getCoordinate(number,axis);
368 /*! Get the number of different geometric types for a given entity type.
370 medEntityMesh entity : MED_CELL, MED_FACE, MED_EDGE, MED_NODE,
374 inline int GRID::getNumberOfTypes(MED_EN::medEntityMesh entity) const
376 MESSAGE_MED("GRID::getNumberOfTypes(medEntityMesh entity) : "<<entity);
377 return 1; // a grid has one type
381 inline int GRID::getNumberOfTypesWithPoly(MED_EN::medEntityMesh entity) const
383 MESSAGE_MED("GRID::getNumberOfTypes(medEntityMesh entity) : "<<entity);
384 return 1; // a grid has one type
388 Get the whole list of CELLMODEL used by cells of given type (medEntityMesh).
390 REMARK : Don't use MED_NODE as medEntityMesh
392 inline const CELLMODEL * GRID::getCellsTypes(MED_EN::medEntityMesh Entity) const
396 if (_connectivity != NULL)
397 return _connectivity->getCellsTypes(Entity);
398 throw MEDEXCEPTION(LOCALIZED("GRID::getCellsTypes( medEntityMesh ) : Connectivity not defined !"));
401 /*! Return an array of size NumbreOfTypes+1 which contains, for each
402 geometric type of the given entity, the first global element number
405 For exemple, if we have a mesh with 5 triangles and 4 quadrangle :
406 - size of GlobalNumberingIndex is 3
407 - GlobalNumberingIndex[0]=1 (the first type)
408 - GlobalNumberingIndex[1]=6 (the second type)
409 - GlobalNumberingIndex[2]=10
411 inline const int * GRID::getGlobalNumberingIndex(MED_EN::medEntityMesh entity) const
415 if (_connectivity != NULL)
416 return _connectivity->getGlobalNumberingIndex(entity);
417 throw MEDEXCEPTION(LOCALIZED("GRID::getNumberOfTypes( medEntityMesh ) : Connectivity not defined !"));
421 Return the number of element of given geometric type of given entity. Return 0 if query is not defined.
423 inline int GRID::getNumberOfElements(MED_EN::medEntityMesh entity, MED_EN::medGeometryElement Type) const
425 int numberOfElements=0;
427 // Cas où le nombre d'éléments n'est pas nul
428 if (entity==MED_EN::MED_FACE && (Type==MED_EN::MED_QUAD4 || Type==MED_EN::MED_ALL_ELEMENTS) && _spaceDimension>2)
429 numberOfElements=(_iArrayLength-1)*(_jArrayLength-1);
431 else if (entity==MED_EN::MED_EDGE && (Type==MED_EN::MED_SEG2 || Type==MED_EN::MED_ALL_ELEMENTS) && _spaceDimension>1)
432 numberOfElements=_iArrayLength-1;
434 else if (entity==MED_EN::MED_NODE && (Type==MED_EN::MED_NONE || Type==MED_EN::MED_ALL_ELEMENTS) && _spaceDimension>0)
435 numberOfElements=_numberOfNodes;
437 else if (entity==MED_EN::MED_CELL && _spaceDimension==3 && (Type==MED_EN::MED_HEXA8 || Type==MED_EN::MED_ALL_ELEMENTS) )
438 numberOfElements=(_iArrayLength-1)*(_jArrayLength-1)*(_kArrayLength-1);
440 else if (entity==MED_EN::MED_CELL && _spaceDimension==2 && (Type==MED_EN::MED_QUAD4 || Type==MED_EN::MED_ALL_ELEMENTS))
441 numberOfElements=(_iArrayLength-1)*(_jArrayLength-1);
443 else if (entity==MED_EN::MED_CELL && _spaceDimension==1 && (Type==MED_EN::MED_SEG2 || Type==MED_EN::MED_ALL_ELEMENTS) )
444 numberOfElements=_iArrayLength-1;
446 MESSAGE_MED("GRID::getNumberOfElements - entity=" << entity << " Type=" << Type);
447 MESSAGE_MED("_spaceDimension=" << _spaceDimension << " numberOfElements=" << numberOfElements);
449 return numberOfElements;
452 int GRID::getNumberOfElementsWithPoly(MED_EN::medEntityMesh entity, MED_EN::medGeometryElement Type) const
454 return getNumberOfElements(entity,Type);
459 Return true if the wanted connectivity exist, else return false
460 (to use before a getSomething method).
462 inline bool GRID::existConnectivity(MED_EN::medConnectivity connectivityType, MED_EN::medEntityMesh entity) const
466 if (_connectivity==(CONNECTIVITY*)NULL)
467 throw MEDEXCEPTION("GRID::existConnectivity(medConnectivity,medEntityMesh) : no connectivity defined !");
468 return _connectivity->existConnectivity(connectivityType,entity);
472 Return the geometric type of global element Number of entity Entity.
474 Throw an exception if Entity is not defined or Number are wrong (too big).
476 inline MED_EN::medGeometryElement GRID::getElementType(MED_EN::medEntityMesh Entity,int Number) const
480 if (_connectivity==(CONNECTIVITY*)NULL)
481 throw MEDEXCEPTION("GRID::getElementType(medEntityMesh,int) : no connectivity defined !");
482 return _connectivity->getElementType(Entity,Number);
485 inline MED_EN::medGeometryElement GRID::getElementTypeWithPoly(MED_EN::medEntityMesh Entity,int Number) const
487 return getElementType(Entity,Number);
491 Calculate the ask connectivity. Return an exception if this could not be
492 done. Do nothing if connectivity already exist.
495 inline void GRID::calculateConnectivity(MED_EN::medModeSwitch Mode,MED_EN::medConnectivity ConnectivityType,MED_EN::medEntityMesh entity) const
499 if (Mode==MED_EN::MED_FULL_INTERLACE)
500 _connectivity->calculateConnectivity(ConnectivityType,entity);
502 throw MEDEXCEPTION(LOCALIZED("GRID::calculateConnectivity : only for MED_FULL_INTERLACE mode"));
505 inline const CONNECTIVITY* GRID::getConnectivityptr() const
509 return _connectivity;
513 Return the required connectivity in the right mode for the given
514 geometric type of the given entity.
516 To get connectivity for all geometric type, use Mode=MED_FULL_INTERLACE
517 and Type=MED_ALL_ELEMENTS.
518 You must also get the corresponding index array.
520 inline const int * GRID::getConnectivity(MED_EN::medModeSwitch Mode,MED_EN::medConnectivity ConnectivityType,MED_EN::medEntityMesh entity, MED_EN::medGeometryElement Type) const
524 if (Mode==MED_EN::MED_FULL_INTERLACE)
525 return _connectivity->getConnectivity(ConnectivityType,entity,Type);
526 throw MEDEXCEPTION(LOCALIZED("GRID::getConnectivity : only for MED_FULL_INTERLACE mode"));
530 Return the required index array for a connectivity received in
531 MED_FULL_ENTERLACE mode and MED_ALL_ELEMENTS type.
533 This array allow to find connectivity of each elements.
535 Example : Connectivity of i^{th} elements (1<=i<=NumberOfElement) begin
536 at index ConnectivityIndex[i-1] and end at index ConnectivityIndex[i]-1
537 in Connectivity array (Connectivity[ConnectivityIndex[i-1]-1] is the
540 inline const int * GRID::getConnectivityIndex(MED_EN::medConnectivity ConnectivityType,MED_EN::medEntityMesh entity) const
544 return _connectivity->getConnectivityIndex(ConnectivityType, entity);
548 Return the reverse connectivity required by ConnectivityType :
549 - If ConnectivityType=MED_NODAL : return connectivity node-cell
550 - If ConnectivityType=MED_DESCENDING : return connectivity face-cell
552 You must get ReverseConnectivityIndex array to use it.
554 inline const int * GRID::getReverseConnectivity(MED_EN::medConnectivity ConnectivityType,MED_EN::medEntityMesh Entity/*=MED_CELL*/) const
558 if (NULL==_connectivity)
559 throw MEDEXCEPTION("GRID::getReverseConnectivity : no connectivity defined in MESH !");
561 return _connectivity->getReverseConnectivity(ConnectivityType,Entity);
565 Return the index array required by ConnectivityType.
567 This array allow to find reverse connectivity of each elements.
569 Example : Reverse connectivity of i^{th} elements (1<=i<=NumberOfElement)
570 begin at index ReverseConnectivityIndex[i-1] and end at index
571 ReverseConnectivityIndex[i]-1
572 in ReverseConnectivity array (
573 ReverseConnectivity[ReverseConnectivityIndex[i-1]-1]
576 inline const int * GRID::getReverseConnectivityIndex(MED_EN::medConnectivity ConnectivityType,MED_EN::medEntityMesh Entity/*=MED_CELL*/) const
580 if (NULL==_connectivity)
581 throw MEDEXCEPTION("GRID::getReverseConnectivityIndex : no connectivity defined in MESH !");
583 return _connectivity->getReverseConnectivityIndex(ConnectivityType,Entity);