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