]> SALOME platform Git repositories - modules/med.git/blob - src/MEDMEM/MEDMEM_Grid.hxx
Salome HOME
update from the MedMemory V1.0.1
[modules/med.git] / src / MEDMEM / MEDMEM_Grid.hxx
1 // File      : MEDMEM_Grid.hxx
2 // Created   : Wed Dec 18 08:35:26 2002
3 // Descr     : class containing structured mesh data
4
5 // Author    : Edward AGAPOV (eap)
6 // Project   : SALOME Pro
7 // Module    : MED 
8 // Copyright : Open CASCADE
9 // $Header$
10
11 #ifndef MEDMEM_Grid_HeaderFile
12 #define MEDMEM_Grid_HeaderFile
13
14 #include "MEDMEM_Mesh.hxx"
15
16 // class containing structured mesh data
17
18 class GRID: public MESH
19 {
20  protected:
21   //-----------------------//
22   //   Fields
23   //-----------------------//
24   
25   // 1. grid type: MED_CARTESIAN, MED_POLAR, MED_BODY_FITTED
26   med_grid_type     _gridType;
27   
28   // 2. node coordinates
29   // For MED_BODY_FITTED MESH::_coordinate is used
30   
31   // 2.1. i component array: X for MED_CARTESIAN, R for MED_POLAR
32   int               _iArrayLength;
33   double*           _iArray;
34   // 2.2. j component array: Y for MED_CARTESIAN, Theta for MED_POLAR
35   int               _jArrayLength;
36   double*           _jArray;
37   // 2.3. k component array: Z for both MED_CARTESIAN and MED_POLAR
38   int               _kArrayLength;
39   double*           _kArray;
40
41   // 3. flags to know that _coordinates and _connectivity of MESH are filled
42   bool              _is_coordinates_filled;
43   bool              _is_connectivity_filled;
44
45   //-----------------------//
46   //   Protected Methods
47   //-----------------------//
48
49   CONNECTIVITY * makeConnectivity (const medEntityMesh Entity,
50                                    const medGeometryElement Geometry,
51                                    const int NbEntities, const int NbNodes,
52                                    int * NodeNumbers) const ;
53   // creates nodal connectivity
54
55   
56   // Suppose a READ Driver to do the following except filling _[ijk]Array's
57   // 1) fill MESH fields:
58   //    * _name
59   //    * _spaceDimension
60   //    * _meshDimension
61   //    * _numberOfNodesFamilies, _numberOfCellsFamilies, ect
62   //    * _familyNode, _familyCell, etc
63   //    * _numberOfNodesGroups, _numberOfCellsGroups, etc
64   //    * _groupNode, _groupCell, etc
65   //    * _
66   // 2) create MESH::_coordinate without setting _coordinate->_coordinate and set: 
67   //    * _coordinate->_coordinateSystem
68   //    * _coordinate->_coordinateName
69   //    * _coordinate->_coordinateUnit
70   
71
72  public:
73   //-----------------------//
74   //   Methods
75   //-----------------------//
76
77   GRID();
78   GRID(const med_grid_type type);
79   GRID(const GRID &m);
80   GRID( driverTypes driverType, const string & fileName="",const string & meshName="");
81   GRID & operator=(const GRID &m);
82   virtual ~GRID();
83   virtual void init();
84
85   void fillCoordinates() const ;
86   void fillConnectivity() const ;
87   // fill _coordinates and _connectivity of MESH if not yet done
88
89   inline void makeUnstructured();
90   // fill both coordinates and connectivity of MESH
91
92   void fillMeshAfterRead();
93   // fill some fields (_numberOfNodes, etc.) after reading
94
95   void writeUnstructured(int index=0, const string & driverName = "");
96   // write a Grid as an Unstructured mesh
97
98   void read(int index=0);
99
100   //   API Methods returning fields of MESH that are filled while reading.
101   //   So they need not to be redefined
102
103 //   string                getName() const;
104 //   int                   getSpaceDimension();
105 //   int                   getMeshDimension();
106 //   string                getCoordinatesSystem();
107 //   int                   getNumberOfNodes();
108 //   string *              getCoordinatesNames();
109 //   string *              getCoordinatesUnits();
110 //   int                   getNumberOfFamilies(medEntityMesh Entity);
111 //   vector<FAMILY*>       getFamilies(medEntityMesh Entity);
112 //   FAMILY*               getFamily(medEntityMesh Entity,int i);
113 //   int                   getNumberOfGroups(medEntityMesh Entity);
114 //   vector<GROUP*>        getGroups(medEntityMesh Entity);
115 //   GROUP*                getGroup(medEntityMesh Entity,int i);
116
117
118 // Since a MESH itself knows if it is a GRID, it calls fillConnectivity()
119 // or fillCoordinates() whenever needed. So no redifinition of the following methods
120
121 //   const double *        getCoordinates(medModeSwitch Mode);
122 //   COORDINATE *          getCoordinateptr();
123 //   const double          getCoordinate(int Number,int Axis);
124 //   int                   getNumberOfTypes(medEntityMesh Entity);
125 //   medGeometryElement *  getTypes(medEntityMesh Entity);
126 //   CELLMODEL *           getCellsTypes(medEntityMesh Entity);
127 //   medGeometryElement    getElementType(medEntityMesh Entity,int Number) ;
128 //   int                   getNumberOfElements(medEntityMesh Entity,medGeometryElement Type);
129 //   int                   getElementNumber(medConnectivity ConnectivityType, medEntityMesh Entity, medGeometryElement Type, int * connectivity) ;
130 //   int *                 getGlobalNumberingIndex(medEntityMesh Entity);
131 //   int *                 getConnectivity(medModeSwitch Mode,medConnectivity ConnectivityType,medEntityMesh Entity, medGeometryElement Type);
132 //   int *                 getConnectivityIndex(medConnectivity ConnectivityType,medEntityMesh Entity);
133 //   int *                 getReverseConnectivity(medConnectivity ConnectivityType);
134 //   int *                 getReverseConnectivityIndex(medConnectivity ConnectivityType);
135 //   bool                  existConnectivity(medConnectivity ConnectivityType,medEntityMesh Entity);
136 //   void                  calculateConnectivity(medModeSwitch Mode,medConnectivity ConnectivityType,medEntityMesh Entity);
137 //   FIELD<double>*        getVolume(const SUPPORT * Support) throw (MEDEXCEPTION) ;
138 //   FIELD<double>*        getArea(const SUPPORT * Support) throw (MEDEXCEPTION) ;
139 //   FIELD<double>*        getLength(const SUPPORT * Support) throw (MEDEXCEPTION) ;
140 //   FIELD<double>*        getNormal(const SUPPORT * Support) throw (MEDEXCEPTION) ;
141 //   FIELD<double>*        getBarycenter(const SUPPORT * Support) throw (MEDEXCEPTION) ;
142
143
144   // Specific GRID methods
145
146   inline int getNodeNumber(const int i, const int j=0, const int k=0) const;
147   // return a NODE number by its position in the grid.
148   // WARNING: be carefull, there is no check that i,j,k are within a good range
149   // A good range is: 0 <= X < getArrayLength( X_Axis )
150   inline int getCellNumber(const int i, const int j=0, const int k=0) const ;
151   // return a CELL number by its position in the grid.
152   // WARNING: be carefull, there is no check that i,j,k are within a good range
153   // A good range is: 0 <= X < (getArrayLength( X_Axis )-1)
154
155   int getEdgeNumber(const int Axis, const int i, const int j=0, const int k=0) const throw (MEDEXCEPTION) ;
156   // return an EDGE number by its position in the grid.
157   // Axis [1,2,3] means one of directions: along i, j or k.
158   // It selects an edge of ones having same (i,j,k):
159   //  * an EDGE going along given Axis.
160   // Exception for Axis out of range or when there is no edges in the grid (1D)
161   // WARNING: be carefull, there is no check that i,j,k are within a good range
162   // A good range is:
163   // 0 <= X < (getArrayLength( X_Axis )-1)
164   // 0 <= X < getArrayLength( NOT_X_Axis )
165
166   int getFaceNumber(const int Axis, const int i, const int j=0, const int k=0) const throw (MEDEXCEPTION) ;
167   // return a FACE number by its position in the grid.
168   // Axis [1,2,3] means one of directions: along i, j or k.
169   // It selects a face of ones having same (i,j,k):
170   //  * a FACE which is normal to given Axis
171   // Exception for Axis out of range or when there is no faces in the grid (1,2D)
172   // WARNING: be carefull, there is no check that i,j,k are within a good range
173   // A good range is:
174   // 0 <= X < (getArrayLength( NOT_X_Axis )-1)
175   // 0 <= X < getArrayLength( X_Axis )
176   
177
178   void getNodePosition(const int Number, int& i, int& j, int& k) const throw (MEDEXCEPTION) ;
179   void getCellPosition(const int Number, int& i, int& j, int& k) const throw (MEDEXCEPTION) ;
180   void getEdgePosition(const int Number, int& Axis, int& i, int& j, int& k) const throw (MEDEXCEPTION) ;
181   void getFacePosition(const int Number, int& Axis, int& i, int& j, int& k) const throw (MEDEXCEPTION) ;
182   // return position (i,j,k) of an entity #Number
183   // Axis: [1,2,3], see get*Number for details
184   // Exception for Number out of range
185
186
187   //  Access to fields
188
189   inline med_grid_type getGridType() const;
190   // return MED_CARTESIAN, MED_POLAR or MED_BODY_FITTED
191
192   int getArrayLength( const int Axis ) const throw (MEDEXCEPTION);
193   // return array length. Axis = [1,2,3] meaning [i,j,k],
194   // exception if Axis out of [1-3] range
195
196   const double getArrayValue (const int Axis, const int i) const throw (MEDEXCEPTION) ;
197   // return i-th array component. Axis = [1,2,3] meaning [i,j,k],
198   // exception if Axis out of [1 - 3] range
199   // exception if i is out of range [0 - (getArrayLength(Axis)-1)];
200
201   inline const COORDINATE * getCoordinateptr() const;
202
203   inline const double * getCoordinates(medModeSwitch Mode) const;
204
205   inline const double getCoordinate(int Number,int Axis) const;
206
207   inline int getNumberOfTypes(medEntityMesh Entity) const;
208
209   inline const medGeometryElement * getTypes(medEntityMesh Entity) const;
210
211   inline const CELLMODEL * getCellsTypes(medEntityMesh Entity) const;
212
213   const int * getGlobalNumberingIndex(medEntityMesh Entity) const;
214
215   inline int getNumberOfElements(medEntityMesh Entity,
216                                  medGeometryElement Type) const;
217
218   inline bool existConnectivity(medConnectivity ConnectivityType,
219                                 medEntityMesh Entity) const;
220
221   inline medGeometryElement getElementType(medEntityMesh Entity,
222                                            int Number) const;
223
224   inline void calculateConnectivity(medModeSwitch Mode,
225                                     medConnectivity ConnectivityType,
226                                     medEntityMesh Entity) const ;
227
228   inline const CONNECTIVITY* getConnectivityptr() const;
229
230   inline const int * getConnectivity(medModeSwitch Mode,
231                                      medConnectivity ConnectivityType,
232                                      medEntityMesh Entity, 
233                                      medGeometryElement Type) const;
234
235   inline const int * getConnectivityIndex(medConnectivity ConnectivityType,
236                                           medEntityMesh Entity) const;
237
238   inline const int * getReverseConnectivity(medConnectivity ConnectivityType,
239                                             medEntityMesh Entity=MED_CELL) const;
240
241   inline const int * getReverseConnectivityIndex(medConnectivity ConnectivityType,
242                                                  medEntityMesh Entity=MED_CELL) const;
243
244   //  Setting fields
245
246   inline void setGridType(med_grid_type gridType);
247
248   friend class MED_MESH_RDONLY_DRIVER;
249   friend class MED_MESH_WRONLY_DRIVER;
250
251 };
252
253
254   //----------------------------------//
255   //   Inline Methods Implementation
256   //----------------------------------//
257
258 inline med_grid_type GRID::getGridType() const
259 {
260   return _gridType;
261 }
262 //=======================================================================
263 //function : getNodeNumber
264 //purpose  : 
265 //=======================================================================
266
267 inline int GRID::getNodeNumber(const int i, const int j, const int k) const
268 {
269   return 1 + i + _iArrayLength * j + _iArrayLength * _jArrayLength * k;
270 }
271
272 //=======================================================================
273 //function : getCellNumber
274 //purpose  : 
275 //=======================================================================
276
277 inline int GRID::getCellNumber(const int i, const int j, const int k) const
278 {
279   return 1 + i + (_iArrayLength-1) * j + (_iArrayLength-1) * (_jArrayLength-1) * k;
280 }
281
282 //=======================================================================
283 //function : makeUnstructured
284 //purpose : fill coordinates and connectivity of MESH
285 //=======================================================================
286
287 inline void GRID::makeUnstructured()
288 {
289   fillCoordinates();
290   fillConnectivity();
291 }
292
293 //=======================================================================
294 //function : setGridType
295 //purpose : set the _gridType field od the class GRID
296 //=======================================================================
297
298 inline void GRID::setGridType(med_grid_type gridType)
299 {
300   _gridType = gridType;
301 }
302
303 /*! Get the COORDINATES object. Use it only if you need COORDINATES informations not provided by the GRID class via the MESH class.*/
304 inline const COORDINATE * GRID::getCoordinateptr() const
305 {
306   fillCoordinates();
307   return _coordinate;
308 }
309
310 /*! Get the whole coordinates array in a given interlacing mode. The interlacing mode are :
311   - MED_NO_INTERLACE   :  X1 X2 Y1 Y2 Z1 Z2
312   - MED_FULL_INTERLACE :  X1 Y1 Z1 X2 Y2 Z2
313  */
314 inline const double * GRID::getCoordinates(medModeSwitch Mode) const
315 {
316   fillCoordinates();
317   return _coordinate->getCoordinates(Mode);
318 }
319
320 /*! Get the coordinate n° number on axis n°axis*/
321 inline const double GRID::getCoordinate(int number, int axis) const
322 {
323   fillCoordinates();
324   return _coordinate->getCoordinate(number,axis);
325 }
326
327 /*! Get the number of different geometric types for a given entity type.
328
329     medEntityMesh entity : MED_CELL, MED_FACE, MED_EDGE, MED_NODE,
330     MED_ALL_ENTITIES
331
332     If entity is not defined, return 0.
333
334     If there is no connectivity, return an exception.
335 */
336 inline int GRID::getNumberOfTypes(medEntityMesh entity) const
337 {
338   MESSAGE("GRID::getNumberOfTypes(medEntityMesh entity) : "<<entity);
339   if (entity == MED_NODE)
340     return 1;
341
342   fillConnectivity();
343
344   if (_connectivity != NULL)
345     return _connectivity->getNumberOfTypes(entity);
346   throw MEDEXCEPTION(LOCALIZED("GRID::getNumberOfTypes( medEntityMesh ) : Connectivity not defined !"));
347 }
348
349 /*!
350   Get the list of geometric types used by a given entity.
351   medEntityMesh entity : MED_CELL, MED_FACE, MED_EDGE, MED_ALL_ENTITIES
352
353   REM : Don't use MED_NODE
354
355   If entity is not defined, return an exception.
356 */
357 inline const medGeometryElement * GRID::getTypes(medEntityMesh entity) const
358 {
359   if (entity == MED_NODE)
360     throw MEDEXCEPTION(LOCALIZED("GRID::getTypes( medEntityMesh ) : No medGeometryElement with MED_NODE entity !"));
361   // return un tableau de taille 1 contenant MED_NONE, comme les supports pour etre coherent avec getNumberOfTypes ???? PG
362
363   fillConnectivity();
364
365   if (_connectivity != NULL)
366     return _connectivity->getGeometricTypes(entity);
367   throw MEDEXCEPTION(LOCALIZED("GRID::getTypes( medEntityMesh ) : Connectivity not defined !"));
368 }
369
370 /*!
371   Get the whole list of CELLMODEL used by cells of given type (medEntityMesh).
372
373   REMARK : Don't use MED_NODE as medEntityMesh
374 */
375 inline const CELLMODEL * GRID::getCellsTypes(medEntityMesh Entity) const
376 {
377   fillConnectivity();
378
379   if (_connectivity != NULL)
380     return _connectivity->getCellsTypes(Entity);
381   throw MEDEXCEPTION(LOCALIZED("GRID::getCellsTypes( medEntityMesh ) : Connectivity not defined !"));
382 }
383
384 /*! Return an array of size NumbreOfTypes+1 which contains, for each
385     geometric type of the given entity, the first global element number
386     of this type.
387
388     For exemple, if we have a mesh with 5 triangles and 4 quadrangle :
389     - size of GlobalNumberingIndex is 3
390     - GlobalNumberingIndex[0]=1 (the first type)
391     - GlobalNumberingIndex[1]=6 (the second type)
392     - GlobalNumberingIndex[2]=10
393 */
394 inline const int * GRID::getGlobalNumberingIndex(medEntityMesh entity) const
395 {
396   fillConnectivity();
397
398   if (_connectivity != NULL)
399     return _connectivity->getGlobalNumberingIndex(entity);
400   throw MEDEXCEPTION(LOCALIZED("GRID::getNumberOfTypes( medEntityMesh ) : Connectivity not defined !"));
401 }
402
403 /*!
404   Return the number of element of given geometric type of given entity. Return 0 if query is not defined.
405
406   Example :
407   - getNumberOfElements(MED_NODE,MED_NONE) : number of node
408   - getNumberOfElements(MED_NODE,MED_TRIA3) : return 0 (not defined)
409   - getNumberOfElements(MED_FACE,MED_TRIA3) : return number of triangles
410   elements defined in face entity (0 if not defined)
411   - getNumberOfElements(MED_CELL,MED_ALL_ELEMENTS) : return total number
412   of elements defined in cell entity
413 */
414 inline int GRID::getNumberOfElements(medEntityMesh entity, medGeometryElement Type) const
415 {
416   //  const char * LOC = "MESH::getNumberOfElements(medEntityMesh,medGeometryElement) : ";
417   if (entity==MED_NODE)
418     if ((Type==MED_NONE)|(Type==MED_ALL_ELEMENTS))
419       return _numberOfNodes;
420     else
421       return 0;
422   //throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"wrong medGeometryElement with MED_NODE"));
423   else
424     {
425       fillConnectivity();
426
427       if (_connectivity != (CONNECTIVITY*)NULL)
428         return _connectivity->getNumberOf(entity,Type);
429       else
430         return 0;
431       //throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"connectivity not defined !"));
432     }
433 }
434
435 /*!
436   Return true if the wanted connectivity exist, else return false
437   (to use before a getSomething method).
438  */
439 inline bool GRID::existConnectivity(medConnectivity connectivityType, medEntityMesh entity) const
440 {
441   fillConnectivity();
442
443   if (_connectivity==(CONNECTIVITY*)NULL)
444     throw MEDEXCEPTION("GRID::existConnectivity(medConnectivity,medEntityMesh) : no connectivity defined !");
445   return _connectivity->existConnectivity(connectivityType,entity);
446 }
447
448 /*!
449   Return the geometric type of global element Number of entity Entity.
450
451   Throw an exception if Entity is not defined or Number are wrong (too big).
452  */
453 inline medGeometryElement GRID::getElementType(medEntityMesh Entity,int Number) const
454 {
455   fillConnectivity();
456
457   if (_connectivity==(CONNECTIVITY*)NULL)
458     throw MEDEXCEPTION("GRID::getElementType(medEntityMesh,int) : no connectivity defined !");
459   return _connectivity->getElementType(Entity,Number);
460 }
461
462 /*!
463   Calculate the ask connectivity. Return an exception if this could not be
464   done. Do nothing if connectivity already exist.
465  */
466
467 inline void GRID::calculateConnectivity(medModeSwitch Mode,medConnectivity ConnectivityType,medEntityMesh entity) const
468 {
469   fillConnectivity();
470
471   if (Mode==MED_FULL_INTERLACE)
472     _connectivity->calculateConnectivity(ConnectivityType,entity);
473   else
474     throw MEDEXCEPTION(LOCALIZED("GRID::calculateConnectivity : only for MED_FULL_INTERLACE mode"));
475 }
476
477 inline const CONNECTIVITY* GRID::getConnectivityptr() const
478 {
479   fillConnectivity();
480
481   return _connectivity;
482 }
483
484 /*!
485   Return the required connectivity in the right mode for the given
486   geometric type of the given entity.
487
488   To get connectivity for all geometric type, use Mode=MED_FULL_INTERLACE
489   and Type=MED_ALL_ELEMENTS.
490   You must also get the corresponding index array.
491  */
492 inline const int * GRID::getConnectivity(medModeSwitch Mode,medConnectivity ConnectivityType,medEntityMesh entity, medGeometryElement Type) const
493 {
494   fillConnectivity();
495
496   if (Mode==MED_FULL_INTERLACE)
497     return _connectivity->getConnectivity(ConnectivityType,entity,Type);
498   throw MEDEXCEPTION(LOCALIZED("GRID::getConnectivity : only for MED_FULL_INTERLACE mode"));
499 }
500
501 /*!
502   Return the required index array for a connectivity received in
503   MED_FULL_ENTERLACE mode and MED_ALL_ELEMENTS type.
504
505   This array allow to find connectivity of each elements.
506
507   Example : Connectivity of i^{th} elements (1<=i<=NumberOfElement) begin
508   at index ConnectivityIndex[i-1] and end at index ConnectivityIndex[i]-1
509   in Connectivity array (Connectivity[ConnectivityIndex[i-1]-1] is the
510   first value)
511  */
512 inline const int * GRID::getConnectivityIndex(medConnectivity ConnectivityType,medEntityMesh entity) const
513 {
514   fillConnectivity();
515
516   return _connectivity->getConnectivityIndex(ConnectivityType, entity);
517 }
518
519 /*!
520   Return the reverse connectivity required by ConnectivityType :
521   - If ConnectivityType=MED_NODAL : return connectivity node-cell
522   - If ConnectivityType=MED_DESCENDING : return connectivity face-cell
523
524   You must get ReverseConnectivityIndex array to use it.
525  */
526 inline const int * GRID::getReverseConnectivity(medConnectivity ConnectivityType,medEntityMesh Entity/*=MED_CELL*/) const
527 {
528   fillConnectivity();
529
530   if (NULL==_connectivity)
531     throw MEDEXCEPTION("GRID::getReverseConnectivity : no connectivity defined in MESH !");
532
533   return _connectivity->getReverseConnectivity(ConnectivityType,Entity);
534 }
535
536 /*!
537   Return the index array required by ConnectivityType.
538
539   This array allow to find reverse connectivity of each elements.
540
541   Example : Reverse connectivity of i^{th} elements (1<=i<=NumberOfElement)
542   begin at index ReverseConnectivityIndex[i-1] and end at index
543   ReverseConnectivityIndex[i]-1
544   in ReverseConnectivity array (
545   ReverseConnectivity[ReverseConnectivityIndex[i-1]-1]
546   is the first value)
547  */
548 inline const int * GRID::getReverseConnectivityIndex(medConnectivity ConnectivityType,medEntityMesh Entity/*=MED_CELL*/) const
549 {
550   fillConnectivity();
551
552   if (NULL==_connectivity)
553     throw MEDEXCEPTION("GRID::getReverseConnectivityIndex : no connectivity defined in MESH !");
554
555   return _connectivity->getReverseConnectivityIndex(ConnectivityType,Entity);
556 }
557
558 #endif