]> SALOME platform Git repositories - modules/med.git/blob - src/MEDMEM/MEDMEM_Meshing.cxx
Salome HOME
Merge from BR_V5_DEV 16Feb09
[modules/med.git] / src / MEDMEM / MEDMEM_Meshing.cxx
1 //  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 //  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 //  This library is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU Lesser General Public
8 //  License as published by the Free Software Foundation; either
9 //  version 2.1 of the License.
10 //
11 //  This library is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 //  Lesser General Public License for more details.
15 //
16 //  You should have received a copy of the GNU Lesser General Public
17 //  License along with this library; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 /*
23   File MEDMEM_Meshing.cxx
24   $Header$
25 */
26
27 #include <string>
28
29 #include "MEDMEM_Utilities.hxx"
30 #include "MEDMEM_STRING.hxx"
31 #include "MEDMEM_Exception.hxx"
32 #include "MEDMEM_define.hxx"
33
34 #include "MEDMEM_Meshing.hxx"
35 #include "MEDMEM_Group.hxx"
36
37 using namespace std;
38 using namespace MEDMEM;
39 using namespace MED_EN;
40
41 namespace MEDMEM {
42 /*!
43
44 \defgroup MESHING_constructors Constructors
45
46 \defgroup MESHING_general General information settings
47
48 \defgroup MESHING_nodes Node coordinates settings
49
50 \defgroup MESHING_connectivity Connectivity settings
51
52 When defining the connectivity, MED_CELL elements connectivity
53 should be defined first. If necessary, constituent connectivities (MED_FACE and/or MED_EDGE) can be defined afterwards. 
54
55 \warning It should be kept in mind that when defining connectivities,
56 elements should be sorted in ascending type order (the type order 
57 being defined by the number of nodes).
58
59
60 \defgroup MESHING_group Group creation
61
62 \defgroup MESHING_poly Polygons and Polyhedra creation
63
64 These methods belong to the meshing class and are necessary for
65 creating the connectivities of MED_POLYHEDRON and MED_POLYGON
66 elements.
67
68 */
69
70 /*!  
71 \addtogroup MESHING_constructors
72  @{  
73 */
74
75 /*! Creates an empty MESH. */
76 MESHING::MESHING(): MESH()
77 {
78   MESSAGE_MED("MESHING::MESHING()");
79   SCRUTE_MED(_coordinate);
80   SCRUTE_MED(_connectivity);
81 }
82 /*!  @}  */
83
84 MESHING::~MESHING()
85 {
86   MESSAGE_MED("Deleting MESHING !!");
87 }
88
89 /*!  
90 \addtogroup MESHING_general
91  @{  */
92
93 /*! Sets the dimension of the space. */
94 void MESHING::setSpaceDimension(int SpaceDimension)
95 {
96   _spaceDimension = SpaceDimension ;
97 }
98
99 /*! Sets the dimension of the mesh. */
100 void MESHING::setMeshDimension(const int MeshDimension)
101 {
102    _meshDimension = MeshDimension ;
103    if (_connectivity)
104      _connectivity->setEntityDimension(MeshDimension);
105 }
106 /*!  @}  */
107
108 /*!  
109 \addtogroup MESHING_nodes
110  @{  */
111
112 /*! Sets the number of nodes used in the mesh. */
113 void MESHING::setNumberOfNodes(const int NumberOfNodes)
114 {
115   _numberOfNodes = NumberOfNodes ;
116   if (_connectivity)
117     _connectivity->setNumberOfNodes(NumberOfNodes);
118 }
119
120 /*! 
121   Sets the whole coordinates array in a given system and interlacing mode.
122   The system coordinates are :
123     - "MED_CART"
124     - "MED_CYL"
125     - "MED_SPHER"
126   The interlacing mode are :
127     - MED_NO_INTERLACE   :  X1 X2 Y1 Y2 Z1 Z2
128     - MED_FULL_INTERLACE :  X1 Y1 Z1 X2 Y2 Z2
129
130 Example :
131 \verbatim
132 MESHING myMeshing ;
133 const int SpaceDimension=2;
134 const int NumberOfNodes=6;
135 int * Coordinates = new int[SpaceDimension*NumberOfNodes] ;
136 string System="CARTESIAN";
137 medModeSwitch Mode = MED_FULL_INTERLACE ;
138 myMeshing.setCoordinates(SpaceDimension,NumberOfNodes,Coordinates,System,Mode);
139 \endverbatim
140
141 */
142 void MESHING::setCoordinates(const int SpaceDimension,
143                                                                                                                  const int NumberOfNodes,
144                                                                                                                  const double * Coordinates,
145                                                                                                                  const string System,
146                                                                                                                  const MED_EN::medModeSwitch Mode)
147 {
148   setSpaceDimension(SpaceDimension);
149   setNumberOfNodes(NumberOfNodes);
150
151   SCRUTE_MED(_coordinate);
152   SCRUTE_MED(_connectivity);
153   //if (NULL != _coordinate) delete _coordinate;
154
155   _coordinate = new COORDINATE(SpaceDimension,
156                                NumberOfNodes,
157                                Mode);
158   _coordinate->setCoordinates(Mode,Coordinates);
159   _coordinate->setCoordinatesSystem(System);
160 }
161 /*!  @}  */
162
163
164 /*! Sets the system in which coordinates are given (MED_CART,MED_CYL,MED_SPHER). */
165 void MESHING::setCoordinatesSystem(const string& System)
166   throw (MEDEXCEPTION)
167 {
168   if (NULL == _coordinate)
169     throw MEDEXCEPTION(LOCALIZED("MESHING::setCoordinatesSystem : no coordinates defined"));
170   _coordinate->setCoordinatesSystem(System);
171 }
172
173 /*! 
174  \addtogroup MESHING_general
175  @{  */
176 /*! Sets the coordinate names array.
177 Coordinates names must not exceed the storage length 
178 defined in MED-file : MED_TAILLE_PNOM (8).
179
180 Example:
181 \verbatim
182 string coord[3]={"x","y","z"};
183 meshing.setCoordinatesNames(coord);
184 \endverbatim
185 */
186 void MESHING::setCoordinatesNames(const string * name)
187 {
188 //    int SpaceDimension = getSpaceDimension() ;
189 //    _coordinate->setCoordinatesNames(SpaceDimension,name);
190   _coordinate->setCoordinatesNames(name);
191 }
192
193
194
195 /*! \ifnot  MEDMEM_ug
196   Sets the (i+1)-th component of coordinate names array.
197  Coordinates names must not exceed the storage length 
198 defined in MED-file : MED_TAILLE_PNOM (8).
199 \endif
200
201 */
202 void MESHING::setCoordinateName(const string name, const int i)
203 {
204   _coordinate->setCoordinateName(name,i);
205 }
206
207 /*! Sets the coordinate unit names array
208   of size n*MED_TAILLE_PNOM. Coordinates units must not exceed the storage length 
209 defined in MED-file : MED_TAILLE_PNOM (8).
210
211 Example:
212 \verbatim
213 string coord[3]={"cm","cm","cm"};
214 meshing.setCoordinatesUnits(coord);
215 \endverbatim
216 */
217 void MESHING::setCoordinatesUnits(const string * units)
218 {
219 //    int SpaceDimension = getSpaceDimension() ;
220 //    _coordinate->setCoordinatesUnits(SpaceDimension,units);
221   _coordinate->setCoordinatesUnits(units);
222 }
223
224 /*!\ifnot MEDMEM_ug
225   Sets the \f$ (i+1)^th \f$  component of the coordinate unit names array
226   ("cm       ","cm       ","cm       ") of size n*MED_TAILLE_PNOM
227  \endif
228 */
229 void MESHING::setCoordinateUnit(const string unit, const int i)
230 {
231   _coordinate->setCoordinateUnit(unit,i);
232 }
233 /*!  @}  */
234
235 /*! 
236  \addtogroup MESHING_connectivity
237  @{ 
238 */
239
240 /*!
241   Creates a new connectivity object with the given number of type and
242   entity. If a connectivity already exist, it is deleted by the call.
243
244   For exemple setNumberOfTypes(3,MED_CELL) creates a connectivity with 3 
245   medGeometryElement in MESH for MED_CELL entity (like MED_TETRA4, 
246   MED_PYRA5 and MED_HEXA6 for example).
247
248   Returns an exception if it could not create the connectivity (as if we set 
249   MED_FACE connectivity before MED_CELL).
250 */
251 void MESHING::setNumberOfTypes(const int NumberOfTypes,
252                                                                                                                          const MED_EN::medEntityMesh Entity) 
253   throw (MEDEXCEPTION)
254 {
255   const char * LOC = "MESHING::setNumberOfTypes( medEntityMesh ) : ";
256
257   // No defined for MED_NODE !
258   if (Entity == MED_NODE)
259     throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Not required with MED_NODE !"));
260
261   if (MED_CELL == Entity) {
262     SCRUTE_MED(_connectivity);
263 //     if (_connectivity != (CONNECTIVITY *) NULL)
264 //       delete _connectivity ;
265     _connectivity = new CONNECTIVITY(NumberOfTypes,Entity) ;
266
267     _connectivity->setNumberOfNodes( _numberOfNodes );
268
269   } else {
270
271     if (_connectivity == NULL) // we must have defined MED_CELL connectivity
272       throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"No connectivity on MED_CELL defined !"));
273
274     if (MED_FACE == Entity)
275       if (3 != getSpaceDimension())
276         throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"No connectivity on MED_FACE could be defined in non 3D space !"));
277     
278     if (MED_EDGE == Entity)
279       if (3 == getSpaceDimension()) {
280         if (!_connectivity->existConnectivity(MED_NODAL,MED_FACE))
281           throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"No connectivity on MED_FACE defined !"));
282       } else {
283         if (2 != getSpaceDimension())
284           throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Could not set connectivity on MED_EDGE !"));
285       }
286     // all right, we could create connectivity !
287     CONNECTIVITY * myConnectivity = new CONNECTIVITY(NumberOfTypes,Entity) ;
288     myConnectivity->setEntityDimension(_connectivity->getEntityDimension()-1);
289     myConnectivity->setNumberOfNodes(_connectivity->getNumberOfNodes());
290     _connectivity->setConstituent(myConnectivity);
291   }
292 }
293
294 /*!
295   Sets the list of geometric types used by a given entity.
296   medEntityMesh entity could be : MED_CELL, MED_FACE, MED_EDGE.
297   This method is used to set the differents geometrics types 
298 ({MED_TETRA4,MED_PYRA5,MED_HEXA8} for example). Geometric types should be given in increasing order of number of nodes for entity type \a entity.
299
300   Remark : Don't use MED_NODE and MED_ALL_ENTITIES.
301
302 If \a entity is not defined, the method will throw an exception.
303
304 */
305
306 void MESHING::setTypes(const MED_EN::medGeometryElement * Types,
307                                                                                         const MED_EN::medEntityMesh entity)
308   throw (MEDEXCEPTION)
309 {
310   if (entity == MED_NODE)
311     throw MEDEXCEPTION(LOCALIZED("MESHING::setTypes : Not defined with MED_NODE entity !"));
312
313   if (_connectivity == NULL)
314     throw MEDEXCEPTION(LOCALIZED("MESHING::setTypes : No connectivity defined !"));
315
316   _connectivity->setGeometricTypes(Types,entity) ;
317 }
318
319 /*!
320   Sets the number of elements for each geometric type of given entity.
321
322   Example : setNumberOfElements(\{12,23\},MED_FACE);
323   If there are two types of face (MED_TRIA3 and MED_QUAD4), 
324   this sets 12 triangles and 23 quadrangles.
325 */
326 void MESHING::setNumberOfElements(const int * NumberOfElements,
327                                   const MED_EN::medEntityMesh Entity)
328   throw (MEDEXCEPTION)
329 {
330   const char * LOC = "MESHING::setNumberOfElements(const int *, medEntityMesh) : " ;
331
332   if (Entity==MED_NODE)
333     throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Not defined with MED_NODE entity !"));
334
335   if (_connectivity == (CONNECTIVITY*)NULL)
336     throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"No connectivity defined !"));
337
338   int NumberOfTypes = getNumberOfTypes(Entity) ;
339   int * Count = new int[NumberOfTypes+1] ;
340   Count[0]=1 ;
341   for (int i=0; i<NumberOfTypes; i++)
342     Count[i+1]=Count[i]+NumberOfElements[i] ;
343   _connectivity->setCount(Count,Entity) ;
344   delete[] Count ;
345 }
346
347 /*!
348   Sets the nodal connectivity for geometric type \a Type of  entity \a Entity.
349   The nodal connectivity must be defined one element type at a time :
350   \a MED_ALL_ELEMENTS is not a valid \a Type argument.
351
352   Example :
353
354 \verbatim
355 MESHING myMeshing ;
356 myMeshing.setCoordinates(SpaceDimension,NumberOfNodes,Coordinates,System,Mode);
357
358 myMeshing.setNumberOfTypes(2,MED_CELL);
359 myMeshing.setTypes({MED_TRIA3,MED_QUAD4},MED_CELL);
360 myMeshing.setNumberOfElements({3,2},MED_CELL); // 3 MED_TRIA3 and 2 MED_QUAD4
361 myMeshing.setConnectivity({1,2,3,6,8,9,4,5,6},MED_CELL,MED_TRIA3);
362 myMeshing.setConnectivity({1,3,4,5,4,5,7,8},MED_CELL,MED_QUAD4);
363 \endverbatim
364
365   Example : setConnectivity({1,2,3,1,4,2},MED_FACE,MED_TRIA3)
366   Define 2 triangles face defined with nodes 1,2,3 and 1,4,2.
367 */
368 void MESHING::setConnectivity(const int * Connectivity,
369                               const MED_EN::medEntityMesh Entity,
370                               const MED_EN::medGeometryElement Type)
371   throw (MEDEXCEPTION)
372 {
373   const char * LOC = "MESHING::setConnectivity : " ;
374
375   if (Entity==MED_NODE)
376     throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Not defined with MED_NODE entity !"));
377
378   if (_connectivity == (CONNECTIVITY*)NULL)
379     throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"No connectivity defined !"));
380
381   _connectivity->setNumberOfNodes(_numberOfNodes);
382   _connectivity->setNodal(Connectivity,Entity,Type) ;
383 }
384 /*!  @}  */
385
386 /*!  
387 \addtogroup MESHING_poly
388  @{
389   */
390
391 /*! Method setting the connectivity for MED_POLYGON
392 elements
393 \param ConnectivityIndex polygon connectivity index
394 \param Connectivity polygon connectivity
395 \param nbOfPolygons number of polygons defined
396 \param Entity entity of the polygon
397
398 The \a Entity parameter specifies whether the polygon is the highest order
399  element (MED_CELL) or it is a 2D element in a 3D mesh (MED_FACE).
400
401 This method is fully compatible with the MESHING::setConnectivity method.
402 The following code excerpt creates two polygons with 5 and 4 nodes respectively.
403 \verbatim
404 MESHING myMeshing ;
405 myMeshing.setCoordinates(SpaceDimension,NumberOfNodes,Coordinates,System,Mode);
406
407 int conn_index[3]={1,6,10};
408 int conn[9]={1,2,3,4,5,5,4,6,7};
409 int nb_poly=2;
410 meshing.setPolygonsConnectivity(conn_index, conn, nb_poly, MED_CELL)
411 \endverbatim
412
413 */
414
415 void MESHING::setPolygonsConnectivity     (const int * ConnectivityIndex,
416                                            const int * Connectivity,
417                                            int nbOfPolygons,
418                                            const MED_EN::medEntityMesh Entity)
419   throw (MEDEXCEPTION)
420 {
421   if (_connectivity == (CONNECTIVITY*)NULL)
422     throw MEDEXCEPTION("No connectivity defined !");
423   
424   _connectivity->setPolygonsConnectivity(MED_NODAL, Entity, Connectivity, ConnectivityIndex,ConnectivityIndex[nbOfPolygons]-1,nbOfPolygons) ;
425 }
426
427
428 /*! Method setting the connectivity for MED_POLYHEDRON
429 elements
430 \param PolyhedronIndex polyhedra connectivity index
431 \param FacesIndex polyhedra face connectivity index
432 \param Nodes polyhedra connectivity
433 \param nbOfPolyhedra number of polyhedra defined
434 \param Entity deprecated parameter 
435 */
436 void MESHING::setPolyhedraConnectivity     (const int * PolyhedronIndex,
437                                             const int * FacesIndex,
438                                             const int * Nodes,
439                                             int nbOfPolyhedra,
440                                             const MED_EN::medEntityMesh Entity)
441   throw (MEDEXCEPTION)
442 {
443   if (_connectivity == (CONNECTIVITY*)NULL)
444     throw MEDEXCEPTION("No connectivity defined !");
445   if(_connectivity->getPolyTypeRelativeTo()==MED_EN::MED_POLYHEDRA)
446     {
447       int nbOfFacesOfAllPolyhedra=PolyhedronIndex[nbOfPolyhedra]-1;
448       _connectivity->setPolyhedronConnectivity(MED_NODAL, Nodes, PolyhedronIndex, FacesIndex[nbOfFacesOfAllPolyhedra]-1 , nbOfPolyhedra, FacesIndex, nbOfFacesOfAllPolyhedra) ;
449     }
450   else
451     throw MEDEXCEPTION("Invalid connectivity for polyhedra !!!");
452 }
453 /*!  @}  */
454
455 /*!
456   NOT YET IMPLEMENTED !! WARNING
457 */
458 void MESHING::setConnectivities (const int * ConnectivityIndex,
459                                  const int * ConnectivityValue,
460                                  const MED_EN::medConnectivity ConnectivityType,
461                                  const MED_EN::medEntityMesh Entity)
462   throw (MEDEXCEPTION)
463 {
464   const char * LOC = "MESHING::setConnectivities : " ;
465   SCRUTE_MED(Entity);
466   SCRUTE_MED(ConnectivityType);
467   SCRUTE_MED(ConnectivityValue);
468   SCRUTE_MED(ConnectivityIndex);
469
470   throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Not Yet Implemented :: Warning !"));
471 }
472
473 /*!
474 */
475
476 // void MESHING::setGroup(const string name,
477 //                     const string description,
478 //                     const int NumberOfElements,
479 //                     const int * ElementsNumbers,
480 //                     const medEntityMesh Entity)
481 // {
482 //   GROUP * myGroup = new GROUP() ;
483 //   myGroup->setMesh(*this) ;
484 //   myGroup->setName(name) ;
485 //   myGroup->setDescription(description) ;
486 //   myGroup->setEntity(Entity) ;
487 //   // medEntityMesh and medGeometryElement ???
488 //   myGroup->setNumberOfGeometricType(NumberOfType) ;
489 //   myGroup->setGeometricType(Type) ;
490 //   myGroup->setNumberOfGaussPoint(NumberOfGaussPoint) ;
491 //   myGroup->setNumberOfElements(NumberOfElements) ;
492 //   myGroup->setNumber(Number) ;
493 // }
494
495 /*!  
496 \addtogroup MESHING_group
497  @{  */
498
499 /*!Adds group \a Group to the mesh.
500 This function registers the group in the list
501 of groups contained in the mesh, so that
502 when the mesh is used for file writing, the group
503 is written in the corresponding MED-file.
504 */
505
506 void MESHING::addGroup(const GROUP & Group)
507   throw (MEDEXCEPTION)
508 {
509   const char * LOC = "MESHING::addGroup : " ;
510
511   GROUP * myGroup = new GROUP(Group) ;
512   switch(Group.getEntity()){
513   case MED_CELL : {
514     _groupCell.push_back(myGroup);
515     break;
516   }
517   case MED_FACE : {
518      _groupFace.push_back(myGroup);
519     break;
520   }
521   case MED_EDGE : {
522      _groupEdge.push_back(myGroup);
523     break;
524   }
525   case MED_NODE : {
526      _groupNode.push_back(myGroup);
527     break;
528   }
529   default :
530     throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Bad Entity !"));
531   }
532 }
533
534 };
535 /*!  @}  */