1 // Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 File MEDMEM_Meshing.cxx
29 #include "MEDMEM_Utilities.hxx"
30 #include "MEDMEM_STRING.hxx"
31 #include "MEDMEM_Exception.hxx"
32 #include "MEDMEM_define.hxx"
34 #include "MEDMEM_Meshing.hxx"
35 #include "MEDMEM_Group.hxx"
38 using namespace MEDMEM;
39 using namespace MED_EN;
44 \defgroup MESHING_constructors Constructors
46 \defgroup MESHING_general General information settings
48 \defgroup MESHING_nodes Node coordinates settings
50 \defgroup MESHING_connectivity Connectivity settings
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.
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).
60 \defgroup MESHING_group Group creation
62 \defgroup MESHING_poly Polygons and Polyhedra creation
64 These methods belong to the meshing class and are necessary for
65 creating the connectivities of MED_POLYHEDRON and MED_POLYGON
71 \addtogroup MESHING_constructors
75 /*! Creates an empty MESH. */
76 MESHING::MESHING(): MESH()
78 MESSAGE_MED("MESHING::MESHING()");
79 SCRUTE_MED(_coordinate);
80 SCRUTE_MED(_connectivity);
86 MESSAGE_MED("Deleting MESHING !!");
90 \addtogroup MESHING_general
93 /*! Sets the dimension of the space. */
94 void MESHING::setSpaceDimension(int SpaceDimension)
96 _spaceDimension = SpaceDimension ;
99 /*! Sets the dimension of the mesh. */
100 void MESHING::setMeshDimension(const int MeshDimension)
102 _meshDimension = MeshDimension ;
104 _connectivity->setEntityDimension(MeshDimension);
109 \addtogroup MESHING_nodes
112 /*! Sets the number of nodes used in the mesh. */
113 void MESHING::setNumberOfNodes(const int NumberOfNodes)
115 _numberOfNodes = NumberOfNodes ;
117 _connectivity->setNumberOfNodes(NumberOfNodes);
121 Sets the whole coordinates array in a given system and interlacing mode.
122 The system coordinates are :
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
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);
142 void MESHING::setCoordinates(const int SpaceDimension,
143 const int NumberOfNodes,
144 const double * Coordinates,
146 const MED_EN::medModeSwitch Mode)
148 setSpaceDimension(SpaceDimension);
149 setNumberOfNodes(NumberOfNodes);
151 SCRUTE_MED(_coordinate);
152 SCRUTE_MED(_connectivity);
153 //if (NULL != _coordinate) delete _coordinate;
155 _coordinate = new COORDINATE(SpaceDimension,
158 _coordinate->setCoordinates(Mode,Coordinates);
159 _coordinate->setCoordinatesSystem(System);
164 /*! Sets the system in which coordinates are given (MED_CART,MED_CYL,MED_SPHER). */
165 void MESHING::setCoordinatesSystem(const string& System)
168 if (NULL == _coordinate)
169 throw MEDEXCEPTION(LOCALIZED("MESHING::setCoordinatesSystem : no coordinates defined"));
170 _coordinate->setCoordinatesSystem(System);
174 \addtogroup MESHING_general
176 /*! Sets the coordinate names array.
177 Coordinates names must not exceed the storage length
178 defined in MED-file : MED_TAILLE_PNOM (8).
182 string coord[3]={"x","y","z"};
183 meshing.setCoordinatesNames(coord);
186 void MESHING::setCoordinatesNames(const string * name)
188 // int SpaceDimension = getSpaceDimension() ;
189 // _coordinate->setCoordinatesNames(SpaceDimension,name);
190 _coordinate->setCoordinatesNames(name);
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).
202 void MESHING::setCoordinateName(const string name, const int i)
204 _coordinate->setCoordinateName(name,i);
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).
213 string coord[3]={"cm","cm","cm"};
214 meshing.setCoordinatesUnits(coord);
217 void MESHING::setCoordinatesUnits(const string * units)
219 // int SpaceDimension = getSpaceDimension() ;
220 // _coordinate->setCoordinatesUnits(SpaceDimension,units);
221 _coordinate->setCoordinatesUnits(units);
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
229 void MESHING::setCoordinateUnit(const string unit, const int i)
231 _coordinate->setCoordinateUnit(unit,i);
236 \addtogroup MESHING_connectivity
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.
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).
248 Returns an exception if it could not create the connectivity (as if we set
249 MED_FACE connectivity before MED_CELL).
251 void MESHING::setNumberOfTypes(const int NumberOfTypes,
252 const MED_EN::medEntityMesh Entity)
255 const char * LOC = "MESHING::setNumberOfTypes( medEntityMesh ) : ";
257 // No defined for MED_NODE !
258 if (Entity == MED_NODE)
259 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Not required with MED_NODE !"));
261 if (MED_CELL == Entity) {
262 SCRUTE_MED(_connectivity);
263 // if (_connectivity != (CONNECTIVITY *) NULL)
264 // delete _connectivity ;
265 _connectivity = new CONNECTIVITY(NumberOfTypes,Entity) ;
267 _connectivity->setNumberOfNodes( _numberOfNodes );
271 if (_connectivity == NULL) // we must have defined MED_CELL connectivity
272 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"No connectivity on MED_CELL defined !"));
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 !"));
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 !"));
283 if (2 != getSpaceDimension())
284 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Could not set connectivity on MED_EDGE !"));
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);
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.
300 Remark : Don't use MED_NODE and MED_ALL_ENTITIES.
302 If \a entity is not defined, the method will throw an exception.
306 void MESHING::setTypes(const MED_EN::medGeometryElement * Types,
307 const MED_EN::medEntityMesh entity)
310 if (entity == MED_NODE)
311 throw MEDEXCEPTION(LOCALIZED("MESHING::setTypes : Not defined with MED_NODE entity !"));
313 if (_connectivity == NULL)
314 throw MEDEXCEPTION(LOCALIZED("MESHING::setTypes : No connectivity defined !"));
316 _connectivity->setGeometricTypes(Types,entity) ;
320 Sets the number of elements for each geometric type of given entity.
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.
326 void MESHING::setNumberOfElements(const int * NumberOfElements,
327 const MED_EN::medEntityMesh Entity)
330 const char * LOC = "MESHING::setNumberOfElements(const int *, medEntityMesh) : " ;
332 if (Entity==MED_NODE)
333 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Not defined with MED_NODE entity !"));
335 if (_connectivity == (CONNECTIVITY*)NULL)
336 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"No connectivity defined !"));
338 int NumberOfTypes = getNumberOfTypes(Entity) ;
339 int * Count = new int[NumberOfTypes+1] ;
341 for (int i=0; i<NumberOfTypes; i++)
342 Count[i+1]=Count[i]+NumberOfElements[i] ;
343 _connectivity->setCount(Count,Entity) ;
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.
356 myMeshing.setCoordinates(SpaceDimension,NumberOfNodes,Coordinates,System,Mode);
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);
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.
368 void MESHING::setConnectivity(const int * Connectivity,
369 const MED_EN::medEntityMesh Entity,
370 const MED_EN::medGeometryElement Type)
373 const char * LOC = "MESHING::setConnectivity : " ;
375 if (Entity==MED_NODE)
376 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Not defined with MED_NODE entity !"));
378 if (_connectivity == (CONNECTIVITY*)NULL)
379 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"No connectivity defined !"));
381 _connectivity->setNumberOfNodes(_numberOfNodes);
382 _connectivity->setNodal(Connectivity,Entity,Type) ;
387 \addtogroup MESHING_poly
391 /*! Method setting the connectivity for MED_POLYGON
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
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).
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.
405 myMeshing.setCoordinates(SpaceDimension,NumberOfNodes,Coordinates,System,Mode);
407 int conn_index[3]={1,6,10};
408 int conn[9]={1,2,3,4,5,5,4,6,7};
410 meshing.setPolygonsConnectivity(conn_index, conn, nb_poly, MED_CELL)
415 void MESHING::setPolygonsConnectivity (const int * ConnectivityIndex,
416 const int * Connectivity,
418 const MED_EN::medEntityMesh Entity)
421 if (_connectivity == (CONNECTIVITY*)NULL)
422 throw MEDEXCEPTION("No connectivity defined !");
424 _connectivity->setPolygonsConnectivity(MED_NODAL, Entity, Connectivity, ConnectivityIndex,ConnectivityIndex[nbOfPolygons]-1,nbOfPolygons) ;
428 /*! Method setting the connectivity for MED_POLYHEDRON
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
436 void MESHING::setPolyhedraConnectivity (const int * PolyhedronIndex,
437 const int * FacesIndex,
440 const MED_EN::medEntityMesh Entity)
443 if (_connectivity == (CONNECTIVITY*)NULL)
444 throw MEDEXCEPTION("No connectivity defined !");
445 if(_connectivity->getPolyTypeRelativeTo()==MED_EN::MED_POLYHEDRA)
447 int nbOfFacesOfAllPolyhedra=PolyhedronIndex[nbOfPolyhedra]-1;
448 _connectivity->setPolyhedronConnectivity(MED_NODAL, Nodes, PolyhedronIndex, FacesIndex[nbOfFacesOfAllPolyhedra]-1 , nbOfPolyhedra, FacesIndex, nbOfFacesOfAllPolyhedra) ;
451 throw MEDEXCEPTION("Invalid connectivity for polyhedra !!!");
456 NOT YET IMPLEMENTED !! WARNING
458 void MESHING::setConnectivities (const int * ConnectivityIndex,
459 const int * ConnectivityValue,
460 const MED_EN::medConnectivity ConnectivityType,
461 const MED_EN::medEntityMesh Entity)
464 const char * LOC = "MESHING::setConnectivities : " ;
466 SCRUTE_MED(ConnectivityType);
467 SCRUTE_MED(ConnectivityValue);
468 SCRUTE_MED(ConnectivityIndex);
470 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Not Yet Implemented :: Warning !"));
476 // void MESHING::setGroup(const string name,
477 // const string description,
478 // const int NumberOfElements,
479 // const int * ElementsNumbers,
480 // const medEntityMesh Entity)
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) ;
496 \addtogroup MESHING_group
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.
506 void MESHING::addGroup(const GROUP & Group)
509 const char * LOC = "MESHING::addGroup : " ;
511 GROUP * myGroup = new GROUP(Group) ;
512 switch(Group.getEntity()){
514 _groupCell.push_back(myGroup);
518 _groupFace.push_back(myGroup);
522 _groupEdge.push_back(myGroup);
526 _groupNode.push_back(myGroup);
530 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Bad Entity !"));