1 // Copyright (C) 2007-2012 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
32 #include "MEDMEM_GMesh.hxx"
33 #include "MEDMEM_Utilities.hxx"
34 #include "MEDMEM_STRING.hxx"
35 #include "MEDMEM_Exception.hxx"
36 #include "MEDMEM_define.hxx"
37 #include "MEDMEM_Coordinate.hxx"
38 #include "MEDMEM_Connectivity.hxx"
39 #include "MEDMEM_GenDriver.hxx"
40 #include "MEDMEM_RCBase.hxx"
41 #include "MEDMEM_FieldForward.hxx"
51 MEDMEM_EXPORT ostream & operator<<(ostream &os, const MESH &my);
53 /*! This class contains all the informations related with a MESH :
58 class MEDMEM_EXPORT MESH : public GMESH
60 //-----------------------//
62 //-----------------------//
67 mutable COORDINATE * _coordinate;
68 mutable CONNECTIVITY * _connectivity;
70 //////////////////////////////////////////////////////////////////////////////////////
71 /// Modification pour prise en compte de la numérotation optionnelle des noeuds ///
72 //////////////////////////////////////////////////////////////////////////////////////
74 /// La map suivante donne le lien numérotation optionnelle => numérotation cannonique
75 /// Elle sera calculée apres l'appel de MEDnumLire(...)
76 /// Et sera utilisée avant chaque appel a MEDconnLire(...) pour renuméroter toutes les mailles de façon canonique [1...n]
77 /// _coordinate->NodeNumber sera utilisé avant chaque appel à MEDconnEcri pour démunéroter les mailles en leur numérotation originelle
78 /// Ce traitement devrait prévenir tout plantage du aux numérotations optionnelles DES NOEUDS
79 /// Et ne ralentira que tres peu les traitements sans numéros optionnels
81 int _arePresentOptionnalNodesNumbers;
82 map<int,int> _optionnalToCanonicNodesNumbers;
84 //-----------------------//
86 //-----------------------//
90 // Add your personnal driver line (step 2)
91 friend class MED_MESH_RDONLY_DRIVER;
92 friend class MED_MESH_WRONLY_DRIVER;
94 friend class MED_MED_RDONLY_DRIVER22;
95 friend class MED_MED_WRONLY_DRIVER22;
96 friend class MED_MED_RDWR_DRIVER22;
98 friend class GIBI_MESH_RDONLY_DRIVER;
99 friend class GIBI_MESH_WRONLY_DRIVER;
100 friend class GIBI_MESH_RDWR_DRIVER;
102 friend class PORFLOW_MESH_RDONLY_DRIVER;
103 friend class PORFLOW_MESH_WRONLY_DRIVER;
104 friend class PORFLOW_MESH_RDWR_DRIVER;
106 friend class VTK_MESH_DRIVER;
108 friend class ENSIGHT_MESH_RDONLY_DRIVER;
114 MESH( driverTypes driverType, const string & fileName="",
115 const string & meshName="") throw (MEDEXCEPTION);
118 MESH & operator=(const MESH &m);
119 virtual bool operator==(const MESH& other) const;
120 virtual bool deepCompare(const GMESH& other) const;
121 virtual bool isEmpty() const;
123 friend ostream & operator<<(ostream &os, const MESH &my);
124 virtual void printMySelf(ostream &os) const;
126 virtual int getMeshDimension() const;
127 virtual bool getIsAGrid() const;
128 virtual const MESH* convertInMESH() const;
130 inline int getNumberOfNodes() const;
131 virtual inline const COORDINATE * getCoordinateptr() const;
132 inline string getCoordinatesSystem() const;
133 virtual inline const double * getCoordinates(MED_EN::medModeSwitch Mode) const;
134 virtual inline const double getCoordinate(int Number,int Axis) const;
135 inline const string * getCoordinatesNames() const;
136 inline const string * getCoordinatesUnits() const;
138 virtual inline int getNumberOfTypes(MED_EN::medEntityMesh Entity) const;
139 virtual inline const MED_EN::medGeometryElement * getTypes(MED_EN::medEntityMesh Entity) const;
140 virtual inline const CELLMODEL * getCellsTypes(MED_EN::medEntityMesh Entity) const;
141 virtual inline string * getCellTypeNames(MED_EN::medEntityMesh Entity) const;
142 virtual inline const int * getGlobalNumberingIndex(MED_EN::medEntityMesh Entity) const;
143 virtual inline int getNumberOfElements(MED_EN::medEntityMesh Entity,
144 MED_EN::medGeometryElement Type) const;
145 virtual inline bool existConnectivity(MED_EN::medConnectivity ConnectivityType,
146 MED_EN::medEntityMesh Entity) const;
148 virtual inline MED_EN::medGeometryElement getElementType(MED_EN::medEntityMesh Entity,
150 virtual inline void calculateConnectivity(MED_EN::medConnectivity ConnectivityType,
151 MED_EN::medEntityMesh Entity) const ;
152 virtual inline int getConnectivityLength(MED_EN::medConnectivity ConnectivityType,
153 MED_EN::medEntityMesh Entity,
154 MED_EN::medGeometryElement Type) const;
155 virtual inline const int * getConnectivity(MED_EN::medConnectivity ConnectivityType,
156 MED_EN::medEntityMesh Entity,
157 MED_EN::medGeometryElement Type) const;
158 virtual inline const int * getConnectivityIndex(MED_EN::medConnectivity ConnectivityType,
159 MED_EN::medEntityMesh Entity) const;
161 virtual int getElementNumber(MED_EN::medConnectivity ConnectivityType,
162 MED_EN::medEntityMesh Entity,
163 MED_EN::medGeometryElement Type,
164 int * connectivity) const;
165 virtual inline int getReverseConnectivityLength(MED_EN::medConnectivity ConnectivityType,
166 MED_EN::medEntityMesh Entity=MED_EN::MED_CELL) const;
167 virtual inline const int * getReverseConnectivity(MED_EN::medConnectivity ConnectivityType,
168 MED_EN::medEntityMesh Entity=MED_EN::MED_CELL) const;
169 virtual inline int getReverseConnectivityIndexLength(MED_EN::medConnectivity ConnectivityType,
170 MED_EN::medEntityMesh Entity=MED_EN::MED_CELL) const;
171 virtual inline const int * getReverseConnectivityIndex(MED_EN::medConnectivity ConnectivityType,
172 MED_EN::medEntityMesh Entity=MED_EN::MED_CELL) const;
174 virtual inline const CONNECTIVITY* getConnectivityptr() const;
175 inline void setConnectivityptr(CONNECTIVITY*);
176 virtual SUPPORT * getBoundaryElements(MED_EN::medEntityMesh Entity) const
177 throw (MEDEXCEPTION);
178 virtual SUPPORT * getSkin(const SUPPORT * Support3D)
179 throw (MEDEXCEPTION);
181 // Node DonneBarycentre(const Cell &m) const;
182 virtual FIELD<double>* getVolume (const SUPPORT * Support, bool isAbs = true) const
183 throw (MEDEXCEPTION);
184 // Support must be on 3D elements
185 virtual FIELD<double>* getArea (const SUPPORT * Support) const
186 throw (MEDEXCEPTION);
187 // Support must be on 2D elements
188 virtual FIELD<double>* getLength (const SUPPORT * Support) const
189 throw (MEDEXCEPTION);
190 // Support must be on 1D elements
191 virtual FIELD<double>* getNormal (const SUPPORT * Support) const
192 throw (MEDEXCEPTION);
193 // Support must be on 2D elements
194 virtual FIELD<double>* getBarycenter (const SUPPORT * Support) const
195 throw (MEDEXCEPTION);
196 // FIELD<int>* getNeighbourhood(SUPPORT * Support) const
197 // throw (MEDEXCEPTION); // Il faut preciser !
199 SUPPORT *buildSupportOnNodeFromElementList(const list<int>& listOfElt, MED_EN::medEntityMesh entity) const throw (MEDEXCEPTION);
200 void fillSupportOnNodeFromElementList(const list<int>& listOfElt, SUPPORT *supportToFill) const throw (MEDEXCEPTION);
201 int getElementContainingPoint(const double *coord);
202 vector< vector<double> > getBoundingBox() const;
203 void convertToPoly();
206 // ---------------------------------------
208 // ---------------------------------------
210 inline const CONNECTIVITY* MESH::getConnectivityptr() const
212 // checkGridFillConnectivity();
213 return _connectivity;
216 inline void MESH::setConnectivityptr(CONNECTIVITY* conn)
219 delete _connectivity;
224 \addtogroup MESH_nodes
228 /*! Gets the number of nodes used in the mesh. */
229 inline int MESH::getNumberOfNodes() const
231 return _numberOfNodes;
235 Gets the COORDINATES object. Use it only if you need COORDINATES informations not provided by the MESH class.
238 inline const COORDINATE * MESH::getCoordinateptr() const
240 // checkGridFillCoords();
244 /*! Retrieves the system in which coordinates are given (CARTESIAN,CYLINDRICAL,SPHERICAL). */
245 inline string MESH::getCoordinatesSystem() const
247 return _coordinate->getCoordinatesSystem();
250 /*! Gets the whole coordinates array in a given interlacing mode. The interlacing mode are :
251 - MED_NO_INTERLACE : X1 X2 Y1 Y2 Z1 Z2
252 - MED_FULL_INTERLACE : X1 Y1 Z1 X2 Y2 Z2
254 inline const double * MESH::getCoordinates(MED_EN::medModeSwitch Mode) const
256 // checkGridFillCoords();
257 return _coordinate->getCoordinates(Mode);
260 /*! Gets the coordinate number \a number on axis \a axis.*/
261 inline const double MESH::getCoordinate(int number, int axis) const
263 // checkGridFillCoords();
264 return _coordinate->getCoordinate(number,axis);
267 /*! Gets a pointer to the coordinate names array.
269 inline const string * MESH::getCoordinatesNames() const
271 return _coordinate->getCoordinatesNames();
274 /*! Gets a pointer to the coordinate units array.
276 inline const string * MESH::getCoordinatesUnits() const
278 return _coordinate->getCoordinatesUnits();
282 Here is a small C++ example program for which the
283 Python version may be found in
284 \a MESHcoordinates.py.
286 \example MESHcoordinates.cxx
292 // int * MESH::getNodesNumbers() const
294 // return nodesNumbers;
298 \addtogroup MESH_connectivity
303 /*! Gets the number of different geometric types for a given entity type.
305 For example getNumberOfTypes(MED_CELL) would return 3 if the MESH
306 have some MED_TETRA4, MED_PYRA5 and MED_HEXA8 in it.
307 If entity is not defined, returns 0.
308 If there is no connectivity, returns an exception.
310 \param entity entity type (MED_CELL, MED_FACE, MED_EDGE, MED_NODE, MED_ALL_ENTITIES)
312 inline int MESH::getNumberOfTypes(MED_EN::medEntityMesh entity) const
314 MESSAGE_MED("MESH::getNumberOfTypes(medEntityMesh entity) : "<<entity);
315 if (entity == MED_EN::MED_NODE)
317 // checkGridFillConnectivity();
318 if (_connectivity != NULL)
319 return _connectivity->getNumberOfTypes(entity);
320 throw MEDEXCEPTION(LOCALIZED("MESH::getNumberOfTypes( medEntityMesh ) : Connectivity not defined !"));
324 Gets the list of geometric types used by a given entity.
325 If entity is not defined, it returns an exception.
326 \param entity Entity type must be MED_CELL, MED_FACE, MED_EDGE or MED_ALL_ENTITIES.
327 Passing MED_NODE as an entity type will throw an exception.
329 inline const MED_EN::medGeometryElement * MESH::getTypes(MED_EN::medEntityMesh entity) const
331 if (entity == MED_EN::MED_NODE)
332 throw MEDEXCEPTION(LOCALIZED("MESH::getTypes( medEntityMesh ) : No medGeometryElement with MED_NODE entity !"));
333 // return un tableau de taille 1 contenant MED_NONE, comme les supports pour etre coherent avec getNumberOfTypes ???? PG
335 // checkGridFillConnectivity();
336 if (_connectivity != NULL)
337 return _connectivity->getGeometricTypes(entity);
338 throw MEDEXCEPTION(LOCALIZED("MESH::getTypes( medEntityMesh ) : Connectivity not defined !"));
340 /*! \if MEDMEM_ug @} \endif */
343 Get the whole list of CELLMODEL used by cells of given type (medEntityMesh).
344 Passing MED_NODE as an entity type will throw an exception.
346 inline const CELLMODEL * MESH::getCellsTypes(MED_EN::medEntityMesh Entity) const
348 // checkGridFillConnectivity();
349 if (_connectivity != NULL)
350 return _connectivity->getCellsTypes(Entity);
351 throw MEDEXCEPTION(LOCALIZED("MESH::getCellsTypes( medEntityMesh ) : Connectivity not defined !"));
355 Get an array (it should deleted after use) of the whole list of CELLMODEL
356 Name of a given type (medEntityMesh).
358 REMARK : Don't use MED_NODE as medEntityMesh
360 inline string * MESH::getCellTypeNames(MED_EN::medEntityMesh Entity) const
362 // checkGridFillConnectivity();
363 if (_connectivity != NULL)
364 return _connectivity->getCellTypeNames(Entity);
365 throw MEDEXCEPTION(LOCALIZED("MESH::getCellTypesName( medEntityMesh ) : Connectivity not defined !"));
368 \addtogroup MESH_connectivity
373 /*! Returns an array of size NumberOfTypes+1 which contains, for each
374 geometric type of the given entity, the first global element number
377 For exemple, if we have a mesh with 5 triangles and 4 quadrangle :
378 - size of GlobalNumberingIndex is 3
379 - GlobalNumberingIndex[0]=1 (the first type)
380 - GlobalNumberingIndex[1]=6 (the second type)
381 - GlobalNumberingIndex[2]=10
383 inline const int * MESH::getGlobalNumberingIndex(MED_EN::medEntityMesh entity) const
385 // checkGridFillConnectivity();
386 if (_connectivity != NULL)
387 return _connectivity->getGlobalNumberingIndex(entity);
388 throw MEDEXCEPTION(LOCALIZED("MESH::getNumberOfTypes( medEntityMesh ) : Connectivity not defined !"));
391 Returns the number of elements of given geometric type of given entity. Returns 0 if query is not defined.
394 - getNumberOfElements(MED_NODE,MED_NONE) : number of nodes
395 - getNumberOfElements(MED_NODE,MED_TRIA3) : returns 0 (not defined)
396 - getNumberOfElements(MED_FACE,MED_TRIA3) : returns number of triangle
397 elements defined in face entity (0 if not defined)
398 - getNumberOfElements(MED_CELL,MED_ALL_ELEMENTS) : returns total number
399 of elements defined in cell entity
401 inline int MESH::getNumberOfElements(MED_EN::medEntityMesh entity, MED_EN::medGeometryElement Type) const
403 if (entity==MED_EN::MED_NODE)
404 if ((Type==MED_EN::MED_NONE)|(Type==MED_EN::MED_ALL_ELEMENTS))
405 return _numberOfNodes;
408 //throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"wrong medGeometryElement with MED_NODE"));
411 // checkGridFillConnectivity();
412 if (_connectivity != (CONNECTIVITY*)NULL)
413 return _connectivity->getNumberOf(entity,Type);
416 //throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"connectivity not defined !"));
421 This example shows the use of connectivity retrieval methods on a mesh which
422 corresponds to the four-element mesh given in figure ??. Note
423 the use of connectivity and connnectivity index tables, and the
424 offsets used to convert Fortran-style numbering to C arrays.
426 The output of this program reads :
435 Element 1 : 4 6 5 10 11 9
438 \example read_example.cxx
440 A more complete example involving descending connectivities
441 can be found in \c MESHconnectivities.cxx and \c MESHconnectivities.py.
447 Returns true if the wanted connectivity exist, else returns false
448 (to use before a getSomething method).
450 inline bool MESH::existConnectivity(MED_EN::medConnectivity connectivityType, MED_EN::medEntityMesh entity) const
452 // checkGridFillConnectivity();
453 if (_connectivity==(CONNECTIVITY*)NULL)
454 throw MEDEXCEPTION("MESH::existConnectivity(medConnectivity,medEntityMesh) : no connectivity defined !");
455 return _connectivity->existConnectivity(connectivityType,entity);
458 \addtogroup MESH_connectivity
464 Returns the geometric type of global element number \a Number of entity \a Entity.
466 Throw an exception if \a Entity is not defined or if \a Numberis wrong.
468 inline MED_EN::medGeometryElement MESH::getElementType(MED_EN::medEntityMesh Entity,int Number) const
470 // checkGridFillConnectivity();
471 if (_connectivity==(CONNECTIVITY*)NULL)
472 throw MEDEXCEPTION("MESH::getElementType(medEntityMesh,int) : no connectivity defined !");
473 return _connectivity->getElementType(Entity,Number);
482 Calculates the required connectivity. Returns an exception if this could not be
483 done. Do nothing if connectivity already exist.
486 inline void MESH::calculateConnectivity(MED_EN::medConnectivity ConnectivityType,MED_EN::medEntityMesh entity) const
488 _connectivity->calculateConnectivity(ConnectivityType,entity);
491 Returns the corresponding length of the array returned by MESH::getConnectivity with exactly the same arguments.
492 Used particulary for wrapping CORBA and python.
494 inline int MESH::getConnectivityLength(MED_EN::medConnectivity ConnectivityType,MED_EN::medEntityMesh entity, MED_EN::medGeometryElement Type) const
496 int nbOfElm = getNumberOfElements(entity,Type);
499 if (Type == MED_EN::MED_ALL_ELEMENTS)
501 size = getConnectivityIndex(ConnectivityType,entity)[nbOfElm]-1;
505 size = _connectivity->getConnectivityLength(ConnectivityType,entity,Type); // issue 19983
511 \addtogroup MESH_connectivity
517 Returns the required connectivity in mode \a Mode for the
518 geometric type \a Type of the entity type \a entity.
519 \a ConnectivityType specifies descending or nodal connectivity.
521 To get connectivity for all geometric type, use \a Mode=MED_FULL_INTERLACE
522 and \a Type=MED_ALL_ELEMENTS.
523 You must also get the corresponding index array.
525 inline const int * MESH::getConnectivity(MED_EN::medConnectivity ConnectivityType,MED_EN::medEntityMesh entity, MED_EN::medGeometryElement Type) const
527 return _connectivity->getConnectivity(ConnectivityType,entity,Type);
530 Returns the required index array for a connectivity received in
531 MED_FULL_INTERLACE mode and MED_ALL_ELEMENTS type.
533 This array allows to find connectivity of each element.
535 Example : Connectivity of i-th element (1<=i<=NumberOfElement) begins
536 at index ConnectivityIndex[i-1] and ends at index ConnectivityIndex[i]-1
537 in Connectivity array (Connectivity[ConnectivityIndex[i-1]-1] is the
538 first node of the element)
540 inline const int * MESH::getConnectivityIndex(MED_EN::medConnectivity ConnectivityType,
541 MED_EN::medEntityMesh entity) const
543 return _connectivity->getConnectivityIndex(ConnectivityType, entity);
553 Returns the corresponding length of the array returned by MESH::getReverseConnectivity with exactly the same arguments.
554 Used particulary for wrapping CORBA and python.
557 inline int MESH::getReverseConnectivityLength(MED_EN::medConnectivity ConnectivityType,
558 MED_EN::medEntityMesh Entity) const
560 int spaceDim = getSpaceDimension();
563 if (ConnectivityType == MED_EN::MED_NODAL)
565 nb = getNumberOfNodes();
570 nb = getNumberOfElements(MED_EN::MED_EDGE,
571 MED_EN::MED_ALL_ELEMENTS);
572 else if (spaceDim == 3)
573 nb = getNumberOfElements(MED_EN::MED_FACE,
574 MED_EN::MED_ALL_ELEMENTS);
576 return getReverseConnectivityIndex(ConnectivityType,Entity)[nb]-1;
579 Returns the reverse connectivity required by ConnectivityType :
580 - If ConnectivityType=MED_NODAL : returns connectivity node-cell
581 - If ConnectivityType=MED_DESCENDING : returns connectivity face-cell
583 You must get ReverseConnectivityIndex array to use it.
586 inline const int * MESH::getReverseConnectivity(MED_EN::medConnectivity ConnectivityType,MED_EN::medEntityMesh Entity/*=MED_CELL*/) const
588 // checkGridFillConnectivity();
589 if (NULL==_connectivity)
590 throw MEDEXCEPTION("MESH::getReverseConnectivity : no connectivity defined in MESH !");
592 return _connectivity->getReverseConnectivity(ConnectivityType,Entity);
595 Returns the corresponding length of the array returned by MESH::getReverseConnectivityIndex with exactly the same arguments.
596 Used particulary for wrapping CORBA and python.
598 inline int MESH::getReverseConnectivityIndexLength(MED_EN::medConnectivity ConnectivityType,
599 MED_EN::medEntityMesh Entity) const
601 int spaceDim = getSpaceDimension();
603 if (ConnectivityType == MED_EN::MED_NODAL)
605 return getNumberOfNodes()+1;
610 return getNumberOfElements(MED_EN::MED_EDGE,MED_EN::MED_ALL_ELEMENTS)+1;
611 else if (spaceDim == 3)
612 return getNumberOfElements(MED_EN::MED_FACE,MED_EN::MED_ALL_ELEMENTS)+1;
614 throw MEDEXCEPTION("Invalid dimension");
618 Returns the index array required by ConnectivityType.
620 This array allow to find reverse connectivity of each elements.
622 Example : Reverse connectivity of i^{th} elements (1<=i<=NumberOfElement)
623 begin at index ReverseConnectivityIndex[i-1] and end at index
624 ReverseConnectivityIndex[i]-1
625 in ReverseConnectivity array (
626 ReverseConnectivity[ReverseConnectivityIndex[i-1]-1]
629 inline const int * MESH::getReverseConnectivityIndex(MED_EN::medConnectivity ConnectivityType,MED_EN::medEntityMesh Entity/*=MED_CELL*/) const
631 // checkGridFillConnectivity();
632 if (NULL==_connectivity)
633 throw MEDEXCEPTION("MESH::getReverseConnectivityIndex : no connectivity defined in MESH !");
635 return _connectivity->getReverseConnectivityIndex(ConnectivityType,Entity);
640 #endif /* MESH_HXX */