Salome HOME
correct a small bug appearing when using the gcc 3.2.1.
[modules/med.git] / src / MEDMEM / MEDMEM_Mesh.hxx
1 #ifndef MESH_HXX
2 #define MESH_HXX
3
4 #include <string>
5 #include <vector>
6
7 #include "utilities.h"
8 #include "MEDMEM_STRING.hxx"
9 #include "MEDMEM_Exception.hxx"
10 #include "MEDMEM_define.hxx"
11
12 //#include "MEDMEM_Support.hxx"
13 #include "MEDMEM_Coordinate.hxx"
14 #include "MEDMEM_Connectivity.hxx"
15
16 // Add your own driver header (step 2)
17 #include "MEDMEM_MedMeshDriver.hxx"
18 #include "MEDMEM_MedMedDriver.hxx"
19 #include "MEDMEM_GibiMeshDriver.hxx"
20
21 #include "MEDMEM_VtkMeshDriver.hxx"
22
23
24
25 //class GENDRIVER;
26 //class MED_MESH_RDONLY_DRIVER;
27 //class MED_MESH_WRONLY_DRIVER;
28
29 using namespace MED_EN;
30
31 /*! This class contains all the informations related with a MESH :
32   - COORDINATES
33   - CONNECTIVITIES
34   - FAMILIES OF NODES
35   - FAMILIES OF CELLS
36   - FAMILIES OF FACES
37   - FAMILIES OF EDGES
38
39   NOTE: A Family is only on one type of entity (MED_CELL, MED_FACE, MED_EDGE, MED_NODE).
40   You can't have a family on MED_CELL and MED_FACE
41
42 */
43
44 namespace MEDMEM {
45
46 template <class T> class FIELD;
47
48 class CELLMODEL;
49 class FAMILY;
50 class GROUP;
51 class SUPPORT;
52 class MESH
53 {
54
55
56 public :
57
58   // ------- Drivers Management Part
59 protected:
60
61   //-----------------------//
62   class INSTANCE
63   //-----------------------//
64   {
65   public:
66     virtual GENDRIVER * run(const string & fileName, MESH * ptrMesh) const = 0;
67   };
68
69   //-------------------------------------------------------//
70   template <class T> class INSTANCE_DE : public INSTANCE
71   //-------------------------------------------------------//
72   {
73   public :
74     GENDRIVER * run(const string & fileName, MESH * ptrMesh) const
75     { return new T(fileName,ptrMesh); }
76   };
77
78   // Add a similar line for your personnal driver (step 3)
79
80   static INSTANCE_DE<MED_MESH_RDWR_DRIVER>  inst_med;
81   static INSTANCE_DE<GIBI_MESH_RDWR_DRIVER> inst_gibi;
82   static INSTANCE_DE<VTK_MESH_DRIVER> inst_vtk;
83
84   //static INSTANCE_DE<VTK_DRIVER>   inst_vtk  ;
85   static const INSTANCE * const instances[];
86
87   // ------ End of Drivers Management Part
88
89
90   //-----------------------//
91   //   Attributes
92   //-----------------------//
93
94 protected :
95
96   string        _name; // A POSITIONNER EN FCT DES IOS ?
97
98   mutable COORDINATE *   _coordinate;
99   mutable CONNECTIVITY * _connectivity;
100
101   int   _spaceDimension;
102   int   _meshDimension;
103   int   _numberOfNodes;
104
105   int             _numberOfNodesFamilies;  //INUTILE ? -> _familyNode.size()
106   vector<FAMILY*> _familyNode;  // array of size _numberOfNodesFamilies;
107   int             _numberOfCellsFamilies;
108   vector<FAMILY*> _familyCell;  // array of size _numberOfCellsFamilies;
109   int             _numberOfFacesFamilies;
110   vector<FAMILY*> _familyFace;  // array of size _numberOfFacesFamilies;
111   int             _numberOfEdgesFamilies;
112   vector<FAMILY*> _familyEdge;  // array of size _numberOfEdgesFamilies;
113
114   int            _numberOfNodesGroups; //INUTILE ?
115   vector<GROUP*> _groupNode;    // array of size _numberOfNodesGroups;
116   int            _numberOfCellsGroups; //INUTILE ?
117   vector<GROUP*> _groupCell;    // array of size _numberOfCellsGroups;
118   int            _numberOfFacesGroups; //INUTILE ?
119   vector<GROUP*> _groupFace;    // array of size _numberOfFacesGroups;
120   int            _numberOfEdgesGroups; //INUTILE ?
121   vector<GROUP*> _groupEdge;    // array of size _numberOfEdgesGroups;
122   // list of all Group
123
124   vector<GENDRIVER *> _drivers; // Storage of the drivers currently in use
125
126   bool           _isAGrid;      // am I a GRID or not
127
128   //-----------------------//
129   //   Methods
130   //-----------------------//
131
132 //   inline void checkGridFillCoords() const;
133 //   inline void checkGridFillConnectivity() const;
134   bool isEmpty() const;
135   // if this->_isAGrid, assure that _coordinate and _connectivity are filled
136
137 public :
138
139   // Add your personnal driver line (step 2)
140   friend class MED_MESH_RDONLY_DRIVER;
141   friend class MED_MESH_WRONLY_DRIVER;
142
143   friend class MED_MED_RDONLY_DRIVER;
144   friend class MED_MED_WRONLY_DRIVER;
145   friend class MED_MED_RDWR_DRIVER;
146
147   friend class GIBI_MESH_RDONLY_DRIVER;
148   friend class GIBI_MESH_WRONLY_DRIVER;
149   friend class GIBI_MESH_RDWR_DRIVER;
150
151   friend class VTK_MESH_DRIVER;
152
153   void init();
154   MESH();
155   MESH(MESH &m);
156   MESH & operator=(const MESH &m);
157   MESH( driverTypes driverType, const string & fileName="",
158         const string & meshName="") throw (MEDEXCEPTION);
159   virtual ~MESH();
160   friend ostream & operator<<(ostream &os, const MESH &my);
161
162   int  addDriver(driverTypes driverType,
163                  const string & fileName  ="Default File Name.med",
164                  const string & driverName="Default Mesh Name");
165   int  addDriver(GENDRIVER & driver);
166   void rmDriver(int index=0);
167
168   virtual void read(int index=0);
169   inline void read(const MED_MED_DRIVER & genDriver);
170   inline void write(int index=0, const string & driverName = "");
171   inline void write(const MED_MED_DRIVER & genDriver);
172
173   //  void calculateReverseConnectivity();
174   //  void createFaces();       //Faces creation => full constituent informations
175   //  void buildConstituent(); // calculate descendent connectivity + face-cell connectivity
176
177
178   inline void         setName(string name);
179
180   inline string       getName() const;
181   inline int          getSpaceDimension() const;
182   inline int          getMeshDimension() const;
183   inline bool         getIsAGrid();
184
185   inline int                        getNumberOfNodes() const;
186   virtual inline const COORDINATE * getCoordinateptr() const;
187   inline string                     getCoordinatesSystem() const;
188   virtual inline const double *     getCoordinates(medModeSwitch Mode) const;
189   virtual inline const double       getCoordinate(int Number,int Axis) const;
190   inline const string *             getCoordinatesNames() const;
191   inline const string *             getCoordinatesUnits() const;
192   //inline int *                    getNodesNumbers();
193
194   virtual inline int             getNumberOfTypes(medEntityMesh Entity) const;
195   virtual inline const medGeometryElement * getTypes(medEntityMesh Entity) const;
196   virtual inline const CELLMODEL * getCellsTypes(medEntityMesh Entity) const;
197   virtual const int * getGlobalNumberingIndex(medEntityMesh Entity) const;
198   virtual inline int getNumberOfElements(medEntityMesh Entity,
199                                          medGeometryElement Type) const;
200   virtual inline bool existConnectivity(medConnectivity ConnectivityType,
201                                         medEntityMesh Entity) const;
202
203   virtual inline medGeometryElement getElementType(medEntityMesh Entity,
204                                                    int Number) const;
205   virtual inline void calculateConnectivity(medModeSwitch Mode,
206                                             medConnectivity ConnectivityType,
207                                             medEntityMesh Entity) const ;
208   virtual inline const int * getConnectivity(medModeSwitch Mode,
209                                              medConnectivity ConnectivityType,
210                                              medEntityMesh Entity, 
211                                              medGeometryElement Type) const;
212   virtual inline const int * getConnectivityIndex(medConnectivity ConnectivityType,
213                                                   medEntityMesh Entity) const;
214   virtual int                 getElementNumber(medConnectivity ConnectivityType, 
215                                                medEntityMesh Entity, 
216                                                medGeometryElement Type, 
217                                                int * connectivity) const;
218
219   virtual inline const int * getReverseConnectivity(medConnectivity ConnectivityType,
220                                                     medEntityMesh Entity=MED_CELL) const;
221   virtual inline const int * getReverseConnectivityIndex(medConnectivity ConnectivityType,
222                                                          medEntityMesh Entity=MED_CELL) const;
223
224   virtual int                          getNumberOfFamilies(medEntityMesh Entity) const;
225   virtual inline const vector<FAMILY*> getFamilies(medEntityMesh Entity) const;
226   virtual inline const FAMILY*         getFamily(medEntityMesh Entity,int i) const;
227   virtual int                          getNumberOfGroups(medEntityMesh Entity) const;
228   virtual inline const vector<GROUP*>  getGroups(medEntityMesh Entity) const;
229   virtual inline const GROUP*          getGroup(medEntityMesh Entity,int i) const;
230   virtual inline const CONNECTIVITY* getConnectivityptr() const;
231   virtual SUPPORT *                    getBoundaryElements(medEntityMesh Entity) 
232                                                 throw (MEDEXCEPTION);
233   // problème avec le maillage dans le support : 
234   //            le pointeur n'est pas const, mais sa valeur oui. A voir !!! PG
235
236   SUPPORT *                            getSkin(const SUPPORT * Support3D) 
237                                                 throw (MEDEXCEPTION);
238
239   //  Node DonneBarycentre(const Cell &m) const;
240   virtual FIELD<double>* getVolume (const SUPPORT * Support) const 
241                                 throw (MEDEXCEPTION); 
242                                 // Support must be on 3D elements
243   virtual FIELD<double>* getArea (const SUPPORT * Support) const 
244                                 throw (MEDEXCEPTION); 
245                                 // Support must be on 2D elements
246   virtual FIELD<double>* getLength (const SUPPORT * Support) const 
247                                 throw (MEDEXCEPTION); 
248                                 // Support must be on 1D elements
249   virtual FIELD<double>* getNormal (const SUPPORT * Support) const 
250                                 throw (MEDEXCEPTION); 
251                                 // Support must be on 2D elements
252   virtual FIELD<double>* getBarycenter (const SUPPORT * Support) const 
253                                 throw (MEDEXCEPTION);
254   //  FIELD<int>* getNeighbourhood(SUPPORT * Support) const 
255   //                            throw (MEDEXCEPTION); // Il faut preciser !
256
257   /*!
258     return a SUPPORT pointer on the union of all SUPPORTs in Supports.
259     You should delete this pointer after use to avois memory leaks.
260   */
261   SUPPORT * mergeSupports(const vector<SUPPORT *> Supports) const throw (MEDEXCEPTION) ;
262
263   /*!
264     return a SUPPORT pointer on the intersection of all SUPPORTs in Supports.
265     The (SUPPORT *) NULL pointer is returned if the intersection is empty.
266     You should delete this pointer after use to avois memory leaks.
267    */
268   SUPPORT * intersectSupports(const vector<SUPPORT *> Supports) const throw (MEDEXCEPTION) ;
269 };
270 };
271
272 using namespace MEDMEM;
273 // ---------------------------------------
274 //              Methodes Inline
275 // ---------------------------------------
276
277 inline const CONNECTIVITY* MESH::getConnectivityptr() const
278 {
279 //   checkGridFillConnectivity();
280   return _connectivity;
281 }
282
283 // inline void MESH::read(int index/*=0*/)
284 // {
285 //   const char * LOC = "MESH::read(int index=0) : ";
286 //   BEGIN_OF(LOC);
287
288 //   if (_drivers[index]) {
289 //     _drivers[index]->open();
290 //     _drivers[index]->read();
291 //     _drivers[index]->close();
292 //   }
293 //   else
294 //     throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
295 //                                      << "The index given is invalid, index must be between  0 and |"
296 //                                      << _drivers.size()
297 //                                      )
298 //                           );
299 //   END_OF(LOC);
300 // }
301
302 /*! Write all the content of the MESH using driver referenced by the handler <index>*/
303 inline void MESH::write(int index/*=0*/, const string & driverName/* = ""*/)
304 {
305   const char * LOC = "MESH::write(int index=0, const string & driverName = \"\") : ";
306   BEGIN_OF(LOC);
307
308   if ( _drivers[index] ) {
309     _drivers[index]->open();
310     if (driverName != "") _drivers[index]->setMeshName(driverName);
311     _drivers[index]->write();
312     _drivers[index]->close();
313   }
314   else
315     throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
316                                      << "The index given is invalid, index must be between  0 and |"
317                                      << _drivers.size()
318                                      )
319                           );
320   END_OF(LOC);
321 }
322
323 // This method is MED specific : don't use it
324 // must be private.
325 inline void MESH::write(const MED_MED_DRIVER & genDriver)
326 {
327   const char * LOC = "MESH::write(const MED_MED_DRIVER & genDriver): ";
328   BEGIN_OF(LOC);
329
330   for (unsigned int index=0; index < _drivers.size(); index++ )
331     if ( *_drivers[index] == genDriver ) {
332       _drivers[index]->open();
333       _drivers[index]->write();
334       _drivers[index]->close();
335       // ? FINALEMENT PAS BESOIN DE L'EXCEPTION ?
336     }
337
338   END_OF(LOC);
339
340 }
341
342 // This method is MED specific : don't use it
343 // must be private.
344 inline void MESH::read(const MED_MED_DRIVER & genDriver)
345 {
346   const char * LOC = "MESH::read(const MED_MED_DRIVER & genDriver): ";
347   BEGIN_OF(LOC);
348
349   for (unsigned int index=0; index < _drivers.size(); index++ )
350     if ( *_drivers[index] == genDriver ) {
351       _drivers[index]->open();
352       _drivers[index]->read();
353       _drivers[index]->close();
354       // ? FINALEMENT PAS BESOIN DE L'EXCEPTION ?
355     }
356
357   END_OF(LOC);
358
359 }
360
361 /*! Set the MESH name */
362 inline void MESH::setName(string name)
363 {
364   _name=name; //NOM interne Ã  la classe
365 }
366
367 /*! Get the MESH name */
368 inline string MESH::getName() const
369 {
370   return _name;
371 }
372
373 /*! Get the dimension of the space */
374 inline int MESH::getSpaceDimension() const
375 {
376   return _spaceDimension;
377 }
378
379 /*! Get the dimension of the MESH */
380 inline int MESH::getMeshDimension() const
381 {
382   return _meshDimension;
383 }
384
385 /*! Get the number of nodes used in the MESH */
386 inline int MESH::getNumberOfNodes() const
387 {
388   return _numberOfNodes;
389 }
390
391 /*! Get the COORDINATES object. Use it only if you need COORDINATES informations not provided by the MESH class.*/
392 inline const COORDINATE * MESH::getCoordinateptr() const
393 {
394 //   checkGridFillCoords();
395   return _coordinate;
396 }
397
398 /*! Get the system in which coordinates are given (CARTESIAN,CYLINDRICAL,SPHERICAL) __??MED_CART??__. */
399 inline string MESH::getCoordinatesSystem() const
400 {
401   return _coordinate->getCoordinatesSystem();
402 }
403
404 /*! Get the whole coordinates array in a given interlacing mode. The interlacing mode are :
405   - MED_NO_INTERLACE   :  X1 X2 Y1 Y2 Z1 Z2
406   - MED_FULL_INTERLACE :  X1 Y1 Z1 X2 Y2 Z2
407  */
408 inline const double * MESH::getCoordinates(medModeSwitch Mode) const
409 {
410 //   checkGridFillCoords();
411   return _coordinate->getCoordinates(Mode);
412 }
413
414 /*! Get the coordinate n° number on axis n°axis*/
415 inline const double MESH::getCoordinate(int number, int axis) const
416 {
417 //   checkGridFillCoords();
418   return _coordinate->getCoordinate(number,axis);
419 }
420
421 /*! Get the coordinate names array ("x       ","y       ","z       ")
422   of size n*MED_TAILLE_PNOM
423 */
424 inline const string * MESH::getCoordinatesNames() const
425 {
426   return _coordinate->getCoordinatesNames();
427 }
428
429 /*! Get the coordinate unit names array ("cm       ","cm       ","cm       ")
430   of size n*MED_TAILLE_PNOM
431 */
432 inline const string * MESH::getCoordinatesUnits() const
433 {
434   return _coordinate->getCoordinatesUnits();
435 }
436 //  int * MESH::getNodesNumbers() const
437 //  {
438 //    return nodesNumbers;
439 //  }
440
441 /*! Get the number of different geometric types for a given entity type.
442
443     For exemple getNumberOfTypes(MED_CELL) would return 3 if the MESH
444     have some MED_TETRA4, MED_PYRA5 and MED_HEXA6 in it.
445
446     medEntityMesh entity : MED_CELL, MED_FACE, MED_EDGE, MED_NODE, MED_ALL_ENTITIES
447
448     If entity is not defined, return 0.
449
450     If there is no connectivity, return an exception.
451 */
452 inline int MESH::getNumberOfTypes(medEntityMesh entity) const
453 {
454   MESSAGE("MESH::getNumberOfTypes(medEntityMesh entity) : "<<entity);
455   if (entity == MED_NODE)
456     return 1;
457 //   checkGridFillConnectivity();
458   if (_connectivity != NULL)
459     return _connectivity->getNumberOfTypes(entity);
460   throw MEDEXCEPTION(LOCALIZED("MESH::getNumberOfTypes( medEntityMesh ) : Connectivity not defined !"));
461 }
462
463 /*!
464   Get the list of geometric types used by a given entity.
465   medEntityMesh entity : MED_CELL, MED_FACE, MED_EDGE, MED_ALL_ENTITIES
466
467   REM : Don't use MED_NODE
468
469   If entity is not defined, return an exception.
470 */
471 inline const medGeometryElement * MESH::getTypes(medEntityMesh entity) const
472 {
473   if (entity == MED_NODE)
474     throw MEDEXCEPTION(LOCALIZED("MESH::getTypes( medEntityMesh ) : No medGeometryElement with MED_NODE entity !"));
475   // return un tableau de taille 1 contenant MED_NONE, comme les supports pour etre coherent avec getNumberOfTypes ???? PG
476
477 //   checkGridFillConnectivity();
478   if (_connectivity != NULL)
479     return _connectivity->getGeometricTypes(entity);
480   throw MEDEXCEPTION(LOCALIZED("MESH::getTypes( medEntityMesh ) : Connectivity not defined !"));
481 }
482
483 /*!
484   Get the whole list of CELLMODEL used by cells of given type (medEntityMesh).
485
486   REMARK : Don't use MED_NODE as medEntityMesh
487 */
488 inline const CELLMODEL * MESH::getCellsTypes(medEntityMesh Entity) const
489 {
490   //  checkGridFillConnectivity();
491   if (_connectivity != NULL)
492     return _connectivity->getCellsTypes(Entity);
493   throw MEDEXCEPTION(LOCALIZED("MESH::getCellsTypes( medEntityMesh ) : Connectivity not defined !"));
494 }
495
496 /*! Return an array of size NumbreOfTypes+1 which contains, for each
497     geometric type of the given entity, the first global element number
498     of this type.
499
500     For exemple, if we have a mesh with 5 triangles and 4 quadrangle :
501     - size of GlobalNumberingIndex is 3
502     - GlobalNumberingIndex[0]=1 (the first type)
503     - GlobalNumberingIndex[1]=6 (the second type)
504     - GlobalNumberingIndex[2]=10
505 */
506 inline const int * MESH::getGlobalNumberingIndex(medEntityMesh entity) const
507 {
508   //  checkGridFillConnectivity();
509   if (_connectivity != NULL)
510     return _connectivity->getGlobalNumberingIndex(entity);
511   throw MEDEXCEPTION(LOCALIZED("MESH::getNumberOfTypes( medEntityMesh ) : Connectivity not defined !"));
512 }
513 /*!
514   Return the number of element of given geometric type of given entity. Return 0 if query is not defined.
515
516   Example :
517   - getNumberOfElements(MED_NODE,MED_NONE) : number of node
518   - getNumberOfElements(MED_NODE,MED_TRIA3) : return 0 (not defined)
519   - getNumberOfElements(MED_FACE,MED_TRIA3) : return number of triangles
520   elements defined in face entity (0 if not defined)
521   - getNumberOfElements(MED_CELL,MED_ALL_ELEMENTS) : return total number
522   of elements defined in cell entity
523  */
524 inline int MESH::getNumberOfElements(medEntityMesh entity, medGeometryElement Type) const
525 {
526   //  const char * LOC = "MESH::getNumberOfElements(medEntityMesh,medGeometryElement) : ";
527   if (entity==MED_NODE)
528     if ((Type==MED_NONE)|(Type==MED_ALL_ELEMENTS))
529       return _numberOfNodes;
530     else
531       return 0;
532   //throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"wrong medGeometryElement with MED_NODE"));
533   else
534     {
535 //       checkGridFillConnectivity();
536       if (_connectivity != (CONNECTIVITY*)NULL)
537         return _connectivity->getNumberOf(entity,Type);
538       else
539         return 0;
540       //throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"connectivity not defined !"));
541     }
542 }
543 /*!
544   Return true if the wanted connectivity exist, else return false
545   (to use before a getSomething method).
546  */
547 inline bool MESH::existConnectivity(medConnectivity connectivityType, medEntityMesh entity) const
548 {
549 //   checkGridFillConnectivity();
550   if (_connectivity==(CONNECTIVITY*)NULL)
551     throw MEDEXCEPTION("MESH::existConnectivity(medConnectivity,medEntityMesh) : no connectivity defined !");
552   return _connectivity->existConnectivity(connectivityType,entity);
553 }
554 /*!
555   Return the geometric type of global element Number of entity Entity.
556
557   Throw an exception if Entity is not defined or Number are wrong (too big).
558  */
559 inline medGeometryElement MESH::getElementType(medEntityMesh Entity,int Number) const
560 {
561   //  checkGridFillConnectivity();
562   if (_connectivity==(CONNECTIVITY*)NULL)
563     throw MEDEXCEPTION("MESH::getElementType(medEntityMesh,int) : no connectivity defined !");
564   return _connectivity->getElementType(Entity,Number);
565 }
566 /*!
567   Calculate the ask connectivity. Return an exception if this could not be
568   done. Do nothing if connectivity already exist.
569  */
570
571 inline void MESH::calculateConnectivity(medModeSwitch Mode,medConnectivity ConnectivityType,medEntityMesh entity) const
572 {
573   //  checkGridFillConnectivity();
574   if (Mode==MED_FULL_INTERLACE)
575     _connectivity->calculateConnectivity(ConnectivityType,entity);
576   else
577     throw MEDEXCEPTION(LOCALIZED("MESH::calculateConnectivity : only for MED_FULL_INTERLACE mode"));
578 }
579 /*!
580   Return the required connectivity in the right mode for the given
581   geometric type of the given entity.
582
583   To get connectivity for all geometric type, use Mode=MED_FULL_INTERLACE
584   and Type=MED_ALL_ELEMENTS.
585   You must also get the corresponding index array.
586  */
587 inline const int * MESH::getConnectivity(medModeSwitch Mode,medConnectivity ConnectivityType,medEntityMesh entity, medGeometryElement Type) const
588 {
589   //  checkGridFillConnectivity();
590   if (Mode==MED_FULL_INTERLACE)
591     return _connectivity->getConnectivity(ConnectivityType,entity,Type);
592   throw MEDEXCEPTION(LOCALIZED("MESH::getConnectivity : only for MED_FULL_INTERLACE mode"));
593 }
594 /*!
595   Return the required index array for a connectivity received in
596   MED_FULL_ENTERLACE mode and MED_ALL_ELEMENTS type.
597
598   This array allow to find connectivity of each elements.
599
600   Example : Connectivity of i^{th} elements (1<=i<=NumberOfElement) begin
601   at index ConnectivityIndex[i-1] and end at index ConnectivityIndex[i]-1
602   in Connectivity array (Connectivity[ConnectivityIndex[i-1]-1] is the
603   first value)
604  */
605 inline const int * MESH::getConnectivityIndex(medConnectivity ConnectivityType,medEntityMesh entity) const
606 {
607   //  checkGridFillConnectivity();
608   return _connectivity->getConnectivityIndex(ConnectivityType, entity);
609 }
610 /*!
611   Return the reverse connectivity required by ConnectivityType :
612   - If ConnectivityType=MED_NODAL : return connectivity node-cell
613   - If ConnectivityType=MED_DESCENDING : return connectivity face-cell
614
615   You must get ReverseConnectivityIndex array to use it.
616  */
617 inline const int * MESH::getReverseConnectivity(medConnectivity ConnectivityType,medEntityMesh Entity/*=MED_CELL*/) const
618 {
619   //  checkGridFillConnectivity();
620   if (NULL==_connectivity)
621     throw MEDEXCEPTION("MESH::getReverseConnectivity : no connectivity defined in MESH !");
622
623   return _connectivity->getReverseConnectivity(ConnectivityType,Entity);
624 }
625 /*!
626   Return the index array required by ConnectivityType.
627
628   This array allow to find reverse connectivity of each elements.
629
630   Example : Reverse connectivity of i^{th} elements (1<=i<=NumberOfElement)
631   begin at index ReverseConnectivityIndex[i-1] and end at index
632   ReverseConnectivityIndex[i]-1
633   in ReverseConnectivity array (
634   ReverseConnectivity[ReverseConnectivityIndex[i-1]-1]
635   is the first value)
636  */
637 inline const int * MESH::getReverseConnectivityIndex(medConnectivity ConnectivityType,medEntityMesh Entity/*=MED_CELL*/) const
638 {
639   //  checkGridFillConnectivity();
640   if (NULL==_connectivity)
641     throw MEDEXCEPTION("MESH::getReverseConnectivityIndex : no connectivity defined in MESH !");
642
643   return _connectivity->getReverseConnectivityIndex(ConnectivityType,Entity);
644 }
645
646
647 inline int MESH::getNumberOfFamilies (medEntityMesh entity) const
648 {
649   switch (entity) {
650   case MED_NODE :
651     return _numberOfNodesFamilies;
652   case MED_CELL :
653     return _numberOfCellsFamilies;
654   case MED_FACE :
655     return _numberOfFacesFamilies;
656   case MED_EDGE :
657     return _numberOfEdgesFamilies;
658   default :
659     throw MEDEXCEPTION("MESH::getNumberOfFamilies : Unknown entity");
660   }
661 }
662 inline int MESH::getNumberOfGroups (medEntityMesh entity) const
663 {
664   switch (entity) {
665   case MED_NODE :
666     return _numberOfNodesGroups;
667   case MED_CELL :
668     return _numberOfCellsGroups;
669   case MED_FACE :
670     return _numberOfFacesGroups;
671   case MED_EDGE :
672     return _numberOfEdgesGroups;
673   default :
674     throw MEDEXCEPTION("MESH::getNumberOfGroups : Unknown entity");
675   }
676 }
677 const vector<MEDMEM::FAMILY*> MESH::getFamilies(medEntityMesh entity) const
678 {
679   switch (entity) {
680   case MED_NODE :
681     return _familyNode;
682   case MED_CELL :
683     return _familyCell;
684   case MED_FACE :
685     return _familyFace;
686   case MED_EDGE :
687     return _familyEdge;
688   default :
689     throw MEDEXCEPTION("MESH::getFamilies : Unknown entity");
690   }
691 }
692
693 const vector<GROUP*> MESH::getGroups(medEntityMesh entity) const
694 {
695   switch (entity) {
696   case MED_NODE :
697     return _groupNode;
698   case MED_CELL :
699     return _groupCell;
700   case MED_FACE :
701     return _groupFace;
702   case MED_EDGE :
703     return _groupEdge;
704   default :
705     throw MEDEXCEPTION("MESH::getGroups : Unknown entity");
706   }
707 }
708
709 const MEDMEM::FAMILY* MESH::getFamily(medEntityMesh entity, int i) const
710 {
711   if (i<=0)
712     throw MEDEXCEPTION("MESH::getFamily(i) : argument i must be > 0");
713   int NumberOfFamilies = 0;
714   vector<FAMILY*> Family;
715   switch (entity) {
716   case MED_NODE : {
717     NumberOfFamilies = _numberOfNodesFamilies;
718     Family = _familyNode;
719     break;
720   }
721   case MED_CELL : {
722     NumberOfFamilies = _numberOfCellsFamilies;
723     Family = _familyCell;
724     break;
725   }
726   case MED_FACE : {
727     NumberOfFamilies = _numberOfFacesFamilies;
728     Family = _familyFace;
729     break;
730   }
731   case MED_EDGE : {
732     NumberOfFamilies = _numberOfEdgesFamilies;
733     Family = _familyEdge;
734     break;
735   }
736   default :
737     throw MEDEXCEPTION("MESH::getFamilies : Unknown entity");
738   }
739   if (i>NumberOfFamilies)
740     throw MEDEXCEPTION("MESH::getFamily(entity,i) : argument i must be <= _numberOfFamilies");
741   return Family[i-1];
742 }
743
744 const GROUP* MESH::getGroup(medEntityMesh entity, int i) const
745 {
746   const char * LOC = "MESH::getGroup(medEntityMesh entity, int i) : ";
747   if (i<=0)
748     throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"argument i must be > 0"));
749   int NumberOfGroups = 0;
750   vector<GROUP*> Group;
751   switch (entity) {
752   case MED_NODE : {
753     NumberOfGroups = _numberOfNodesGroups;
754     Group = _groupNode;
755     break;
756   }
757   case MED_CELL : {
758     NumberOfGroups = _numberOfCellsGroups;
759     Group = _groupCell;
760     break;
761   }
762   case MED_FACE : {
763     NumberOfGroups = _numberOfFacesGroups;
764     Group = _groupFace;
765     break;
766   }
767   case MED_EDGE : {
768     NumberOfGroups = _numberOfEdgesGroups;
769     Group = _groupEdge;
770     break;
771   }
772   default :
773     throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Unknown entity"));
774   }
775   if (i>NumberOfGroups)
776     throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"argument i="<<i<<" must be <= _numberOfGroups="<<NumberOfGroups));
777   return Group[i-1];
778 }
779
780
781 //    int * get_() {
782 //      return ;
783 //    }
784
785 //inline void MESH::write(const string & driverName)  {
786 //  write(0,driverName);
787 //}
788
789 inline bool MESH::getIsAGrid()
790 {
791   SCRUTE(_isAGrid);
792
793   return _isAGrid;
794 }
795
796 #endif /* MESH_HXX */