1 // Copyright (C) 2007-2012 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
24 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_nodes
94 Sets the whole coordinates array in a given system and interlacing mode.
95 The system coordinates are :
99 The interlacing mode are :
100 - MED_NO_INTERLACE : X1 X2 Y1 Y2 Z1 Z2
101 - MED_FULL_INTERLACE : X1 Y1 Z1 X2 Y2 Z2
106 const int SpaceDimension=2;
107 const int NumberOfNodes=6;
108 int * Coordinates = new int[SpaceDimension*NumberOfNodes] ;
109 string System="CARTESIAN";
110 medModeSwitch Mode = MED_FULL_INTERLACE ;
111 myMeshing.setCoordinates(SpaceDimension,NumberOfNodes,Coordinates,System,Mode);
115 void MESHING::setCoordinates(const int SpaceDimension,
116 const int NumberOfNodes,
117 const double * Coordinates,
119 const MED_EN::medModeSwitch Mode)
121 _spaceDimension = SpaceDimension;
122 _numberOfNodes = NumberOfNodes;
124 _connectivity->setNumberOfNodes(NumberOfNodes);
126 if ( !NumberOfNodes && !Coordinates )
127 return; // enable using this method for setting SpaceDimension only
129 SCRUTE_MED(_coordinate);
130 SCRUTE_MED(_connectivity);
133 delete _coordinate, _coordinate = 0;
134 _coordinate = new COORDINATE(SpaceDimension,NumberOfNodes,Mode);
135 _coordinate->setCoordinates(Mode,Coordinates);
136 _coordinate->setCoordinatesSystem(System);
141 \addtogroup MESHING_general
143 /*! Sets the coordinate names array.
144 Coordinates names must not exceed the storage length
145 defined in MED-file : MED_TAILLE_PNOM (8).
149 string coord[3]={"x","y","z"};
150 meshing.setCoordinatesNames(coord);
153 void MESHING::setCoordinatesNames(const string * name)
155 // int SpaceDimension = getSpaceDimension() ;
156 // _coordinate->setCoordinatesNames(SpaceDimension,name);
157 _coordinate->setCoordinatesNames(name);
163 Sets the (i+1)-th component of coordinate names array.
164 Coordinates names must not exceed the storage length
165 defined in MED-file : MED_TAILLE_PNOM (8).
169 void MESHING::setCoordinateName(const string name, const int i)
171 _coordinate->setCoordinateName(name,i);
174 /*! Sets the coordinate unit names array
175 of size n*MED_TAILLE_PNOM. Coordinates units must not exceed the storage length
176 defined in MED-file : MED_TAILLE_PNOM (8).
180 string coord[3]={"cm","cm","cm"};
181 meshing.setCoordinatesUnits(coord);
184 void MESHING::setCoordinatesUnits(const string * units)
186 // int SpaceDimension = getSpaceDimension() ;
187 // _coordinate->setCoordinatesUnits(SpaceDimension,units);
188 _coordinate->setCoordinatesUnits(units);
192 Sets the \f$ (i+1)^th \f$ component of the coordinate unit names array
193 ("cm ","cm ","cm ") of size n*MED_TAILLE_PNOM
196 void MESHING::setCoordinateUnit(const string unit, const int i)
198 _coordinate->setCoordinateUnit(unit,i);
203 \addtogroup MESHING_connectivity
208 Creates a new connectivity object with the given number of type and
209 entity. If a connectivity already exist, it is deleted by the call.
211 For exemple setNumberOfTypes(3,MED_CELL) creates a connectivity with 3
212 medGeometryElement in MESH for MED_CELL entity (like MED_TETRA4,
213 MED_PYRA5 and MED_HEXA6 for example).
215 Returns an exception if it could not create the connectivity (as if we set
216 MED_FACE connectivity before MED_CELL).
218 void MESHING::setNumberOfTypes(const int NumberOfTypes,
219 const MED_EN::medEntityMesh Entity)
222 const char * LOC = "MESHING::setNumberOfTypes( medEntityMesh ) : ";
224 // No defined for MED_NODE !
225 if (Entity == MED_NODE)
226 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Not required with MED_NODE !"));
228 if (MED_CELL == Entity) {
229 SCRUTE_MED(_connectivity);
231 delete _connectivity ;
232 _connectivity = new CONNECTIVITY(NumberOfTypes,Entity) ;
233 _connectivity->setNumberOfNodes( _numberOfNodes );
237 if (_connectivity == NULL) // we must have defined MED_CELL connectivity
238 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"No connectivity on MED_CELL defined !"));
240 if (MED_FACE == Entity)
241 if (3 != getSpaceDimension())
242 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"No connectivity on MED_FACE could be defined in non 3D space !"));
244 if (MED_EDGE == Entity)
246 if (3 == getSpaceDimension()) {
247 if (3 == getMeshDimension() && !_connectivity->existConnectivity(MED_NODAL,MED_FACE))
248 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"No connectivity on MED_FACE defined !"));
249 if (2 > getMeshDimension())
250 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Could not set connectivity on MED_EDGE !"));
252 if (2 != getSpaceDimension())
253 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Could not set connectivity on MED_EDGE !"));
256 // all right, we could create connectivity !
257 CONNECTIVITY * myConnectivity = new CONNECTIVITY(NumberOfTypes,Entity) ;
258 myConnectivity->setNumberOfNodes(_connectivity->getNumberOfNodes());
259 _connectivity->setConstituent(myConnectivity);
264 Sets the list of geometric types used by a given entity.
265 medEntityMesh entity could be : MED_CELL, MED_FACE, MED_EDGE.
266 This method is used to set the differents geometrics types
267 ({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.
269 Remark : Don't use MED_NODE and MED_ALL_ENTITIES.
271 If \a entity is not defined, the method will throw an exception.
275 void MESHING::setTypes(const MED_EN::medGeometryElement * Types,
276 const MED_EN::medEntityMesh entity)
279 if (entity == MED_NODE)
280 throw MEDEXCEPTION(LOCALIZED("MESHING::setTypes : Not defined with MED_NODE entity !"));
282 if (_connectivity == NULL)
283 throw MEDEXCEPTION(LOCALIZED("MESHING::setTypes : No connectivity defined !"));
285 _connectivity->setGeometricTypes(Types,entity);
289 Sets the number of elements for each geometric type of given entity.
291 Example : setNumberOfElements(\{12,23\},MED_FACE);
292 If there are two types of face (MED_TRIA3 and MED_QUAD4),
293 this sets 12 triangles and 23 quadrangles.
295 void MESHING::setNumberOfElements(const int * NumberOfElements,
296 const MED_EN::medEntityMesh Entity)
299 const char * LOC = "MESHING::setNumberOfElements(const int *, medEntityMesh) : " ;
301 if (Entity==MED_NODE)
302 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Not defined with MED_NODE entity !"));
304 if (_connectivity == (CONNECTIVITY*)NULL)
305 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"No connectivity defined !"));
307 int NumberOfTypes = getNumberOfTypes(Entity) ;
308 int * Count = new int[NumberOfTypes+1] ;
310 for (int i=0; i<NumberOfTypes; i++)
311 Count[i+1]=Count[i]+NumberOfElements[i] ;
312 _connectivity->setCount(Count,Entity) ;
317 Sets the nodal connectivity for geometric type \a Type of entity \a Entity.
318 The nodal connectivity must be defined one element type at a time :
319 \a MED_ALL_ELEMENTS is not a valid \a Type argument.
320 To define connectivity of \a MED_POLYGON and \a MED_POLYHEDRA, \a PolyConnectivityIndex
321 is also necessary, which defines index of the first node of each element.
322 Connectiviy of polyhedron must contain -1 as a separator of faces. For example,
323 a tetrahedron with connectivity {1,2,3,4} can be represented as a polyhedron by the following arrays:<br>
324 Connectivity : {1,2,3,-1,2,3,4,-1,3,4,1,-1,4,1,2}<br>
325 Connectivity_index : {1,16}
331 myMeshing.setCoordinates(SpaceDimension,NumberOfNodes,Coordinates,System,Mode);
332 myMeshing.setNumberOfTypes(2,MED_CELL);
333 myMeshing.setTypes({MED_TRIA3,MED_QUAD4},MED_CELL);
334 myMeshing.setNumberOfElements({3,2},MED_CELL); // 3 MED_TRIA3 and 2 MED_QUAD4
335 myMeshing.setConnectivity(MED_CELL,MED_TRIA3,{1,2,3,6,8,9,4,5,6});
336 myMeshing.setConnectivity(MED_CELL,MED_QUAD4,{1,3,4,5,4,5,7,8});
339 Example : setConnectivity(MED_FACE,MED_TRIA3,{1,2,3,1,4,2})
340 Define 2 triangles face defined with nodes 1,2,3 and 1,4,2.
342 void MESHING::setConnectivity(const MED_EN::medEntityMesh Entity,
343 const MED_EN::medGeometryElement Type,
344 const int * Connectivity,
345 const int * PolyConnectivityIndex)
348 const char * LOC = "MESHING::setConnectivity : " ;
350 if (Entity==MED_NODE)
351 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Not defined with MED_NODE entity !"));
353 if (_connectivity == (CONNECTIVITY*)NULL)
354 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"No connectivity defined !"));
356 _connectivity->setNumberOfNodes(_numberOfNodes);
357 _connectivity->setNodal(Connectivity,Entity,Type,PolyConnectivityIndex) ;
363 \addtogroup MESHING_group
366 /*!Adds group \a Group to the mesh.
367 This function registers the group in the list
368 of groups contained in the mesh, so that
369 when the mesh is used for file writing, the group
370 is written in the corresponding MED-file.
373 void MESHING::addGroup(const GROUP & Group)
376 const char * LOC = "MESHING::addGroup : " ;
378 GROUP * myGroup = new GROUP(Group) ;
379 if(myGroup->getMesh()==this)
383 switch(Group.getEntity()){
385 _groupCell.push_back(myGroup);
389 _groupFace.push_back(myGroup);
393 _groupEdge.push_back(myGroup);
397 _groupNode.push_back(myGroup);
401 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Bad Entity !"));