8 #include "MEDMEM_STRING.hxx"
9 #include "MEDMEM_Exception.hxx"
10 #include "MEDMEM_define.hxx"
12 //#include "MEDMEM_Support.hxx"
13 #include "MEDMEM_Coordinate.hxx"
14 #include "MEDMEM_Connectivity.hxx"
16 #include "MEDMEM_MedMeshDriver.hxx"
17 #include "MEDMEM_MedMedDriver.hxx"
24 template <class T> class FIELD;
27 //class MED_MESH_RDONLY_DRIVER ;
28 //class MED_MESH_WRONLY_DRIVER ;
30 using namespace MED_EN;
32 /*! This class contains all the informations related with a MESH :
40 NOTE: A Family is only on one type of entity (MED_CELL, MED_FACE, MED_EDGE, MED_NODE).
41 You can't have a family on MED_CELL and MED_FACE
51 // ------- Drivers Management Part
54 //-----------------------//
56 //-----------------------//
59 virtual GENDRIVER * run(const string & fileName, MESH * ptrMesh) const = 0 ;
62 //-------------------------------------------------------//
63 template <class T> class INSTANCE_DE : public INSTANCE
64 //-------------------------------------------------------//
67 GENDRIVER * run(const string & fileName, MESH * ptrMesh) const
68 { return new T(fileName,ptrMesh) ; }
71 static INSTANCE_DE<MED_MESH_RDWR_DRIVER> inst_med ;
72 //static INSTANCE_DE<VTK_DRIVER> inst_vtk ;
73 static const INSTANCE * const instances[] ;
75 // ------ End of Drivers Management Part
78 //-----------------------//
80 //-----------------------//
84 string _name; // A POSITIONNER EN FCT DES IOS ?
86 int _numberOfMEDNodeFamily ; // INUTILE
87 int * _MEDArrayNodeFamily ; // SOLUTION TEMPORAIRE
88 int * _numberOfMEDCellFamily ; // INUTILE
89 int * _numberOfMEDFaceFamily ; // INUTILE
90 int * _numberOfMEDEdgeFamily ; // INUTILE
91 int ** _MEDArrayCellFamily ; // SOLUTION TEMPORAIRE
92 int ** _MEDArrayFaceFamily ; // SOLUTION TEMPORAIRE
93 int ** _MEDArrayEdgeFamily ; // SOLUTION TEMPORAIRE
95 COORDINATE * _coordinate;
96 CONNECTIVITY * _connectivity;
102 int _numberOfNodesFamilies; //INUTILE ? -> _familyNode.size()
103 vector<FAMILY*> _familyNode ; // array of size _numberOfNodesFamilies;
104 int _numberOfCellsFamilies;
105 vector<FAMILY*> _familyCell ; // array of size _numberOfCellsFamilies;
106 int _numberOfFacesFamilies;
107 vector<FAMILY*> _familyFace ; // array of size _numberOfFacesFamilies;
108 int _numberOfEdgesFamilies;
109 vector<FAMILY*> _familyEdge ; // array of size _numberOfEdgesFamilies;
111 int _numberOfNodesGroups; //INUTILE ?
112 vector<GROUP*> _groupNode; // array of size _numberOfNodesGroups;
113 int _numberOfCellsGroups; //INUTILE ?
114 vector<GROUP*> _groupCell; // array of size _numberOfCellsGroups;
115 int _numberOfFacesGroups; //INUTILE ?
116 vector<GROUP*> _groupFace; // array of size _numberOfFacesGroups;
117 int _numberOfEdgesGroups; //INUTILE ?
118 vector<GROUP*> _groupEdge; // array of size _numberOfEdgesGroups;
121 vector<GENDRIVER *> _drivers; // Storage of the drivers currently in use
123 //-----------------------//
125 //-----------------------//
129 friend class MED_MESH_RDONLY_DRIVER;
130 friend class MED_MESH_WRONLY_DRIVER;
131 friend class MED_MED_DRIVER;
136 MESH & operator=(const MESH &m);
137 MESH( driverTypes driverType, const string & fileName="",
138 const string & meshName="");
140 friend ostream & operator<<(ostream &os, MESH &my) ;
142 int addDriver(driverTypes driverType,
143 const string & fileName ="Default File Name.med",
144 const string & driverName="Default Mesh Name");
145 int addDriver(MED_MESH_DRIVER & driver);
146 void rmDriver(int index=0);
148 inline void read(int index=0);
149 inline void read(const MED_MED_DRIVER & genDriver);
150 inline void write(int index=0, const string & driverName = "");
151 inline void write(const MED_MED_DRIVER & genDriver);
153 inline int * getMEDArrayNodeFamily() ;
154 inline int ** getMEDArrayCellFamily() ;
155 inline int ** getMEDArrayFaceFamily() ;
156 inline int ** getMEDArrayEdgeFamily() ;
158 // void calculateReverseConnectivity();
159 // void createFaces(); //Faces creation => full constituent informations
160 // void buildConstituent() ; // calculate descendent connectivity + face-cell connectivity
163 inline void setName(string name);
165 inline string getName() const;
166 inline int getSpaceDimension();
167 inline int getMeshDimension();
169 inline int getNumberOfNodes();
170 inline COORDINATE * getCoordinateptr();
171 inline string getCoordinatesSystem();
172 inline const double * getCoordinates(medModeSwitch Mode);
173 inline const double getCoordinate(int Number,int Axis);
174 inline string * getCoordinatesNames();
175 inline string * getCoordinatesUnits();
176 // inline int * getNodesNumbers();
178 inline int getNumberOfTypes(medEntityMesh Entity);
179 inline medGeometryElement * getTypes(medEntityMesh Entity);
180 inline CELLMODEL * getCellsTypes(medEntityMesh Entity);
181 inline int * getGlobalNumberingIndex(medEntityMesh Entity);
182 inline int getNumberOfElements(medEntityMesh Entity,medGeometryElement Type);
183 inline bool existConnectivity(medConnectivity ConnectivityType,medEntityMesh Entity);
184 inline medGeometryElement getElementType(medEntityMesh Entity,int Number) ;
185 inline void calculateConnectivity(medModeSwitch Mode,medConnectivity ConnectivityType,medEntityMesh Entity);
186 inline int * getConnectivity(medModeSwitch Mode,medConnectivity ConnectivityType,medEntityMesh Entity, medGeometryElement Type);
187 inline int * getConnectivityIndex(medConnectivity ConnectivityType,medEntityMesh Entity);
188 int getElementNumber(medConnectivity ConnectivityType, medEntityMesh Entity, medGeometryElement Type, int * connectivity) ;
189 inline int * getReverseConnectivity(medConnectivity ConnectivityType,medEntityMesh Entity=MED_CELL);
190 inline int * getReverseConnectivityIndex(medConnectivity ConnectivityType,medEntityMesh Entity=MED_CELL);
192 inline int getNumberOfFamilies(medEntityMesh Entity);
193 inline vector<FAMILY*> getFamilies(medEntityMesh Entity);
194 inline FAMILY* getFamily(medEntityMesh Entity,int i);
195 inline int getNumberOfGroups(medEntityMesh Entity);
196 inline vector<GROUP*> getGroups(medEntityMesh Entity);
197 inline GROUP* getGroup(medEntityMesh Entity,int i);
198 inline CONNECTIVITY* getConnectivityptr();
199 SUPPORT * getBoundaryElements(medEntityMesh Entity) throw (MEDEXCEPTION) ;
201 // Node DonneBarycentre(const Cell &m) const;
202 FIELD<double>* getVolume(const SUPPORT * Support) throw (MEDEXCEPTION) ; // Support must be on 3D elements
203 FIELD<double>* getArea(const SUPPORT * Support) throw (MEDEXCEPTION) ; // Support must be on 2D elements
204 FIELD<double>* getLength(const SUPPORT * Support) throw (MEDEXCEPTION) ; // Support must be on 1D elements
205 FIELD<double>* getNormal(const SUPPORT * Support) throw (MEDEXCEPTION) ; // Support must be on 2D elements
206 FIELD<double>* getBarycenter(const SUPPORT * Support) throw (MEDEXCEPTION) ;
207 // FIELD<int>* getNeighbourhood(SUPPORT * Support) throw (MEDEXCEPTION) ; // Il faut preciser !
210 // ---------------------------------------
212 // ---------------------------------------
214 inline CONNECTIVITY* MESH::getConnectivityptr() {return _connectivity;}
216 inline void MESH::read(int index/*=0*/)
218 const char * LOC = "MESH::read(int index=0) : ";
221 if (_drivers[index]) {
222 _drivers[index]->open();
223 _drivers[index]->read();
224 _drivers[index]->close();
227 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
228 << "The index given is invalid, index must be between 0 and |"
235 /*! Write all the content of the MESH using driver referenced by the handler <index>*/
236 inline void MESH::write(int index/*=0*/, const string & driverName/* = ""*/)
238 const char * LOC = "MESH::write(int index=0, const string & driverName = \"\") : ";
241 if ( _drivers[index] ) {
242 _drivers[index]->open();
243 if (driverName != "") _drivers[index]->setMeshName(driverName);
244 _drivers[index]->write();
245 _drivers[index]->close();
248 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
249 << "The index given is invalid, index must be between 0 and |"
256 // This method is MED specific : don't use it
258 inline void MESH::write(const MED_MED_DRIVER & genDriver)
260 const char * LOC = "MESH::write(const MED_MED_DRIVER & genDriver): ";
263 for (int index=0; index < _drivers.size(); index++ )
264 if ( *_drivers[index] == genDriver ) {
265 _drivers[index]->open();
266 _drivers[index]->write();
267 _drivers[index]->close();
268 // ? FINALEMENT PAS BESOIN DE L'EXCEPTION ?
275 // This method is MED specific : don't use it
277 inline void MESH::read(const MED_MED_DRIVER & genDriver)
279 const char * LOC = "MESH::read(const MED_MED_DRIVER & genDriver): ";
282 for (int index=0; index < _drivers.size(); index++ )
283 if ( *_drivers[index] == genDriver ) {
284 _drivers[index]->open();
285 _drivers[index]->read();
286 _drivers[index]->close();
287 // ? FINALEMENT PAS BESOIN DE L'EXCEPTION ?
294 /*! Set the MESH name */
295 inline void MESH::setName(string name)
297 _name=name ; //NOM interne à la classe
300 /*! Get the MESH name */
301 inline string MESH::getName() const
306 /*! Get the dimension of the space */
307 inline int MESH::getSpaceDimension()
309 return _spaceDimension;
312 /*! Get the dimension of the MESH */
313 inline int MESH::getMeshDimension()
315 return _meshDimension;
318 /*! Get the number of nodes used in the MESH */
319 inline int MESH::getNumberOfNodes()
321 return _numberOfNodes;
324 /*! Get the COORDINATES object. Use it only if you need COORDINATES informations not provided by the MESH class.*/
325 inline COORDINATE * MESH::getCoordinateptr()
330 /*! Get the system in which coordinates are given (CARTESIAN,CYLINDRICAL,SPHERICAL) __??MED_CART??__. */
331 inline string MESH::getCoordinatesSystem()
333 return _coordinate->getCoordinatesSystem();
336 /*! Get the whole coordinates array in a given interlacing mode. The interlacing mode are :
337 - MED_NO_INTERLACE : X1 X2 Y1 Y2 Z1 Z2
338 - MED_FULL_INTERLACE : X1 Y1 Z1 X2 Y2 Z2
340 inline const double * MESH::getCoordinates(medModeSwitch Mode)
342 return _coordinate->getCoordinates(Mode);
345 /*! Get the coordinate n° number on axis n°axis*/
346 inline const double MESH::getCoordinate(int number, int axis)
348 return _coordinate->getCoordinate(number,axis);
351 /*! Get the coordinate names array ("x ","y ","z ")
352 of size n*MED_TAILLE_PNOM
354 inline string * MESH::getCoordinatesNames()
356 return _coordinate->getCoordinatesNames();
359 /*! Get the coordinate unit names array ("cm ","cm ","cm ")
360 of size n*MED_TAILLE_PNOM
362 inline string * MESH::getCoordinatesUnits()
364 return _coordinate->getCoordinatesUnits();
366 // int * MESH::getNodesNumbers() {
367 // return nodesNumbers;
370 /*! Get the number of different geometric types for a given entity type.
372 For exemple getNumberOfTypes(MED_CELL) would return 3 is the MESH
373 have some MED_TETRA4, MED_PYRA5 and MED_HEXA6 in it.
375 medEntityMesh entity : MED_CELL, MED_FACE, MED_EDGE, MED_NODE, MED_ALL_ENTITIES
377 If entity is not defined, return 0.
379 If there is no connectivity, return an exception.
381 inline int MESH::getNumberOfTypes(medEntityMesh entity)
383 MESSAGE("MESH::getNumberOfTypes(medEntityMesh entity) : "<<entity);
384 if (entity == MED_NODE)
386 if (_connectivity != NULL)
387 return _connectivity->getNumberOfTypes(entity) ;
388 throw MEDEXCEPTION(LOCALIZED("MESH::getNumberOfTypes( medEntityMesh ) : Connectivity not defined !"));
392 Get the list of geometric types used by a given entity.
393 medEntityMesh entity : MED_CELL, MED_FACE, MED_EDGE, MED_ALL_ENTITIES
395 REM : Don't use MED_NODE
397 If entity is not defined, return an exception.
399 inline medGeometryElement * MESH::getTypes(medEntityMesh entity)
401 if (entity == MED_NODE)
402 throw MEDEXCEPTION(LOCALIZED("MESH::getTypes( medEntityMesh ) : No medGeometryElement with MED_NODE entity !"));
403 // return un tableau de taille 1 contenant MED_NONE, comme les supports pour etre coherent avec getNumberOfTypes ???? PG
405 if (_connectivity != NULL)
406 return _connectivity->getGeometricTypes(entity) ;
407 throw MEDEXCEPTION(LOCALIZED("MESH::getTypes( medEntityMesh ) : Connectivity not defined !"));
411 Get the whole list of CELLMODEL used by cells of given type (medEntityMesh).
413 REMARK : Don't use MED_NODE as medEntityMesh
415 inline CELLMODEL * MESH::getCellsTypes(medEntityMesh Entity)
417 if (_connectivity != NULL)
418 return _connectivity->getCellsTypes(Entity) ;
419 throw MEDEXCEPTION(LOCALIZED("MESH::getCellsTypes( medEntityMesh ) : Connectivity not defined !"));
422 /*! Return an array of size NumbreOfTypes+1 which contains, for each
423 geometric type of the given entity, the first global element number
426 For exemple, if we have a mesh with 5 triangles and 4 quadrangle :
427 - size of GlobalNumberingIndex is 3
428 - GlobalNumberingIndex[0]=1 (the first type)
429 - GlobalNumberingIndex[1]=6 (the second type)
430 - GlobalNumberingIndex[2]=10
432 inline int * MESH::getGlobalNumberingIndex(medEntityMesh entity)
434 if (_connectivity != NULL)
435 return _connectivity->getGlobalNumberingIndex(entity);
436 throw MEDEXCEPTION(LOCALIZED("MESH::getNumberOfTypes( medEntityMesh ) : Connectivity not defined !"));
439 Return the number of element of given geometric type of given entity. Return 0 if query is not defined.
442 - getNumberOfElements(MED_NODE,MED_NONE) : number of node
443 - getNumberOfElements(MED_NODE,MED_TRIA3) : return 0 (not defined)
444 - getNumberOfElements(MED_FACE,MED_TRIA3) : return number of triangles
445 elements defined in face entity (0 if not defined)
446 - getNumberOfElements(MED_CELL,MED_ALL_ELEMENTS) : return total number
447 of elements defined in cell entity
449 inline int MESH::getNumberOfElements(medEntityMesh entity, medGeometryElement Type)
451 const char * LOC = "MESH::getNumberOfElements(medEntityMesh,medGeometryElement) : " ;
452 if (entity==MED_NODE)
453 if ((Type==MED_NONE)|(Type==MED_ALL_ELEMENTS))
454 return _numberOfNodes ;
457 //throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"wrong medGeometryElement with MED_NODE"));
459 if (_connectivity != (CONNECTIVITY*)NULL)
460 return _connectivity->getNumberOf(entity,Type) ;
463 //throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"connectivity not defined !"));
466 Return true if the wanted connectivity exist, else return false
467 (to use before a getSomething method).
469 inline bool MESH::existConnectivity(medConnectivity connectivityType, medEntityMesh entity)
471 if (_connectivity==(CONNECTIVITY*)NULL)
472 throw MEDEXCEPTION("MESH::existConnectivity(medConnectivity,medEntityMesh) : no connectivity defined !");
473 return _connectivity->existConnectivity(connectivityType,entity) ;
476 Return the geometric type of global element Number of entity Entity.
478 Throw an exception if Entity is not defined or Number are wrong (too big).
480 inline medGeometryElement MESH::getElementType(medEntityMesh Entity,int Number)
482 if (_connectivity==(CONNECTIVITY*)NULL)
483 throw MEDEXCEPTION("MESH::getElementType(medEntityMesh,int) : no connectivity defined !");
484 return _connectivity->getElementType(Entity,Number) ;
487 Calculate the ask connectivity. Return an exception if this could not be
488 done. Do nothing if connectivity already exist.
491 inline void MESH::calculateConnectivity(medModeSwitch Mode,medConnectivity ConnectivityType,medEntityMesh entity)
493 if (Mode==MED_FULL_INTERLACE)
494 _connectivity->calculateConnectivity(ConnectivityType,entity) ;
496 throw MEDEXCEPTION(LOCALIZED("MESH::calculateConnectivity : only for MED_FULL_INTERLACE mode"));
499 Return the required connectivity in the right mode for the given
500 geometric type of the given entity.
502 To get connectivity for all geometric type, use Mode=MED_FULL_INTERLACE
503 and Type=MED_ALL_ELEMENTS.
504 You must also get the corresponding index array.
506 inline int * MESH::getConnectivity(medModeSwitch Mode,medConnectivity ConnectivityType,medEntityMesh entity, medGeometryElement Type)
508 if (Mode==MED_FULL_INTERLACE)
509 return _connectivity->getConnectivity(ConnectivityType,entity,Type) ;
510 throw MEDEXCEPTION(LOCALIZED("MESH::getConnectivity : only for MED_FULL_INTERLACE mode"));
513 Return the required index array for a connectivity received in
514 MED_FULL_ENTERLACE mode and MED_ALL_ELEMENTS type.
516 This array allow to find connectivity of each elements.
518 Example : Connectivity of i^{th} elements (1<=i<=NumberOfElement) begin
519 at index ConnectivityIndex[i-1] and end at index ConnectivityIndex[i]-1
520 in Connectivity array (Connectivity[ConnectivityIndex[i-1]-1] is the
523 inline int * MESH::getConnectivityIndex(medConnectivity ConnectivityType,medEntityMesh entity)
525 return _connectivity->getConnectivityIndex(ConnectivityType, entity) ;
528 Return the reverse connectivity required by ConnectivityType :
529 - If ConnectivityType=MED_NODAL : return connectivity node-cell
530 - If ConnectivityType=MED_DESCENDING : return connectivity face-cell
532 You must get ReverseConnectivityIndex array to use it.
534 inline int * MESH::getReverseConnectivity(medConnectivity ConnectivityType,medEntityMesh Entity/*=MED_CELL*/)
536 if (NULL==_connectivity)
537 throw MEDEXCEPTION("MESH::getReverseConnectivity : no connectivity defined in MESH !");
539 return _connectivity->getReverseConnectivity(ConnectivityType,Entity) ;
542 Return the index array required by ConnectivityType.
544 This array allow to find reverse connectivity of each elements.
546 Example : Reverse connectivity of i^{th} elements (1<=i<=NumberOfElement)
547 begin at index ReverseConnectivityIndex[i-1] and end at index
548 ReverseConnectivityIndex[i]-1
549 in ReverseConnectivity array (
550 ReverseConnectivity[ReverseConnectivityIndex[i-1]-1]
553 inline int * MESH::getReverseConnectivityIndex(medConnectivity ConnectivityType,medEntityMesh Entity/*=MED_CELL*/)
555 if (NULL==_connectivity)
556 throw MEDEXCEPTION("MESH::getReverseConnectivityIndex : no connectivity defined in MESH !");
558 return _connectivity->getReverseConnectivityIndex(ConnectivityType,Entity) ;
562 inline int MESH::getNumberOfFamilies (medEntityMesh entity)
566 return _numberOfNodesFamilies ;
568 return _numberOfCellsFamilies ;
570 return _numberOfFacesFamilies ;
572 return _numberOfEdgesFamilies ;
574 throw MEDEXCEPTION("MESH::getNumberOfFamilies : Unknown entity");
577 inline int MESH::getNumberOfGroups (medEntityMesh entity)
581 return _numberOfNodesGroups ;
583 return _numberOfCellsGroups ;
585 return _numberOfFacesGroups ;
587 return _numberOfEdgesGroups ;
589 throw MEDEXCEPTION("MESH::getNumberOfGroups : Unknown entity");
592 vector<FAMILY*> MESH::getFamilies(medEntityMesh entity) {
603 throw MEDEXCEPTION("MESH::getFamilies : Unknown entity");
607 vector<GROUP*> MESH::getGroups(medEntityMesh entity) {
618 throw MEDEXCEPTION("MESH::getGroups : Unknown entity");
622 FAMILY* MESH::getFamily(medEntityMesh entity, int i) {
624 throw MEDEXCEPTION("MESH::getFamily(i) : argument i must be > 0");
625 int NumberOfFamilies = 0 ;
626 vector<FAMILY*> Family ;
629 NumberOfFamilies = _numberOfNodesFamilies ;
630 Family = _familyNode ;
634 NumberOfFamilies = _numberOfCellsFamilies ;
635 Family = _familyCell ;
639 NumberOfFamilies = _numberOfFacesFamilies ;
640 Family = _familyFace ;
644 NumberOfFamilies = _numberOfEdgesFamilies ;
645 Family = _familyEdge ;
649 throw MEDEXCEPTION("MESH::getFamilies : Unknown entity");
651 if (i>NumberOfFamilies)
652 throw MEDEXCEPTION("MESH::getFamily(entity,i) : argument i must be <= _numberOfFamilies");
656 GROUP* MESH::getGroup(medEntityMesh entity, int i) {
657 const char * LOC = "MESH::getGroup(medEntityMesh entity, int i) : " ;
659 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"argument i must be > 0"));
660 int NumberOfGroups = 0 ;
661 vector<GROUP*> Group ;
664 NumberOfGroups = _numberOfNodesGroups ;
669 NumberOfGroups = _numberOfCellsGroups ;
674 NumberOfGroups = _numberOfFacesGroups ;
679 NumberOfGroups = _numberOfEdgesGroups ;
684 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Unknown entity"));
686 if (i>NumberOfGroups)
687 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"argument i="<<i<<" must be <= _numberOfGroups="<<NumberOfGroups));
696 //inline void MESH::write(const string & driverName) {
697 // write(0,driverName);
701 // this method are temporary, perhaps we remove it if we put information in an other place
702 inline int * MESH::getMEDArrayNodeFamily() {
703 return _MEDArrayNodeFamily ;
705 inline int ** MESH::getMEDArrayCellFamily() {
706 return _MEDArrayCellFamily ;
708 inline int ** MESH::getMEDArrayFaceFamily() {
709 return _MEDArrayFaceFamily ;
711 inline int ** MESH::getMEDArrayEdgeFamily() {
712 return _MEDArrayEdgeFamily ;
715 #endif /* MESH_HXX */