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