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