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