]> SALOME platform Git repositories - modules/med.git/blob - src/MEDMEM/MEDMEM_Mesh.hxx
Salome HOME
remove a reference to the $MED_ROOT_DIR in the Makefile.in wich is useless
[modules/med.git] / src / MEDMEM / MEDMEM_Mesh.hxx
1 #ifndef MESH_HXX
2 #define MESH_HXX
3
4 #include <string>
5 #include <vector>
6 #include <list>
7 #include <map>
8
9 #include "utilities.h"
10 #include "MEDMEM_STRING.hxx"
11 #include "MEDMEM_Exception.hxx"
12 #include "MEDMEM_define.hxx"
13 #include "MEDMEM_Coordinate.hxx"
14 #include "MEDMEM_Connectivity.hxx"
15 #include "MEDMEM_GenDriver.hxx"
16 #include "MEDMEM_RCBase.hxx"
17
18 /*! This class contains all the informations related with a MESH :
19   - COORDINATES
20   - CONNECTIVITIES
21   - FAMILIES OF NODES
22   - FAMILIES OF CELLS
23   - FAMILIES OF FACES
24   - FAMILIES OF EDGES
25
26   NOTE: A Family is only on one type of entity (MED_CELL, MED_FACE, MED_EDGE, MED_NODE).
27   You can't have a family on MED_CELL and MED_FACE
28
29 */
30
31 namespace MEDMEM {
32
33 template <class T> class FIELD;
34
35 class CELLMODEL;
36 class FAMILY;
37 class GROUP;
38 class SUPPORT;
39
40 class MESH : public RCBASE
41 {
42   //-----------------------//
43   //   Attributes
44   //-----------------------//
45
46 protected :
47
48   string        _name; // A POSITIONNER EN FCT DES IOS ?
49   string        _description;
50
51   mutable COORDINATE *   _coordinate;
52   mutable CONNECTIVITY * _connectivity;
53
54   int   _spaceDimension;
55   int   _meshDimension;
56   int   _numberOfNodes;
57
58
59   //////////////////////////////////////////////////////////////////////////////////////
60   ///  Modification pour prise en compte de la numérotation optionnelle des noeuds   ///
61   //////////////////////////////////////////////////////////////////////////////////////
62   ///
63   ///  La map suivante donne le lien numérotation optionnelle => numérotation cannonique
64   ///  Elle  sera calculée apres l'appel de MEDnumLire(...)
65   ///  Et sera utilisée avant chaque appel a MEDconnLire(...) pour renuméroter toutes les mailles de façon canonique [1...n]
66   ///  _coordinate->NodeNumber sera utilisé avant chaque appel à MEDconnEcri pour démunéroter les mailles en leur numérotation originelle
67   ///  Ce traitement devrait prévenir tout plantage du aux numérotations optionnelles DES NOEUDS
68   ///  Et ne ralentira que tres peu les traitements sans numéros optionnels
69
70   int _arePresentOptionnalNodesNumbers;
71   map<int,int> _optionnalToCanonicNodesNumbers;
72
73   vector<FAMILY*> _familyNode;
74   vector<FAMILY*> _familyCell;
75   vector<FAMILY*> _familyFace;
76   vector<FAMILY*> _familyEdge;
77
78   vector<GROUP*> _groupNode;
79   vector<GROUP*> _groupCell;
80   vector<GROUP*> _groupFace;
81   vector<GROUP*> _groupEdge;
82   // list of all Group
83
84   vector<GENDRIVER *> _drivers; // Storage of the drivers currently in use
85
86   bool           _isAGrid;      // am I a GRID or not
87
88   //-----------------------//
89   //   Methods
90   //-----------------------//
91
92 //   inline void checkGridFillCoords() const;
93 //   inline void checkGridFillConnectivity() const;
94   bool isEmpty() const;
95   // if this->_isAGrid, assure that _coordinate and _connectivity are filled
96 public :
97
98   // Add your personnal driver line (step 2)
99   friend class IMED_MESH_RDONLY_DRIVER;
100   friend class IMED_MESH_WRONLY_DRIVER;
101   friend class MED_MESH_RDONLY_DRIVER21;
102   friend class MED_MESH_WRONLY_DRIVER21;
103   friend class MED_MESH_RDONLY_DRIVER22;
104   friend class MED_MESH_WRONLY_DRIVER22;
105
106   friend class MED_MED_RDONLY_DRIVER21;
107   friend class MED_MED_WRONLY_DRIVER21;
108   friend class MED_MED_RDWR_DRIVER21;
109   friend class MED_MED_RDONLY_DRIVER22;
110   friend class MED_MED_WRONLY_DRIVER22;
111   friend class MED_MED_RDWR_DRIVER22;
112
113   friend class GIBI_MESH_RDONLY_DRIVER;
114   friend class GIBI_MESH_WRONLY_DRIVER;
115   friend class GIBI_MESH_RDWR_DRIVER;
116
117   friend class PORFLOW_MESH_RDONLY_DRIVER;
118   friend class PORFLOW_MESH_WRONLY_DRIVER;
119   friend class PORFLOW_MESH_RDWR_DRIVER;
120
121   friend class VTK_MESH_DRIVER;
122
123   void init();
124   MESH();
125   MESH(MESH &m);
126   MESH & operator=(const MESH &m);
127   virtual bool operator==(const MESH& other) const;
128   virtual bool deepCompare(const MESH& other) const;
129   MESH( driverTypes driverType, const string & fileName="",
130         const string & meshName="") throw (MEDEXCEPTION);
131   virtual ~MESH();
132   friend ostream & operator<<(ostream &os, const MESH &my);
133
134   int  addDriver(driverTypes driverType,
135                  const string & fileName  ="Default File Name.med",
136                  const string & driverName="Default Mesh Name",
137                  MED_EN::med_mode_acces access=MED_EN::MED_REMP);
138   int  addDriver(GENDRIVER & driver);
139   void rmDriver(int index=0);
140
141   virtual void read(int index=0);
142   inline void read(const GENDRIVER & genDriver);
143   inline void write(int index=0, const string & driverName = "");
144   inline void write(const GENDRIVER & genDriver);
145
146   inline void         setName(string name);
147   inline void         setDescription(string description);
148   inline string       getName() const;
149   inline string       getDescription() const;
150   inline int          getSpaceDimension() const;
151   inline int          getMeshDimension() const;
152   inline bool         getIsAGrid();
153
154   inline int                        getNumberOfNodes() const;
155   virtual inline const COORDINATE * getCoordinateptr() const;
156   inline string                     getCoordinatesSystem() const;
157   virtual inline const double *     getCoordinates(MED_EN::medModeSwitch Mode) const;
158   virtual inline const double       getCoordinate(int Number,int Axis) const;
159   inline const string *             getCoordinatesNames() const;
160   inline const string *             getCoordinatesUnits() const;
161   //inline int *                    getNodesNumbers();
162
163   virtual inline int             getNumberOfTypes(MED_EN::medEntityMesh Entity) const;
164   virtual int getNumberOfTypesWithPoly(MED_EN::medEntityMesh Entity) const;
165   virtual inline const MED_EN::medGeometryElement * getTypes(MED_EN::medEntityMesh Entity) const;
166   virtual MED_EN::medGeometryElement * getTypesWithPoly(MED_EN::medEntityMesh Entity) const;
167   virtual inline const CELLMODEL * getCellsTypes(MED_EN::medEntityMesh Entity) const;
168   virtual const int * getGlobalNumberingIndex(MED_EN::medEntityMesh Entity) const;
169   virtual inline int getNumberOfElements(MED_EN::medEntityMesh Entity,
170                                          MED_EN::medGeometryElement Type) const;
171   virtual int getNumberOfElementsWithPoly(MED_EN::medEntityMesh Entity,
172                                          MED_EN::medGeometryElement Type) const;
173   virtual inline bool existConnectivity(MED_EN::medConnectivity ConnectivityType,
174                                         MED_EN::medEntityMesh Entity) const;
175   inline bool existPolygonsConnectivity(MED_EN::medConnectivity ConnectivityType,
176                                         MED_EN::medEntityMesh Entity) const;
177   inline bool existPolyhedronConnectivity(MED_EN::medConnectivity ConnectivityType,
178                                           MED_EN::medEntityMesh Entity) const;
179
180   virtual inline MED_EN::medGeometryElement getElementType(MED_EN::medEntityMesh Entity,
181                                                    int Number) const;
182   virtual inline MED_EN::medGeometryElement getElementTypeWithPoly(MED_EN::medEntityMesh Entity,
183                                                    int Number) const;
184   virtual inline void calculateConnectivity(MED_EN::medModeSwitch Mode,
185                                             MED_EN::medConnectivity ConnectivityType,
186                                             MED_EN::medEntityMesh Entity) const ;
187   virtual inline int getConnectivityLength(MED_EN::medModeSwitch Mode,
188                                              MED_EN::medConnectivity ConnectivityType,
189                                              MED_EN::medEntityMesh Entity,
190                                              MED_EN::medGeometryElement Type) const;
191   virtual inline const int * getConnectivity(MED_EN::medModeSwitch Mode,
192                                              MED_EN::medConnectivity ConnectivityType,
193                                              MED_EN::medEntityMesh Entity,
194                                              MED_EN::medGeometryElement Type) const;
195   virtual inline const int * getConnectivityIndex(MED_EN::medConnectivity ConnectivityType,
196                                                   MED_EN::medEntityMesh Entity) const;
197
198   inline const int * getPolygonsConnectivity(MED_EN::medConnectivity ConnectivityType,
199                                              MED_EN::medEntityMesh Entity) const;
200   inline const int * getPolygonsConnectivityIndex(MED_EN::medConnectivity ConnectivityType,
201                                                   MED_EN::medEntityMesh Entity) const;
202   inline int getNumberOfPolygons() const;
203   inline const int * getPolyhedronConnectivity(MED_EN::medConnectivity ConnectivityType) const;
204   inline const int * getPolyhedronFacesIndex() const;
205   inline const int * getPolyhedronIndex(MED_EN::medConnectivity ConnectivityType) const;
206   inline int getNumberOfPolyhedronFaces() const;
207   inline int getNumberOfPolyhedron() const;
208
209   virtual int                 getElementNumber(MED_EN::medConnectivity ConnectivityType,
210                                                MED_EN::medEntityMesh Entity,
211                                                MED_EN::medGeometryElement Type,
212                                                int * connectivity) const;
213   virtual inline int getReverseConnectivityLength(MED_EN::medConnectivity ConnectivityType,
214                                                   MED_EN::medEntityMesh Entity=MED_EN::MED_CELL) const;
215   virtual inline const int * getReverseConnectivity(MED_EN::medConnectivity ConnectivityType,
216                                                     MED_EN::medEntityMesh Entity=MED_EN::MED_CELL) const;
217   virtual inline int getReverseConnectivityIndexLength(MED_EN::medConnectivity ConnectivityType,
218                                                          MED_EN::medEntityMesh Entity=MED_EN::MED_CELL) const;
219   virtual inline const int * getReverseConnectivityIndex(MED_EN::medConnectivity ConnectivityType,
220                                                          MED_EN::medEntityMesh Entity=MED_EN::MED_CELL) const;
221
222   virtual int                          getNumberOfFamilies(MED_EN::medEntityMesh Entity) const;
223   virtual inline const vector<FAMILY*> getFamilies(MED_EN::medEntityMesh Entity) const;
224   virtual inline const FAMILY*         getFamily(MED_EN::medEntityMesh Entity,int i) const;
225   virtual int                          getNumberOfGroups(MED_EN::medEntityMesh Entity) const;
226   virtual inline const vector<GROUP*>  getGroups(MED_EN::medEntityMesh Entity) const;
227   virtual inline const GROUP*          getGroup(MED_EN::medEntityMesh Entity,int i) const;
228   virtual inline const CONNECTIVITY* getConnectivityptr() const;
229   virtual SUPPORT *                    getBoundaryElements(MED_EN::medEntityMesh Entity)
230                                                 throw (MEDEXCEPTION);
231   // problème avec le maillage dans le support :
232   //            le pointeur n'est pas const, mais sa valeur oui. A voir !!! PG
233
234   SUPPORT *                            getSkin(const SUPPORT * Support3D)
235                                                 throw (MEDEXCEPTION);
236
237   //  Node DonneBarycentre(const Cell &m) const;
238   virtual FIELD<double>* getVolume (const SUPPORT * Support) const
239                                 throw (MEDEXCEPTION);
240                                 // Support must be on 3D elements
241   virtual FIELD<double>* getArea (const SUPPORT * Support) const
242                                 throw (MEDEXCEPTION);
243                                 // Support must be on 2D elements
244   virtual FIELD<double>* getLength (const SUPPORT * Support) const
245                                 throw (MEDEXCEPTION);
246                                 // Support must be on 1D elements
247   virtual FIELD<double>* getNormal (const SUPPORT * Support) const
248                                 throw (MEDEXCEPTION);
249                                 // Support must be on 2D elements
250   virtual FIELD<double>* getBarycenter (const SUPPORT * Support) const
251                                 throw (MEDEXCEPTION);
252   //  FIELD<int>* getNeighbourhood(SUPPORT * Support) const
253   //                            throw (MEDEXCEPTION); // Il faut preciser !
254
255   /*!
256     returns a SUPPORT pointer on the union of all SUPPORTs in Supports.
257     You should delete this pointer after use to avois memory leaks.
258   */
259   static SUPPORT * mergeSupports(const vector<SUPPORT *> Supports) throw (MEDEXCEPTION) ;
260
261   /*!
262     returns a SUPPORT pointer on the intersection of all SUPPORTs in Supports.
263     The (SUPPORT *) NULL pointer is returned if the intersection is empty.
264     You should delete this pointer after use to avois memory leaks.
265    */
266   static SUPPORT * intersectSupports(const vector<SUPPORT *> Supports) throw (MEDEXCEPTION) ;
267
268   /*!
269    * Create families from groups.
270    * This function is automaticaly called whenever we ask for families that are not up-to-date.
271    * (The creation of families is delayed to the need of user.)
272    * If a new created family hapen to already exist, we keep the old one.
273    * (There is no way to know which family has change.)
274    */
275   void createFamilies();
276   SUPPORT *buildSupportOnNodeFromElementList(const list<int>& listOfElt, MED_EN::medEntityMesh entity) const throw (MEDEXCEPTION);
277   void fillSupportOnNodeFromElementList(const list<int>& listOfElt, SUPPORT *supportToFill) const throw (MEDEXCEPTION);
278   SUPPORT *buildSupportOnElementsFromElementList(const list<int>& listOfElt, MED_EN::medEntityMesh entity) const throw (MEDEXCEPTION);
279   int getElementContainingPoint(const double *coord);
280   template<class T>
281   static FIELD<T> *mergeFields(const vector< FIELD<T>* >& others,bool meshCompare=false);
282   /*!
283    *For ref counter. Only for client
284    */
285   virtual void addReference() const;
286   virtual void removeReference() const;
287 };
288
289 // ---------------------------------------
290 //              Methodes Inline
291 // ---------------------------------------
292
293 inline const CONNECTIVITY* MESH::getConnectivityptr() const
294 {
295 //   checkGridFillConnectivity();
296   return _connectivity;
297 }
298
299 // inline void MESH::read(int index/*=0*/)
300 // {
301 //   const char * LOC = "MESH::read(int index=0) : ";
302 //   BEGIN_OF(LOC);
303
304 //   if (_drivers[index]) {
305 //     _drivers[index]->open();
306 //     _drivers[index]->read();
307 //     _drivers[index]->close();
308 //   }
309 //   else
310 //     throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
311 //                                      << "The index given is invalid, index must be between  0 and |"
312 //                                      << _drivers.size()
313 //                                      )
314 //                           );
315 //   END_OF(LOC);
316 // }
317
318 /*! Write all the content of the MESH using driver referenced by the integer handler index.*/
319 inline void MESH::write(int index/*=0*/, const string & driverName/* = ""*/)
320 {
321   const char * LOC = "MESH::write(int index=0, const string & driverName = \"\") : ";
322   BEGIN_OF(LOC);
323
324   if ( _drivers[index] ) {
325     _drivers[index]->open();
326     if (driverName != "") _drivers[index]->setMeshName(driverName);
327     _drivers[index]->write();
328     _drivers[index]->close();
329   }
330   else
331     throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
332                                      << "The index given is invalid, index must be between  0 and |"
333                                      << _drivers.size()
334                                      )
335                           );
336   END_OF(LOC);
337 }
338
339 // This method is MED specific : don't use it
340 // must be private.
341 inline void MESH::write(const GENDRIVER & genDriver)
342 {
343   const char * LOC = "MESH::write(const MED_MED_DRIVER & genDriver): ";
344   BEGIN_OF(LOC);
345
346   for (unsigned int index=0; index < _drivers.size(); index++ )
347     if ( *_drivers[index] == genDriver ) {
348       _drivers[index]->open();
349       _drivers[index]->write();
350       _drivers[index]->close();
351       // ? FINALEMENT PAS BESOIN DE L'EXCEPTION ?
352     }
353
354   END_OF(LOC);
355
356 }
357
358 // This method is MED specific : don't use it
359 // must be private.
360 inline void MESH::read(const GENDRIVER & genDriver)
361 {
362   const char * LOC = "MESH::read(const MED_MED_DRIVER & genDriver): ";
363   BEGIN_OF(LOC);
364
365   for (unsigned int index=0; index < _drivers.size(); index++ )
366     if ( *_drivers[index] == genDriver ) {
367       _drivers[index]->open();
368       _drivers[index]->read();
369       _drivers[index]->close();
370       // ? FINALEMENT PAS BESOIN DE L'EXCEPTION ?
371     }
372
373   END_OF(LOC);
374
375 }
376
377 /*! Set the MESH name */
378 inline void MESH::setName(string name)
379 {
380   _name=name; //NOM interne à la classe
381 }
382
383 /*! Get the MESH name */
384 inline string MESH::getName() const
385 {
386   return _name;
387 }
388
389 /*! Set the MESH description */
390 inline void MESH::setDescription(string description)
391 {
392   _description=description; //NOM interne à la classe
393 }
394
395 /*! Get the MESH description */
396 inline string MESH::getDescription() const
397 {
398   return _description;
399 }
400
401 /*! Get the dimension of the space */
402 inline int MESH::getSpaceDimension() const
403 {
404   return _spaceDimension;
405 }
406
407 /*! Get the dimension of the MESH */
408 inline int MESH::getMeshDimension() const
409 {
410   return _meshDimension;
411 }
412
413 /*! Get the number of nodes used in the MESH */
414 inline int MESH::getNumberOfNodes() const
415 {
416   return _numberOfNodes;
417 }
418
419 /*! Get the COORDINATES object. Use it only if you need COORDINATES informations not provided by the MESH class.*/
420 inline const COORDINATE * MESH::getCoordinateptr() const
421 {
422 //   checkGridFillCoords();
423   return _coordinate;
424 }
425
426 /*! Get the system in which coordinates are given (CARTESIAN,CYLINDRICAL,SPHERICAL) __??MED_CART??__. */
427 inline string MESH::getCoordinatesSystem() const
428 {
429   return _coordinate->getCoordinatesSystem();
430 }
431
432 /*! Get the whole coordinates array in a given interlacing mode. The interlacing mode are :
433   - MED_NO_INTERLACE   :  X1 X2 Y1 Y2 Z1 Z2
434   - MED_FULL_INTERLACE :  X1 Y1 Z1 X2 Y2 Z2
435  */
436 inline const double * MESH::getCoordinates(MED_EN::medModeSwitch Mode) const
437 {
438 //   checkGridFillCoords();
439   return _coordinate->getCoordinates(Mode);
440 }
441
442 /*! Get the coordinate n° number on axis n°axis*/
443 inline const double MESH::getCoordinate(int number, int axis) const
444 {
445 //   checkGridFillCoords();
446   return _coordinate->getCoordinate(number,axis);
447 }
448
449 /*! Get the coordinate names array ("x       ","y       ","z       ")
450   of size n*MED_TAILLE_PNOM
451 */
452 inline const string * MESH::getCoordinatesNames() const
453 {
454   return _coordinate->getCoordinatesNames();
455 }
456
457 /*! Get the coordinate unit names array ("cm       ","cm       ","cm       ")
458   of size n*MED_TAILLE_PNOM
459 */
460 inline const string * MESH::getCoordinatesUnits() const
461 {
462   return _coordinate->getCoordinatesUnits();
463 }
464 //  int * MESH::getNodesNumbers() const
465 //  {
466 //    return nodesNumbers;
467 //  }
468
469 /*! Get the number of different geometric types for a given entity type.
470
471     For exemple getNumberOfTypes(MED_CELL) would return 3 if the MESH
472     have some MED_TETRA4, MED_PYRA5 and MED_HEXA6 in it.
473
474     medEntityMesh entity : MED_CELL, MED_FACE, MED_EDGE, MED_NODE, MED_ALL_ENTITIES
475
476     If entity is not defined, return 0.
477
478     If there is no connectivity, return an exception.
479 */
480 inline int MESH::getNumberOfTypes(MED_EN::medEntityMesh entity) const
481 {
482   MESSAGE("MESH::getNumberOfTypes(medEntityMesh entity) : "<<entity);
483   if (entity == MED_EN::MED_NODE)
484     return 1;
485 //   checkGridFillConnectivity();
486   if (_connectivity != NULL)
487     return _connectivity->getNumberOfTypes(entity);
488   throw MEDEXCEPTION(LOCALIZED("MESH::getNumberOfTypes( medEntityMesh ) : Connectivity not defined !"));
489 }
490
491 /*!
492   Gets the list of geometric types used by a given entity.
493   medEntityMesh entity : MED_CELL, MED_FACE, MED_EDGE, MED_ALL_ENTITIES
494
495   REM : Don't use MED_NODE
496
497   If entity is not defined, it returns an exception.
498 */
499 inline const MED_EN::medGeometryElement * MESH::getTypes(MED_EN::medEntityMesh entity) const
500 {
501   if (entity == MED_EN::MED_NODE)
502     throw MEDEXCEPTION(LOCALIZED("MESH::getTypes( medEntityMesh ) : No medGeometryElement with MED_NODE entity !"));
503   // return un tableau de taille 1 contenant MED_NONE, comme les supports pour etre coherent avec getNumberOfTypes ???? PG
504
505 //   checkGridFillConnectivity();
506   if (_connectivity != NULL)
507     return _connectivity->getGeometricTypes(entity);
508   throw MEDEXCEPTION(LOCALIZED("MESH::getTypes( medEntityMesh ) : Connectivity not defined !"));
509 }
510
511 /*!
512   Get the whole list of CELLMODEL used by cells of given type (medEntityMesh).
513
514   REMARK : Don't use MED_NODE as medEntityMesh
515 */
516 inline const CELLMODEL * MESH::getCellsTypes(MED_EN::medEntityMesh Entity) const
517 {
518   //  checkGridFillConnectivity();
519   if (_connectivity != NULL)
520     return _connectivity->getCellsTypes(Entity);
521   throw MEDEXCEPTION(LOCALIZED("MESH::getCellsTypes( medEntityMesh ) : Connectivity not defined !"));
522 }
523
524 /*! Returns an array of size NumbreOfTypes+1 which contains, for each
525     geometric type of the given entity, the first global element number
526     of this type.
527
528     For exemple, if we have a mesh with 5 triangles and 4 quadrangle :
529     - size of GlobalNumberingIndex is 3
530     - GlobalNumberingIndex[0]=1 (the first type)
531     - GlobalNumberingIndex[1]=6 (the second type)
532     - GlobalNumberingIndex[2]=10
533 */
534 inline const int * MESH::getGlobalNumberingIndex(MED_EN::medEntityMesh entity) const
535 {
536   //  checkGridFillConnectivity();
537   if (_connectivity != NULL)
538     return _connectivity->getGlobalNumberingIndex(entity);
539   throw MEDEXCEPTION(LOCALIZED("MESH::getNumberOfTypes( medEntityMesh ) : Connectivity not defined !"));
540 }
541 /*!
542   Returns the number of element of given geometric type of given entity. Return 0 if query is not defined.
543
544   Example :
545   - getNumberOfElements(MED_NODE,MED_NONE) : number of node
546   - getNumberOfElements(MED_NODE,MED_TRIA3) : returns 0 (not defined)
547   - getNumberOfElements(MED_FACE,MED_TRIA3) : returns number of triangles
548   elements defined in face entity (0 if not defined)
549   - getNumberOfElements(MED_CELL,MED_ALL_ELEMENTS) : returns total number
550   of elements defined in cell entity
551  */
552 inline int MESH::getNumberOfElements(MED_EN::medEntityMesh entity, MED_EN::medGeometryElement Type) const
553 {
554   //  const char * LOC = "MESH::getNumberOfElements(medEntityMesh,medGeometryElement) : ";
555   if (entity==MED_EN::MED_NODE)
556     if ((Type==MED_EN::MED_NONE)|(Type==MED_EN::MED_ALL_ELEMENTS))
557       return _numberOfNodes;
558     else
559       return 0;
560   //throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"wrong medGeometryElement with MED_NODE"));
561   else
562     {
563 //       checkGridFillConnectivity();
564       if (_connectivity != (CONNECTIVITY*)NULL)
565         return _connectivity->getNumberOf(entity,Type);
566       else
567         return 0;
568       //throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"connectivity not defined !"));
569     }
570 }
571 /*!
572   Returns true if the wanted connectivity exist, else returns false
573   (to use before a getSomething method).
574  */
575 inline bool MESH::existConnectivity(MED_EN::medConnectivity connectivityType, MED_EN::medEntityMesh entity) const
576 {
577 //   checkGridFillConnectivity();
578   if (_connectivity==(CONNECTIVITY*)NULL)
579     throw MEDEXCEPTION("MESH::existConnectivity(medConnectivity,medEntityMesh) : no connectivity defined !");
580   return _connectivity->existConnectivity(connectivityType,entity);
581 }
582 /*!
583   Returns true if the wanted polygons connectivity exist, else returns false
584 */
585 inline bool MESH::existPolygonsConnectivity(MED_EN::medConnectivity connectivityType, MED_EN::medEntityMesh entity) const
586 {
587   if (_connectivity == (CONNECTIVITY*) NULL)
588     throw MEDEXCEPTION("MESH::existPolygonsConnectivity(medConnectivity,medEntityMesh) : no connectivity defined !");
589   return _connectivity->existPolygonsConnectivity(connectivityType,entity);
590 }
591 /*!
592   Returns true if the wanted polyhedron connectivity exist, else returns false
593 */
594 inline bool MESH::existPolyhedronConnectivity(MED_EN::medConnectivity connectivityType, MED_EN::medEntityMesh entity) const
595 {
596   if (_connectivity == (CONNECTIVITY*) NULL)
597     throw MEDEXCEPTION("MESH::existPolyhedronConnectivity(medConnectivity,medEntityMesh) : no connectivity defined !");
598   return _connectivity->existPolyhedronConnectivity(connectivityType,entity);
599 }
600 /*!
601   Returns the geometric type of global element Number of entity Entity.
602
603   Throw an exception if Entity is not defined or Number are wrong (too big).
604  */
605 inline MED_EN::medGeometryElement MESH::getElementType(MED_EN::medEntityMesh Entity,int Number) const
606 {
607   //  checkGridFillConnectivity();
608   if (_connectivity==(CONNECTIVITY*)NULL)
609     throw MEDEXCEPTION("MESH::getElementType(medEntityMesh,int) : no connectivity defined !");
610   return _connectivity->getElementType(Entity,Number);
611 }
612
613 /*
614   Method equivalent to getElementType except that it includes not only classical Types but polygons/polyhedra also.
615  */
616 MED_EN::medGeometryElement MESH::getElementTypeWithPoly(MED_EN::medEntityMesh Entity, int Number) const
617 {
618   if (_connectivity==(CONNECTIVITY*)NULL)
619     throw MEDEXCEPTION("MESH::getElementType(medEntityMesh,int) : no connectivity defined !");
620   return _connectivity->getElementTypeWithPoly(Entity,Number);
621 }
622
623 /*!
624   Calculate the ask connectivity. Returns an exception if this could not be
625   done. Do nothing if connectivity already exist.
626  */
627
628 inline void MESH::calculateConnectivity(MED_EN::medModeSwitch Mode,MED_EN::medConnectivity ConnectivityType,MED_EN::medEntityMesh entity) const
629 {
630   //  checkGridFillConnectivity();
631   if (Mode==MED_EN::MED_FULL_INTERLACE)
632     _connectivity->calculateConnectivity(ConnectivityType,entity);
633   else
634     throw MEDEXCEPTION(LOCALIZED("MESH::calculateConnectivity : only for MED_FULL_INTERLACE mode"));
635 }
636 /*!
637  Returns the corresponding length of the array returned by MESH::getConnectivity with exactly the same arguments.
638  Used particulary for wrapping CORBA and python.
639  */
640 inline int MESH::getConnectivityLength(MED_EN::medModeSwitch Mode,MED_EN::medConnectivity ConnectivityType,MED_EN::medEntityMesh entity, MED_EN::medGeometryElement Type) const
641 {
642   int nbOfElm = getNumberOfElements(entity,Type);
643   int size;
644
645   if (Type == MED_EN::MED_ALL_ELEMENTS)
646     {
647       size = getConnectivityIndex(ConnectivityType,entity)[nbOfElm]-1;
648     }
649   else
650     {
651       size = nbOfElm*(((int) Type)%100);
652     }
653   return size;
654 }
655 /*!
656   Returns the required connectivity in the right mode for the given
657   geometric type of the given entity.
658
659   To get connectivity for all geometric type, use Mode=MED_FULL_INTERLACE
660   and Type=MED_ALL_ELEMENTS.
661   You must also get the corresponding index array.
662  */
663 inline const int * MESH::getConnectivity(MED_EN::medModeSwitch Mode,MED_EN::medConnectivity ConnectivityType,MED_EN::medEntityMesh entity, MED_EN::medGeometryElement Type) const
664 {
665   //  checkGridFillConnectivity();
666   if (Mode==MED_EN::MED_FULL_INTERLACE)
667     return _connectivity->getConnectivity(ConnectivityType,entity,Type);
668   throw MEDEXCEPTION(LOCALIZED("MESH::getConnectivity : only for MED_FULL_INTERLACE mode"));
669 }
670 /*!
671   Returns the required index array for a connectivity received in
672   MED_FULL_ENTERLACE mode and MED_ALL_ELEMENTS type.
673
674   This array allow to find connectivity of each elements.
675
676   Example : Connectivity of i^{th} elements (1<=i<=NumberOfElement) begin
677   at index ConnectivityIndex[i-1] and end at index ConnectivityIndex[i]-1
678   in Connectivity array (Connectivity[ConnectivityIndex[i-1]-1] is the
679   first value)
680  */
681 inline const int * MESH::getConnectivityIndex(MED_EN::medConnectivity ConnectivityType,MED_EN::medEntityMesh entity) const
682 {
683   //  checkGridFillConnectivity();
684   return _connectivity->getConnectivityIndex(ConnectivityType, entity);
685 }
686 /*!
687   Return the required connectivity of polygons for the given entity.
688   You must also get the corresponding index array.
689  */
690 inline const int * MESH::getPolygonsConnectivity(MED_EN::medConnectivity ConnectivityType,
691                                                  MED_EN::medEntityMesh Entity) const
692 {
693   return _connectivity->getPolygonsConnectivity(ConnectivityType,Entity);
694 }
695 /*!
696   Return the required index array for polygons connectivity.
697  */
698 inline const int * MESH::getPolygonsConnectivityIndex(MED_EN::medConnectivity ConnectivityType,
699                                                       MED_EN::medEntityMesh Entity) const
700 {
701   return _connectivity->getPolygonsConnectivityIndex(ConnectivityType,Entity);
702 }
703 /*!
704   Return the number of polygons.
705  */
706 inline int MESH::getNumberOfPolygons() const
707 {
708   return _connectivity->getNumberOfPolygons();
709 }
710 /*!
711   Return the required connectivity of polyhedron :
712   - in nodal mode, it gives you the polyhedron faces nodal connectivity.
713   - in descending mode, it gives you the polyhedron faces list.
714   You must also get :
715   - faces index and polyhedron index arrays in nodal mode.
716   - polyhedron index array in descending mode.
717  */
718 inline const int * MESH::getPolyhedronConnectivity(MED_EN::medConnectivity ConnectivityType) const
719 {
720   return _connectivity->getPolyhedronConnectivity(ConnectivityType);
721 }
722 /*!
723   Return the index array of polyhedron faces in nodal mode.
724   You must also get the polyhedron index array.
725  */
726 inline const int * MESH::getPolyhedronFacesIndex() const
727 {
728   return _connectivity->getPolyhedronFacesIndex();
729 }
730 /*!
731   Return the required polyhedron index array.
732  */
733 inline const int * MESH::getPolyhedronIndex(MED_EN::medConnectivity ConnectivityType) const
734 {
735   return _connectivity->getPolyhedronIndex(ConnectivityType);
736 }
737 /*!
738   Return the number of polyhedron faces.
739  */
740 inline int MESH::getNumberOfPolyhedronFaces() const
741 {
742   return _connectivity->getNumberOfPolyhedronFaces();
743 }
744 /*!
745   Return the number of polyhedron.
746  */
747 inline int MESH::getNumberOfPolyhedron() const
748 {
749   return _connectivity->getNumberOfPolyhedron();
750 }
751 /*!
752   Returns the corresponding length of the array returned by MESH::getReverseConnectivity with exactly the same arguments.
753   Used particulary for wrapping CORBA and python.
754  */
755
756 inline int MESH::getReverseConnectivityLength(MED_EN::medConnectivity ConnectivityType,
757                                                     MED_EN::medEntityMesh Entity) const
758 {
759   int spaceDim = getSpaceDimension();
760   int nb;
761
762   if (ConnectivityType == MED_EN::MED_NODAL)
763     {
764       nb = getNumberOfNodes();
765     }
766   else
767     {
768       if (spaceDim == 2)
769         nb = getNumberOfElements(MED_EN::MED_EDGE,
770                                         MED_EN::MED_ALL_ELEMENTS);
771       else if (spaceDim == 3)
772         nb = getNumberOfElements(MED_EN::MED_FACE,
773                                         MED_EN::MED_ALL_ELEMENTS);
774     }
775   return getReverseConnectivityIndex(ConnectivityType)[nb]-1;
776 }
777 /*!
778   Returns the reverse connectivity required by ConnectivityType :
779   - If ConnectivityType=MED_NODAL : returns connectivity node-cell
780   - If ConnectivityType=MED_DESCENDING : returns connectivity face-cell
781
782   You must get ReverseConnectivityIndex array to use it.
783  */
784
785 inline const int * MESH::getReverseConnectivity(MED_EN::medConnectivity ConnectivityType,MED_EN::medEntityMesh Entity/*=MED_CELL*/) const
786 {
787   //  checkGridFillConnectivity();
788   if (NULL==_connectivity)
789     throw MEDEXCEPTION("MESH::getReverseConnectivity : no connectivity defined in MESH !");
790
791   return _connectivity->getReverseConnectivity(ConnectivityType,Entity);
792 }
793 /*!
794   Returns the corresponding length of the array returned by MESH::getReverseConnectivityIndex with exactly the same arguments.
795   Used particulary for wrapping CORBA and python.
796  */
797 inline int MESH::getReverseConnectivityIndexLength(MED_EN::medConnectivity ConnectivityType,
798                                                          MED_EN::medEntityMesh Entity) const
799 {
800   int spaceDim = getSpaceDimension();
801
802   if (ConnectivityType == MED_EN::MED_NODAL)
803     {
804       return getNumberOfNodes()+1;
805     }
806   else
807     {
808       if (spaceDim == 2)
809         return getNumberOfElements(MED_EN::MED_EDGE,MED_EN::MED_ALL_ELEMENTS)+1;
810       else if (spaceDim == 3)
811         return getNumberOfElements(MED_EN::MED_FACE,MED_EN::MED_ALL_ELEMENTS)+1;
812       else
813         throw MEDEXCEPTION("Invalid dimension");
814     }
815 }
816 /*!
817   Returns the index array required by ConnectivityType.
818
819   This array allow to find reverse connectivity of each elements.
820
821   Example : Reverse connectivity of i^{th} elements (1<=i<=NumberOfElement)
822   begin at index ReverseConnectivityIndex[i-1] and end at index
823   ReverseConnectivityIndex[i]-1
824   in ReverseConnectivity array (
825   ReverseConnectivity[ReverseConnectivityIndex[i-1]-1]
826   is the first value)
827  */
828 inline const int * MESH::getReverseConnectivityIndex(MED_EN::medConnectivity ConnectivityType,MED_EN::medEntityMesh Entity/*=MED_CELL*/) const
829 {
830   //  checkGridFillConnectivity();
831   if (NULL==_connectivity)
832     throw MEDEXCEPTION("MESH::getReverseConnectivityIndex : no connectivity defined in MESH !");
833
834   return _connectivity->getReverseConnectivityIndex(ConnectivityType,Entity);
835 }
836
837
838 inline int MESH::getNumberOfFamilies (MED_EN::medEntityMesh entity) const
839 {
840   switch (entity) {
841   case MED_EN::MED_NODE :
842     return _familyNode.size();
843   case MED_EN::MED_CELL :
844     return _familyCell.size();
845   case MED_EN::MED_FACE :
846     return _familyFace.size();
847   case MED_EN::MED_EDGE :
848     return _familyEdge.size();
849   default :
850     throw MEDEXCEPTION("MESH::getNumberOfFamilies : Unknown entity");
851   }
852 }
853 inline int MESH::getNumberOfGroups (MED_EN::medEntityMesh entity) const
854 {
855   switch (entity) {
856   case MED_EN::MED_NODE :
857     return _groupNode.size();
858   case MED_EN::MED_CELL :
859     return _groupCell.size();
860   case MED_EN::MED_FACE :
861     return _groupFace.size();
862   case MED_EN::MED_EDGE :
863     return _groupEdge.size();
864   default :
865     throw MEDEXCEPTION("MESH::getNumberOfGroups : Unknown entity");
866   }
867 }
868 const vector<MEDMEM::FAMILY*> MESH::getFamilies(MED_EN::medEntityMesh entity) const
869 {
870   switch (entity) {
871   case MED_EN::MED_NODE :
872     return _familyNode;
873   case MED_EN::MED_CELL :
874     return _familyCell;
875   case MED_EN::MED_FACE :
876     return _familyFace;
877   case MED_EN::MED_EDGE :
878     return _familyEdge;
879   default :
880     throw MEDEXCEPTION("MESH::getFamilies : Unknown entity");
881   }
882 }
883
884 const vector<GROUP*> MESH::getGroups(MED_EN::medEntityMesh entity) const
885 {
886   switch (entity) {
887   case MED_EN::MED_NODE :
888     return _groupNode;
889   case MED_EN::MED_CELL :
890     return _groupCell;
891   case MED_EN::MED_FACE :
892     return _groupFace;
893   case MED_EN::MED_EDGE :
894     return _groupEdge;
895   default :
896     throw MEDEXCEPTION("MESH::getGroups : Unknown entity");
897   }
898 }
899
900 const MEDMEM::FAMILY* MESH::getFamily(MED_EN::medEntityMesh entity, int i) const
901 {
902   if (i<=0)
903     throw MEDEXCEPTION("MESH::getFamily(i) : argument i must be > 0");
904   vector<FAMILY*> Family;
905   switch (entity) {
906   case MED_EN::MED_NODE : {
907     Family = _familyNode;
908     break;
909   }
910   case MED_EN::MED_CELL : {
911     Family = _familyCell;
912     break;
913   }
914   case MED_EN::MED_FACE : {
915     Family = _familyFace;
916     break;
917   }
918   case MED_EN::MED_EDGE : {
919     Family = _familyEdge;
920     break;
921   }
922   default :
923     throw MEDEXCEPTION("MESH::getFamilies : Unknown entity");
924   }
925   if (i>Family.size())
926     throw MEDEXCEPTION("MESH::getFamily(entity,i) : argument i must be <= _numberOfFamilies");
927   return Family[i-1];
928 }
929
930 const GROUP* MESH::getGroup(MED_EN::medEntityMesh entity, int i) const
931 {
932   const char * LOC = "MESH::getGroup(medEntityMesh entity, int i) : ";
933   if (i<=0)
934     throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"argument i must be > 0"));
935   vector<GROUP*> Group;
936   switch (entity) {
937   case MED_EN::MED_NODE : {
938     Group = _groupNode;
939     break;
940   }
941   case MED_EN::MED_CELL : {
942     Group = _groupCell;
943     break;
944   }
945   case MED_EN::MED_FACE : {
946     Group = _groupFace;
947     break;
948   }
949   case MED_EN::MED_EDGE : {
950     Group = _groupEdge;
951     break;
952   }
953   default :
954     throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Unknown entity"));
955   }
956   if (i>Group.size())
957     throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"argument i="<<i<<" must be <= _numberOfGroups="<<Group.size()));
958   return Group[i-1];
959 }
960
961
962 //    int * get_() {
963 //      return ;
964 //    }
965
966 //inline void MESH::write(const string & driverName)  {
967 //  write(0,driverName);
968 //}
969
970 inline bool MESH::getIsAGrid()
971 {
972   SCRUTE(_isAGrid);
973
974   return _isAGrid;
975 }
976
977 }
978
979 #include "MEDMEM_Support.hxx"
980
981 namespace MEDMEM {
982
983 //Create a new FIELD that should be deallocated based on a SUPPORT that should be deallocated too.
984 template<class T>
985 FIELD<T> *MESH::mergeFields(const vector< FIELD<T>* >& others,bool meshCompare)
986 {
987   const char * LOC = "MESH::mergeFields(const vector< FIELD<T>* >& others,bool meshCompare): ";
988   BEGIN_OF(LOC);
989   int i,j;
990   if(others.size()==0)
991     return 0;
992   vector<SUPPORT *> sup;
993   typename vector< FIELD<T>* >::const_iterator iter;
994   for(iter=others.begin();iter!=others.end();iter++)
995     {
996       sup.push_back((SUPPORT *)(*iter)->getSupport());
997     }
998   iter=others.begin();
999   SUPPORT *retSup=mergeSupports(sup);
1000   int retNumberOfComponents=(*iter)->getNumberOfComponents();
1001   FIELD<T> *ret=new FIELD<T>(retSup,retNumberOfComponents,MED_EN::MED_FULL_INTERLACE);
1002   ret->setValueType((*iter)->getValueType());
1003   T* valuesToSet=(T*)ret->getValue(MED_EN::MED_FULL_INTERLACE);
1004   int nbOfEltsRetSup=retSup->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS);
1005   T* tempValues=new T[retNumberOfComponents];
1006   if(retSup->isOnAllElements())
1007     {
1008       for(i=0;i<nbOfEltsRetSup;i++)
1009         {
1010           bool found=false;
1011           for(iter=others.begin();iter!=others.end() && !found;iter++)
1012             {
1013               found=(*iter)->getValueOnElement(i+1,tempValues);
1014               if(found)
1015                 for(j=0;j<retNumberOfComponents;j++)
1016                   valuesToSet[i*retNumberOfComponents+j]=tempValues[j];
1017             }
1018         }
1019     }
1020   else
1021     {
1022       const int *eltsRetSup=retSup->getNumber(MED_EN::MED_ALL_ELEMENTS);
1023       for(i=0;i<nbOfEltsRetSup;i++)
1024         {
1025           bool found=false;
1026           for(iter=others.begin();iter!=others.end() && !found;iter++)
1027             {
1028               found=(*iter)->getValueOnElement(eltsRetSup[i],tempValues);
1029               if(found)
1030                 for(j=0;j<retNumberOfComponents;j++)
1031                   valuesToSet[i*retNumberOfComponents+j]=tempValues[j];
1032             }
1033           if(!found)
1034             throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<" Merging error due to an error in merging support"));
1035         }
1036     }
1037   delete [] tempValues;
1038   END_OF(LOC);
1039   return ret;
1040 }
1041
1042 }
1043
1044 #endif /* MESH_HXX */