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