]> SALOME platform Git repositories - modules/med.git/blob - src/MEDMEM/MEDMEM_Connectivity.hxx
Salome HOME
update after merging trhe branches CEA_V3_0_x, OCC_V3_1_0_a1_x, and the main
[modules/med.git] / src / MEDMEM / MEDMEM_Connectivity.hxx
1 #ifndef CONNECTIVITY_HXX
2 #define CONNECTIVITY_HXX
3
4 #include <vector>
5
6 #include "MEDMEM_Utilities.hxx"
7 #include "MEDMEM_Exception.hxx"
8 #include "MEDMEM_define.hxx"
9 #include "MEDMEM_PolyhedronArray.hxx"
10
11 namespace MEDMEM {
12 class MEDSKYLINEARRAY;
13 class CELLMODEL;
14 class FAMILY;
15 class GROUP;
16
17 /*!
18         This class deals with all type of connectivity .\n
19         it a recursive class.
20 */
21
22 /* ------------------------------------------- */
23 class CONNECTIVITY
24 /* ------------------------------------------- */
25 {
26   /* ---------------------- */
27   /*    Class Attributs     */
28   /* ---------------------- */
29
30 protected:
31                                          /*! contains MED_CELL MED_FACE or MED_EDGE */
32   MED_EN::medEntityMesh           _entity;
33                                          /*! contains MED_NODAL or MED_DESCEND */
34   MED_EN::medConnectivity         _typeConnectivity;
35                                          /*! count of differents cells types
36                                             used by the mesh */
37   int                 _numberOfTypes;
38                                         /*! array of all med_geometric_type used by MESH. */
39   MED_EN::medGeometryElement*     _geometricTypes;
40
41                                         /*! map indexed by med_geometric_type
42                                             which contains the different
43                                             'CellModel' used by MESH. */
44   CELLMODEL *             _type;
45                                         /*! contains the dimension of the entity */
46   int                 _entityDimension;
47
48                                         /*! needed by calculateReverseNodalConnectivity */
49   int                 _numberOfNodes;
50
51                                          /*! array of size _numberOfTypes+1 which
52                                          gives for each cell type the first
53                                          cell number in _nodal or _descending
54                                          array (depends on _typeConnectivity)
55                                          To get cells count for one type, we
56                                          must minus _count[i+1] and _count[i]
57                                          ( 0 <= i < _numberOfTypes ).
58                                          Note that _count[_numberOfTypes] returns
59                                          total cells count + 1 */
60   int *               _count;
61
62                                         /*! pointer to an array which stores the nodal connectivity */
63   MEDSKYLINEARRAY* _nodal;
64                                         /*! pointer to an array which stores the nodal connectivity only for polygons */
65   MEDSKYLINEARRAY* _polygonsNodal;
66                                         /*! pointer to an array which stores the nodal connectivity only for polyhedron */
67   POLYHEDRONARRAY* _polyhedronNodal;
68                                         /*! pointer to an array which stores
69                                             the descending connectivity */
70   MEDSKYLINEARRAY* _descending;
71                                         /*!  pointer to an array which stores the descending connectivity only for polygons */
72   MEDSKYLINEARRAY* _polygonsDescending;
73                                         /*!  pointer to an array which stores the descending connectivity only for polyhedron */
74   MEDSKYLINEARRAY* _polyhedronDescending;
75                                         /*! pointer to an array which stores
76                                             the reverse nodal connectivity */
77   MEDSKYLINEARRAY* _reverseNodalConnectivity;
78                                         /*! pointer to an array which stores
79                                             the reverse descending connectivity */
80   MEDSKYLINEARRAY* _reverseDescendingConnectivity;
81                                         /*! if face or edge, list of 2 cells or
82                                             2 faces it belongs to.
83                                             If 2nd number equals 0, we have a
84                                             boundary entity. We could use
85                                             MEDSKYLINEARRAY, but we suppose we have
86                                             always only 2 (or 1) entities. */
87   MEDSKYLINEARRAY* _neighbourhood;
88                                         /*! connectivity of sub cell if
89                                             descendant connectivity is calculated */
90   CONNECTIVITY * _constituent;
91
92   /* -------------------- */
93   /*    Class Methods     */
94   /* -------------------- */
95
96 private:
97                                         /*! private method :\n
98                                             does nothing if already exists, else
99                                             evaluates _nodal from _descending */
100   void  calculateNodalConnectivity();
101                                         /*! private method :\n
102                                             does nothing if already exists, else
103                                             evaluates from _nodal */
104   void calculateReverseNodalConnectivity();
105                                         /*! private method :\n
106                                             does nothing if already exists, else
107                                             evaluates _descending from _nodal */
108   void calculateDescendingConnectivity();
109                                         /*! private method :\n
110                                             does nothing if already exists, else
111                                             evaluates from _descending */
112   //  void calculateReverseDescendingConnectivity(CONNECTIVITY *myConnectivity);
113
114   const int*      getReverseNodalConnectivity           ();
115   const int*      getReverseNodalConnectivityIndex      ();
116   const int*      getReverseDescendingConnectivity      ();
117   const int*      getReverseDescendingConnectivityIndex ();
118
119                                         /*! private method :\n
120                                             does nothing if already exists, else
121                                             evaluates _neighbourhood from _descending */
122   void calculateNeighbourhood(CONNECTIVITY &myConnectivity);
123
124   int getIndexOfEndClassicElementInReverseNodal(const int *reverseNodalValue, const int *reverseNodalIndex, int rk)  const;
125
126 public:
127
128   friend class IMED_MESH_RDONLY_DRIVER;
129   friend class MED_MESH_RDONLY_DRIVER21;
130   friend class IMED_MESH_WRONLY_DRIVER;
131   friend class MED_MESH_WRONLY_DRIVER21;
132   friend class MED_MESH_RDONLY_DRIVER22;
133   friend class MED_MESH_WRONLY_DRIVER22;
134
135
136   friend ostream & operator<<(ostream &os, CONNECTIVITY &connectivity);
137
138   // in order to fill CONNECTIVITY of MESH
139   friend class GRID;
140
141   CONNECTIVITY  (MED_EN::medEntityMesh Entity=MED_EN::MED_CELL);
142   CONNECTIVITY  (int numberOfTypes, MED_EN::medEntityMesh Entity=MED_EN::MED_CELL);
143   CONNECTIVITY  (const CONNECTIVITY & m);
144   virtual ~CONNECTIVITY ();
145
146   void setConstituent (CONNECTIVITY * Constituent)
147                                         throw (MEDEXCEPTION);
148
149   void setGeometricTypes (const MED_EN::medGeometryElement * Types,
150                            const MED_EN::medEntityMesh Entity)
151                                         throw (MEDEXCEPTION);
152
153   void setCount (const int * Count, const MED_EN::medEntityMesh Entity)
154                                         throw (MEDEXCEPTION);
155
156   void setNodal (const int * Connectivity,
157                  const MED_EN::medEntityMesh Entity,
158                  const MED_EN::medGeometryElement Type)
159                                         throw (MEDEXCEPTION);
160
161   inline void setNumberOfNodes(int NumberOfNodes);
162
163   inline int getEntityDimension() const;
164
165   inline void setEntityDimension(int EntityDimension);
166
167   void setPolygonsConnectivity(MED_EN::medConnectivity ConnectivityType,
168                                MED_EN::medEntityMesh Entity,
169                                const int* PolygonsConnectivity,
170                                const int* PolygonsConnectivityIndex,
171                                int ConnectivitySize, int NumberOfPolygons);
172
173   void setPolyhedronConnectivity(MED_EN::medConnectivity ConnectivityType,
174                                  const int* PolyhedronConnectivity,
175                                  const int* PolyhedronIndex, int ConnectivitySize,
176                                  int NumberOfPolyhedron,
177                                  const int* PolyhedronFacesIndex= (int*) NULL,
178                                  int NumberOfFaces=0);
179
180   inline bool   existConnectivity     (MED_EN::medConnectivity connectivityType, MED_EN::medEntityMesh Entity) const;
181   
182   virtual bool existPolygonsConnectivity(MED_EN::medConnectivity connectivityType,
183                                          MED_EN::medEntityMesh Entity) const;
184
185   virtual bool existPolyhedronConnectivity(MED_EN::medConnectivity connectivityType,
186                                            MED_EN::medEntityMesh Entity) const;
187
188   virtual void          calculateConnectivity (MED_EN::medConnectivity connectivityType, MED_EN::medEntityMesh Entity);
189
190   virtual void          updateFamily (const vector<FAMILY*>& myFamilies);
191
192   inline MED_EN::medEntityMesh              getEntity               ()                     const;
193   inline int                    getNumberOfTypes        (MED_EN::medEntityMesh Entity) const;
194   int                    getNumberOfTypesWithPoly(MED_EN::medEntityMesh Entity) const;
195   const int * getConnectivityOfAnElementWithPoly(MED_EN::medConnectivity ConnectivityType,
196                                                  MED_EN::medEntityMesh Entity,
197                                                  int Number, int &lgth);
198   int getNumberOfPolyType()  const;
199   int getNumberOfElementsWithPoly(MED_EN::medEntityMesh Entity, MED_EN::medGeometryElement Type) const;
200   int getNumberOfElementOfPolyType(MED_EN::medEntityMesh Entity)  const;
201   inline const MED_EN::medGeometryElement * getGeometricTypes       (MED_EN::medEntityMesh Entity) const
202                                                              throw (MEDEXCEPTION);
203   MED_EN::medGeometryElement * getGeometricTypesWithPoly       (MED_EN::medEntityMesh Entity) const
204                                                              throw (MEDEXCEPTION);
205   MED_EN::medGeometryElement                getElementType          (MED_EN::medEntityMesh Entity,
206                                                              int Number)           const;
207   MED_EN::medGeometryElement                getElementTypeWithPoly          (MED_EN::medEntityMesh Entity,
208                                                              int Number)           const;
209   inline MED_EN::medGeometryElement                getPolyTypeRelativeTo() const;
210   virtual inline const int *                getGlobalNumberingIndex (MED_EN::medEntityMesh Entity) const
211                                                              throw (MEDEXCEPTION);
212
213   virtual const int *     getConnectivity      (MED_EN::medConnectivity ConnectivityType,
214                                                 MED_EN::medEntityMesh Entity,
215                                                 MED_EN::medGeometryElement Type);
216   virtual int getConnectivityLength        (MED_EN::medConnectivity ConnectivityType,
217                                             MED_EN::medEntityMesh Entity,
218                                             MED_EN::medGeometryElement Type);
219
220   virtual const int *     getConnectivityIndex (MED_EN::medConnectivity ConnectivityType,
221                                                 MED_EN::medEntityMesh Entity);
222
223   virtual const int* getPolygonsConnectivity(MED_EN::medConnectivity ConnectivityType,
224                                              MED_EN::medEntityMesh Entity);
225   virtual const int* getPolygonsConnectivityIndex(MED_EN::medConnectivity ConnectivityType,
226                                                   MED_EN::medEntityMesh Entity);
227   virtual int getNumberOfPolygons() const;
228   virtual const int* getPolyhedronConnectivity(MED_EN::medConnectivity ConnectivityType) const;
229   virtual const int* getPolyhedronFacesIndex() const;
230   virtual const int* getPolyhedronIndex(MED_EN::medConnectivity ConnectivityType) const;
231   virtual int getNumberOfPolyhedronFaces() const;
232   virtual int getNumberOfPolyhedron() const;
233   int *getNodesOfPolyhedron(int polyhedronId, int& lgthOfTab) const;
234   int **getNodesPerFaceOfPolyhedron(int polyhedronId, int& nbOfFaces, int* & nbOfNodesPerFaces) const;
235   const CELLMODEL &   getType              (MED_EN::medGeometryElement Type) const;
236   const CELLMODEL *   getCellsTypes        (MED_EN::medEntityMesh Entity)    const
237                                             throw (MEDEXCEPTION);
238
239   int       getNumberOfNodesInType     (MED_EN::medGeometryElement Type) const;
240   int       getNumberOfSubCellInType   (MED_EN::medGeometryElement Type) const;
241   virtual int   getNumberOf                (MED_EN::medEntityMesh Entity,
242                                             MED_EN::medGeometryElement Type) const;
243   virtual const int*      getValue             (MED_EN::medConnectivity TypeConnectivity,
244                                             MED_EN::medGeometryElement Type);
245   virtual const int*      getValueIndex        (MED_EN::medConnectivity TypeConnectivity);
246
247   virtual inline const int* getReverseConnectivity (MED_EN::medConnectivity ConnectivityType,
248                                                 MED_EN::medEntityMesh Entity=MED_EN::MED_CELL)
249                                                 throw (MEDEXCEPTION);
250   virtual inline const int* getReverseConnectivityIndex (MED_EN::medConnectivity ConnectivityType,
251                                                      MED_EN::medEntityMesh Entity=MED_EN::MED_CELL)
252                                                      throw (MEDEXCEPTION);
253
254   const int*      getNeighbourhood() const;
255   void invertConnectivityForAFace(int faceId, const int *nodalConnForFace, bool polygonFace=false);
256   bool deepCompare(const CONNECTIVITY& other) const;
257 };
258 /*----------------------*/
259 /* Methodes Inline      */
260 /*----------------------*/
261
262 /*! Returns the  medEntityMesh */
263 //--------------------------------------------------//
264 inline MED_EN::medEntityMesh CONNECTIVITY::getEntity() const
265 //--------------------------------------------------//
266 {
267         return _entity;
268 }
269
270 /*!  Returns the number of different %medGeometryElement types
271      existing in the specified entity. \n
272      Note : Not implemented for MED_ALL_ENTITIES. */
273 //-----------------------------------------------------------------------//
274 inline int CONNECTIVITY::getNumberOfTypes(MED_EN::medEntityMesh Entity) const
275 //-----------------------------------------------------------------------//
276 {
277   MESSAGE("CONNECTIVITY::getNumberOfTypes : Entity = "<<Entity<<", _entity = "<<_entity);
278   if (_entity==Entity)
279     return _numberOfTypes;
280   else if (_constituent!=NULL)
281     return _constituent->getNumberOfTypes(Entity);
282   else if (_constituent == NULL)
283     {
284       MESSAGE("CONNECTIVITY::getNumberOfTypes : _constituent == NULL");
285       try
286         {
287           (const_cast <CONNECTIVITY *> (this))->calculateDescendingConnectivity();
288         }
289       catch (MEDEXCEPTION & ex)
290         {
291           return 0 ;
292         }
293
294       SCRUTE(_entityDimension);
295
296       if (_entityDimension != 2 && _entityDimension != 3) return 0;
297
298       try
299         {
300           _constituent->calculateConnectivity(MED_EN::MED_NODAL,Entity);
301         }
302       catch (MEDEXCEPTION & ex)
303         {
304           return 0 ;
305         }
306
307       return _constituent->getNumberOfTypes(Entity);
308     }
309   else
310         return 0; // because it is the right information (no exception needed)!
311 }
312
313 /*!  Returns an array of all %medGeometryElement types existing in the mesh
314      for the given %medEntityMesh.
315      Note : Not implemented for MED_ALL_ENTITIES.
316      Throws an exception if Entity is unknown */
317 //------------------------------------------------------------------------------------------//
318 inline const MED_EN::medGeometryElement* CONNECTIVITY::getGeometricTypes(MED_EN::medEntityMesh Entity) const
319                                                 throw (MEDEXCEPTION)
320 //------------------------------------------------------------------------------------------//
321 {
322   if (_entity==Entity)
323         return _geometricTypes;
324   else if (_constituent!=NULL)
325         return _constituent->getGeometricTypes(Entity);
326   else
327         throw MEDEXCEPTION("CONNECTIVITY::getGeometricTypes : Entity not defined !");
328 }
329
330 /*!   Returns an array containing the accumulated number of entities sorted by the geometric type.\n
331
332       Exemple :\n
333
334       In case of a CONNECTIVITY containing 3*MED_TRIA3 et 2*MED_QUAD4 : \n
335             int * count = getGlobalNumberingIndex(MED_CELL)\n
336       count[0] is always set to 1\n
337       count[1] is set to 1+3=4\n
338       count[2] is set to 4+2=6 = total number of cells + 1\n
339
340       Note : Not implemented for MED_ALL_ENTITIES. \n
341       Note : The geometric type order is given by the typedef enum medGeometryElement.
342
343 */
344 //----------------------------------------------------------------------------------//
345 inline const int * CONNECTIVITY::getGlobalNumberingIndex(MED_EN::medEntityMesh Entity) const
346                                                 throw (MEDEXCEPTION)
347 //----------------------------------------------------------------------------------//
348 {
349   if (_entity==Entity)
350         return _count;
351   else if (_constituent!=NULL)
352         return _constituent->getGlobalNumberingIndex(Entity);
353   else
354         throw MEDEXCEPTION("CONNECTIVITY::getGlobalNumberingIndex : Entity not defined !");
355 }
356
357 /*!  Returns true if a connectivity exists on elements of type "Entity" */
358 //-----------------------------------------------------------------------------//
359 inline bool CONNECTIVITY::existConnectivity( MED_EN::medConnectivity ConnectivityType,
360                                              MED_EN::medEntityMesh Entity) const
361 //-----------------------------------------------------------------------------//
362 {
363   if (_entity==Entity) {
364     if ((ConnectivityType==MED_EN::MED_NODAL)&(_nodal!=(MEDSKYLINEARRAY*)NULL))
365       return true;
366     if ((ConnectivityType==MED_EN::MED_DESCENDING)&(_descending!=(MEDSKYLINEARRAY*)NULL))
367       return true;
368   } else if (_constituent!=NULL)
369     return _constituent->existConnectivity(ConnectivityType,Entity);
370   return false;
371 }
372
373 /*! Returns true if a polygons connectivity exists on elements of type "Entity" */
374 //-----------------------------------------------------------------------------//
375 inline bool CONNECTIVITY::existPolygonsConnectivity(MED_EN::medConnectivity ConnectivityType,
376                                                     MED_EN::medEntityMesh Entity) const
377 //-----------------------------------------------------------------------------//
378 {
379   if (_entity == Entity)
380     {
381       MESSAGE("existPolygonsConnectivity : _entity == Entity = "<<Entity);
382       if (ConnectivityType == MED_EN::MED_NODAL && _polygonsNodal != (MEDSKYLINEARRAY*) NULL)
383         return true;
384       if (ConnectivityType == MED_EN::MED_DESCENDING && _polygonsDescending != (MEDSKYLINEARRAY*) NULL)
385         return true;
386     }
387   else if (_constituent != (CONNECTIVITY*) NULL)
388     return _constituent->existPolygonsConnectivity(ConnectivityType,Entity);
389   return false;
390 }
391
392 /*! Returns true if a polyhedron connectivity exists on elements of type "Entity" */
393 //-----------------------------------------------------------------------------//
394 inline bool CONNECTIVITY::existPolyhedronConnectivity(MED_EN::medConnectivity ConnectivityType,
395                                                       MED_EN::medEntityMesh Entity) const
396 //-----------------------------------------------------------------------------//
397 {
398   if (_entity == Entity)
399     {
400       MESSAGE("existPolyhedronConnectivity : _entity == Entity = "<<Entity);
401       if (ConnectivityType == MED_EN::MED_NODAL && _polyhedronNodal != (POLYHEDRONARRAY*) NULL)
402         return true;
403       if (ConnectivityType == MED_EN::MED_DESCENDING && _polyhedronDescending != (MEDSKYLINEARRAY*) NULL)
404         return true;
405     }
406   else if (_constituent != (CONNECTIVITY*) NULL)
407     return _constituent->existPolyhedronConnectivity(ConnectivityType,Entity);
408   return false;
409 }
410
411 /*!
412 Returns an array containing CELLMODEL foreach element type present
413 in connectivity for given medEntityMesh (similar as getGeometricTypes).\n
414 Throw an execption if the given entity is not defined or if the array is not defined.
415 */
416 //-----------------------------------------------------------------------------//
417 inline const CELLMODEL * CONNECTIVITY::getCellsTypes(MED_EN::medEntityMesh Entity) const
418                                                 throw (MEDEXCEPTION)
419 //-----------------------------------------------------------------------------//
420 {
421   if (Entity == _entity)
422     if (_type!=NULL)
423       return _type;
424     else
425       throw MEDEXCEPTION("CONNECTIVITY::getCellsTypes(medEntityMesh) :"
426                          " CELLMODEL array is not defined !");
427   else
428     if (_constituent != NULL)
429       return _constituent->getCellsTypes(Entity);
430     else
431       throw MEDEXCEPTION("CONNECTIVITY::getCellsTypes(medEntityMesh) : Not found Entity !");
432 }
433
434 /*! A DOCUMENTER */
435 //------------------------------------------------------------------------------------------//
436 inline const int* CONNECTIVITY::getReverseConnectivity( MED_EN::medConnectivity ConnectivityType,
437                                                             MED_EN::medEntityMesh Entity)
438                                                             throw (MEDEXCEPTION)
439 //------------------------------------------------------------------------------------------//
440 {
441   if(_entity==Entity)
442     if (ConnectivityType==MED_EN::MED_NODAL)
443       return getReverseNodalConnectivity();
444     else if (ConnectivityType==MED_EN::MED_DESCENDING)
445       return getReverseDescendingConnectivity();
446     else
447       throw MEDEXCEPTION("MESH::getReverseConnectivity : connectivity mode not supported !");
448
449   // other entity :
450   if (NULL==_constituent)
451     calculateDescendingConnectivity();
452   return _constituent->getReverseConnectivity(ConnectivityType,Entity);
453 }
454
455 /*! A DOCUMENTER */
456 //-----------------------------------------------------------------------------------------------//
457 inline const int* CONNECTIVITY::getReverseConnectivityIndex(MED_EN::medConnectivity ConnectivityType,
458                                                                 MED_EN::medEntityMesh Entity)
459                                                                 throw (MEDEXCEPTION)
460 //-----------------------------------------------------------------------------------------------//
461 {
462   if(_entity==Entity)
463     if (ConnectivityType==MED_EN::MED_NODAL)
464       return getReverseNodalConnectivityIndex();
465     else if (ConnectivityType==MED_EN::MED_DESCENDING)
466       return getReverseDescendingConnectivityIndex();
467     else
468       throw MEDEXCEPTION("MESH::getReverseConnectivityIndex : connectivity mode not supported !");
469
470   // other entity :
471   if (NULL==_constituent)
472     calculateDescendingConnectivity();
473   return _constituent->getReverseConnectivityIndex(ConnectivityType,Entity);
474 }
475
476
477 inline void CONNECTIVITY::setNumberOfNodes(int NumberOfNodes)
478 {
479     _numberOfNodes=NumberOfNodes;
480 }
481
482 inline void CONNECTIVITY::setEntityDimension(int EntityDimension)
483 {
484     _entityDimension=EntityDimension;
485 }
486
487 int CONNECTIVITY::getEntityDimension() const
488 {
489   return _entityDimension;
490 }
491
492 MED_EN::medGeometryElement CONNECTIVITY::getPolyTypeRelativeTo() const
493 {
494   if(_entity==MED_EN::MED_CELL && _entityDimension==3)
495     return MED_EN::MED_POLYHEDRA;
496   else if((_entity==MED_EN::MED_CELL && _entityDimension==2) || (_entity==MED_EN::MED_FACE && _entityDimension==2))
497     return MED_EN::MED_POLYGON;
498   else
499     throw MEDEXCEPTION("getPolyTypeRelativeTo : ");
500 }
501
502 }//End namespace MEDMEM
503
504 #endif /* CONNECTIVITY_HXX */