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