Salome HOME
update from the MedMemory V1.0.1
[modules/med.git] / src / MEDMEM / MEDMEM_Connectivity.hxx
1 #ifndef CONNECTIVITY_HXX
2 #define CONNECTIVITY_HXX
3
4 #include <vector>
5
6 #include "utilities.h"
7 #include "MEDMEM_Exception.hxx"
8 #include "MEDMEM_define.hxx"
9
10 using namespace MED_EN;
11
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   medEntityMesh           _entity;      
33                                          /*! contains MED_NODAL or MED_DESCEND */
34   medConnectivity         _typeConnectivity;
35                                          /*! count of differents cells types 
36                                             used by the mesh */  
37   med_int                 _numberOfTypes; 
38                                         /*! array of all med_geometric_type used by MESH. */
39   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   med_int                 _entityDimension;
47
48                                         /*! needed by calculateReverseNodalConnectivity */
49   med_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   med_int *               _count;
61
62                                         /*! pointer to an array which stores the nodal connectivity */
63   MEDSKYLINEARRAY* _nodal;
64                                         /*! pointer to an array which stores 
65                                             the descending connectivity */
66   MEDSKYLINEARRAY* _descending;
67                                         /*! pointer to an array which stores 
68                                             the reverse nodal connectivity */
69   MEDSKYLINEARRAY* _reverseNodalConnectivity;
70                                         /*! pointer to an array which stores 
71                                             the reverse descending connectivity */
72   MEDSKYLINEARRAY* _reverseDescendingConnectivity;
73                                         /*! if face or edge, list of 2 cells or 
74                                             2 faces it belongs to.
75                                             If 2nd number equals 0, we have a 
76                                             boundary entity. We could use 
77                                             MEDSKYLINEARRAY, but we suppose we have
78                                             always only 2 (or 1) entities. */
79   MEDSKYLINEARRAY* _neighbourhood;
80                                         /*! connectivity of sub cell if 
81                                             descendant connectivity is calculated */
82   CONNECTIVITY * _constituent;  
83
84   /* -------------------- */
85   /*    Class Methods     */
86   /* -------------------- */
87
88 private:
89                                         /*! private method :/n
90                                             does nothing if already exists, else 
91                                             evaluates _nodal from _descending */
92   void  calculateNodalConnectivity();   
93                                         /*! private method :/n
94                                             does nothing if already exists, else
95                                             evaluates from _nodal */  
96   void calculateReverseNodalConnectivity(); 
97                                         /*! private method :/n
98                                             does nothing if already exists, else
99                                             evaluates _descending from _nodal */ 
100   void calculateDescendingConnectivity(); 
101                                         /*! private method :/n
102                                             does nothing if already exists, else
103                                             evaluates from _descending */
104   //  void calculateReverseDescendingConnectivity(CONNECTIVITY *myConnectivity);
105
106   const med_int*      getReverseNodalConnectivity           ();
107   const med_int*      getReverseNodalConnectivityIndex      ();
108   const med_int*      getReverseDescendingConnectivity      ();
109   const med_int*      getReverseDescendingConnectivityIndex ();
110
111                                         /*! private method :/n
112                                             does nothing if already exists, else
113                                             evaluates _neighbourhood from _descending */
114   void calculateNeighbourhood(CONNECTIVITY &myConnectivity);
115
116 public:
117
118   friend class MED_MESH_RDONLY_DRIVER;
119   friend class MED_MESH_WRONLY_DRIVER;
120   friend ostream & operator<<(ostream &os, CONNECTIVITY &connectivity);
121
122   // in order to fill CONNECTIVITY of MESH
123   friend class GRID;
124
125   CONNECTIVITY  (medEntityMesh Entity=MED_CELL);
126   CONNECTIVITY  (int numberOfTypes, medEntityMesh Entity=MED_CELL);
127   CONNECTIVITY  (const CONNECTIVITY & m);
128   virtual ~CONNECTIVITY ();
129
130   void setConstituent (CONNECTIVITY * Constituent)
131                                         throw (MEDEXCEPTION);
132
133   void setGeometricTypes (const medGeometryElement * Types,
134                            const medEntityMesh Entity)
135                                         throw (MEDEXCEPTION);
136
137   void setCount (const int * Count, const medEntityMesh Entity)
138                                         throw (MEDEXCEPTION);
139
140   void setNodal (const int * Connectivity,
141                  const medEntityMesh Entity,
142                  const medGeometryElement Type)
143                                         throw (MEDEXCEPTION);
144
145   inline void setNumberOfNodes(med_int NumberOfNodes);
146   
147   inline void setEntityDimension(med_int EntityDimension);
148
149   inline bool   existConnectivity     (medConnectivity connectivityType, medEntityMesh Entity) const;
150
151   virtual void          calculateConnectivity (medConnectivity connectivityType, medEntityMesh Entity);
152
153   virtual void          updateFamily (vector<FAMILY*> myFamilies);
154   virtual void          updateGroup (vector<GROUP*> myFamilies);
155
156   inline medEntityMesh              getEntity               ()                     const;
157   inline med_int                    getNumberOfTypes        (medEntityMesh Entity) const;
158   inline const medGeometryElement * getGeometricTypes       (medEntityMesh Entity) const
159                                                              throw (MEDEXCEPTION);
160   medGeometryElement                getElementType          (medEntityMesh Entity,
161                                                              int Number)           const;
162   virtual inline const int *                getGlobalNumberingIndex (medEntityMesh Entity) const
163                                                              throw (MEDEXCEPTION);
164
165   virtual const med_int *     getConnectivity      (medConnectivity ConnectivityType, 
166                                             medEntityMesh Entity,
167                                             medGeometryElement Type);
168   virtual const med_int *     getConnectivityIndex (medConnectivity ConnectivityType,
169                                             medEntityMesh Entity);
170  
171   const CELLMODEL &   getType              (medGeometryElement Type) const; 
172   const CELLMODEL *   getCellsTypes        (medEntityMesh Entity)    const 
173                                             throw (MEDEXCEPTION);
174  
175   med_int       getNumberOfNodesInType     (medGeometryElement Type) const; 
176   med_int       getNumberOfSubCellInType   (medGeometryElement Type) const; 
177   virtual med_int       getNumberOf                (medEntityMesh Entity, 
178                                             medGeometryElement Type) const;
179   virtual const med_int*      getValue             (medConnectivity TypeConnectivity, 
180                                             medGeometryElement Type); 
181   virtual const med_int*      getValueIndex        (medConnectivity TypeConnectivity);
182
183   virtual inline const med_int* getReverseConnectivity (medConnectivity ConnectivityType, 
184                                                 medEntityMesh Entity=MED_CELL)
185                                                 throw (MEDEXCEPTION);
186   virtual inline const med_int* getReverseConnectivityIndex (medConnectivity ConnectivityType, 
187                                                      medEntityMesh Entity=MED_CELL)
188                                                      throw (MEDEXCEPTION);
189
190   const med_int*      getNeighbourhood() const;
191
192 };
193 /*----------------------*/
194 /* Methodes Inline      */
195 /*----------------------*/
196
197 /*! Returns the  medEntityMesh */
198 //--------------------------------------------------//
199 inline medEntityMesh CONNECTIVITY::getEntity() const 
200 //--------------------------------------------------//
201
202         return _entity; 
203 }
204
205 /*!  Returns the number of different <medGeometryElement> types 
206      existing in the specified entity. /n
207      Note : Not implemented for MED_ALL_ENTITIES. */
208 //-----------------------------------------------------------------------//
209 inline med_int CONNECTIVITY::getNumberOfTypes(medEntityMesh Entity) const
210 //-----------------------------------------------------------------------//
211 {
212   MESSAGE("CONNECTIVITY::getNumberOfTypes : Entity = "<<Entity<<", _entity = "<<_entity);
213   if (_entity==Entity)
214         return _numberOfTypes; 
215   else if (_constituent!=NULL)
216         return _constituent->getNumberOfTypes(Entity);
217   else if (_constituent == NULL)
218     {
219       MESSAGE("CONNECTIVITY::getNumberOfTypes : _constituent == NULL");
220       try
221         {
222           (const_cast <CONNECTIVITY *> (this))->calculateDescendingConnectivity();
223         }
224       catch (MEDEXCEPTION & ex)
225         {
226           return 0 ;
227         }
228
229       SCRUTE(_entityDimension);
230
231       if (_entityDimension != 2 && _entityDimension != 3) return 0;
232
233       try
234         {
235           _constituent->calculateConnectivity(MED_NODAL,Entity);
236         }
237       catch (MEDEXCEPTION & ex)
238         {
239           return 0 ;
240         }
241
242       return _constituent->getNumberOfTypes(Entity);
243     }
244   else
245         return 0; // because it is the right information (no exception needed)!
246 }
247
248 /*!  Returns an array of all <med geometry elements> types existing in the mesh 
249      for the given medEntityMesh./n
250      Note : Not implemented for MED_ALL_ENTITIES. /n
251      Throws an exception if Entity is unknown */
252 //------------------------------------------------------------------------------------------//
253 inline const medGeometryElement* CONNECTIVITY::getGeometricTypes(medEntityMesh Entity) const 
254                                                 throw (MEDEXCEPTION)
255 //------------------------------------------------------------------------------------------//
256 {
257   if (_entity==Entity)
258         return _geometricTypes;
259   else if (_constituent!=NULL)
260         return _constituent->getGeometricTypes(Entity);
261   else
262         throw MEDEXCEPTION("CONNECTIVITY::getGeometricTypes : Entity not defined !");
263 }
264
265 /*!   Returns an array containing the accumulated number of entities sorted by the geometric type./n
266
267       Exemple :/n
268
269       In case of a CONNECTIVITY containing 3*MED_TRIA3 et 2*MED_QUAD4 : /n
270             int * count = getGlobalNumberingIndex(MED_CELL)/n
271       count[0] is always set to 1/n
272       count[1] is set to 1+3=4/n
273       count[2] is set to 4+2=6 = total number of cells + 1/n
274
275       Note : Not implemented for MED_ALL_ENTITIES. /n
276       Note : The geometric type order is given by the typedef enum medGeometryElement.
277                       
278 */
279 //----------------------------------------------------------------------------------//
280 inline const int * CONNECTIVITY::getGlobalNumberingIndex(medEntityMesh Entity) const 
281                                                 throw (MEDEXCEPTION)
282 //----------------------------------------------------------------------------------//
283 {
284   if (_entity==Entity)
285         return _count;
286   else if (_constituent!=NULL)
287         return _constituent->getGlobalNumberingIndex(Entity);
288   else
289         throw MEDEXCEPTION("CONNECTIVITY::getGlobalNumberingIndex : Entity not defined !");
290 }
291
292 /*!  Returns true if a connectivity exists on elements of type "Entity" */
293 //-----------------------------------------------------------------------------//
294 inline bool CONNECTIVITY::existConnectivity( medConnectivity ConnectivityType, 
295                                              medEntityMesh Entity) const
296 //-----------------------------------------------------------------------------//
297 {
298   if (_entity==Entity) { 
299     MESSAGE("existConnectivity : _entity==Entity="<<Entity);
300     if ((ConnectivityType==MED_NODAL)&(_nodal!=(MEDSKYLINEARRAY*)NULL))
301       return true;
302     if ((ConnectivityType==MED_DESCENDING)&(_descending!=(MEDSKYLINEARRAY*)NULL))
303       return true;
304   } else if (_constituent!=NULL)
305     return _constituent->existConnectivity(ConnectivityType,Entity);
306   return false;
307 }
308
309 /*! 
310 Returns an array containing CELLMODEL foreach element type present 
311 in connectivity for given medEntityMesh (similar as getGeometricTypes)./n
312 Throw an execption if the given entity is not defined or if the array is not defined.
313 */
314 //-----------------------------------------------------------------------------//
315 inline const CELLMODEL * CONNECTIVITY::getCellsTypes(medEntityMesh Entity) const
316                                                 throw (MEDEXCEPTION)
317 //-----------------------------------------------------------------------------//
318 {
319   if (Entity == _entity)
320     if (_type!=NULL)
321       return _type;
322     else
323       throw MEDEXCEPTION("CONNECTIVITY::getCellsTypes(medEntityMesh) :"
324                          " CELLMODEL array is not defined !");
325   else
326     if (_constituent != NULL)
327       return _constituent->getCellsTypes(Entity);
328     else
329       throw MEDEXCEPTION("CONNECTIVITY::getCellsTypes(medEntityMesh) : Not found Entity !");
330 }
331
332 /*! A DOCUMENTER */
333 //------------------------------------------------------------------------------------------//
334 inline const med_int* CONNECTIVITY::getReverseConnectivity( medConnectivity ConnectivityType, 
335                                                             medEntityMesh Entity) 
336                                                             throw (MEDEXCEPTION)
337 //------------------------------------------------------------------------------------------//
338 {
339   if(_entity==Entity)
340     if (ConnectivityType==MED_NODAL)
341       return getReverseNodalConnectivity();
342     else if (ConnectivityType==MED_DESCENDING)
343       return getReverseDescendingConnectivity();
344     else
345       throw MEDEXCEPTION("MESH::getReverseConnectivity : connectivity mode not supported !");
346
347   // other entity :
348   if (NULL==_constituent)
349     calculateDescendingConnectivity();
350   return _constituent->getReverseConnectivity(ConnectivityType,Entity);
351 }
352
353 /*! A DOCUMENTER */
354 //-----------------------------------------------------------------------------------------------//
355 inline const med_int* CONNECTIVITY::getReverseConnectivityIndex(medConnectivity ConnectivityType, 
356                                                                 medEntityMesh Entity) 
357                                                                 throw (MEDEXCEPTION)
358 //-----------------------------------------------------------------------------------------------//
359 {
360   if(_entity==Entity)
361     if (ConnectivityType==MED_NODAL)
362       return getReverseNodalConnectivityIndex();
363     else if (ConnectivityType==MED_DESCENDING)
364       return getReverseDescendingConnectivityIndex();
365     else
366       throw MEDEXCEPTION("MESH::getReverseConnectivityIndex : connectivity mode not supported !");
367   
368   // other entity :
369   if (NULL==_constituent)
370     calculateDescendingConnectivity();
371   return _constituent->getReverseConnectivityIndex(ConnectivityType,Entity);
372 }
373
374
375 inline void CONNECTIVITY::setNumberOfNodes(med_int NumberOfNodes)
376 {
377     _numberOfNodes=NumberOfNodes;
378 }
379   
380 inline void CONNECTIVITY::setEntityDimension(med_int EntityDimension)
381 {
382     _entityDimension=EntityDimension;
383 }
384
385 #endif /* CONNECTIVITY_HXX */
386