Salome HOME
adding a new test for makeMesh method.
[modules/med.git] / src / MULTIPR / MULTIPR_Mesh.hxx
1 //  Copyright (C) 2007-2008  CEA/DEN, EDF R&D
2 //
3 //  This library is free software; you can redistribute it and/or
4 //  modify it under the terms of the GNU Lesser General Public
5 //  License as published by the Free Software Foundation; either
6 //  version 2.1 of the License.
7 //
8 //  This library is distributed in the hope that it will be useful,
9 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 //  Lesser General Public License for more details.
12 //
13 //  You should have received a copy of the GNU Lesser General Public
14 //  License along with this library; if not, write to the Free Software
15 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 // Partitioning/decimation module for the SALOME v3.2 platform
20 //
21 /**
22  * \file    MULTIPR_Mesh.hxx
23  *
24  * \brief   Class Mesh used by the MULTIPR API; used to wrap MED file meshes.
25  *
26  * \author  Olivier LE ROUX - CS, Virtual Reality Dpt
27  * 
28  * \date    01/2007
29  */
30
31 #ifndef MULTIPR_MESH_HXX
32 #define MULTIPR_MESH_HXX
33
34 //*****************************************************************************
35 // Includes section
36 //*****************************************************************************
37
38 extern "C"
39 {
40     #include "med.h"
41 }
42
43 #include <iostream>
44 #include <fstream>
45 #include <set>
46 #include <map>
47 #include <vector>
48 #include <string>
49
50 #include "MULTIPR_Globals.hxx"
51
52 namespace multipr
53 {
54
55 //*****************************************************************************
56 // Pre-declaration
57 //*****************************************************************************
58
59 class GaussLoc;
60 class Profil;
61 class Nodes;
62 class Elements;
63 class Family;
64 class Field;
65 class Group;
66 class MeshDis;
67 class PointOfField;
68
69 extern const med_geometrie_element CELL_TYPES[MED_NBR_GEOMETRIE_MAILLE];
70 extern char CELL_NAMES[MED_NBR_GEOMETRIE_MAILLE][MED_TAILLE_NOM + 1];
71 extern const int CELL_NB_NODE[MED_NBR_GEOMETRIE_MAILLE];
72
73 enum eMeshType
74 {
75     eMED_POINT1,
76     eMED_SEG2, 
77     eMED_SEG3,
78     eMED_TRIA3,
79     eMED_TRIA6,
80     eMED_QUAD4,
81     eMED_QUAD8,
82     eMED_TETRA4,
83     eMED_TETRA10,
84     eMED_HEXA8,
85     eMED_HEXA20,
86     eMED_PENTA6,
87     eMED_PENTA15,
88         eMED_PYRA5,
89         eMED_PYRA13,
90         eMaxMedMesh
91 };
92
93 //*****************************************************************************
94 // Class Mesh
95 //*****************************************************************************
96
97 /**
98  * Assumes:
99  * - 3D mesh in a 3D space
100  * - Unstructured mesh (not a grid)
101  * - Nodal connectivity
102  * - Cartesian coordinates system
103  * Always use FULL_INTERLACE arrays
104  */
105 class Mesh
106 {
107 public:
108
109     /**
110      * Builds an empty Mesh (default constructor).
111      */
112     Mesh();
113      
114     /**
115      * Destructor. Removes everything.
116      */
117     ~Mesh();
118      
119     /**
120      * Resets this object in its state by default (empty). Cleans memory.
121      */
122     void reset();
123     
124     //---------------------------------------------------------------------
125     // Basic accessors/mutators
126     //---------------------------------------------------------------------
127     
128     /**
129      * Returns the name of this Mesh.
130      * \return the name of this Mesh.
131      */
132     const char* getName() const { return mMeshName; }
133     
134         /**
135      * Returns the groups of this Mesh.
136      * \return the groups of this Mesh.
137      */
138         std::vector<Group*>* getGroups() { return &mGroups; }
139
140         /**
141      * Returns the nodes of this Mesh.
142      * \return the nodes of this Mesh.
143      */
144         const Nodes* getNodes() const { return mNodes; }
145
146         /**
147      * Returns the elements of this Mesh.
148      * \param pGeomIdx The index of the geometry.
149      * \return the elements of this Mesh.
150      */
151         const Elements* getElements(int pGeomIdx) const { return mElements[pGeomIdx]; }
152
153         /**
154      * Returns the gauss index of the splited meshes.
155          * Only valid after a call to Mesh::splitGroupsOfElements().
156      * \return the elements of this Mesh.
157      */
158         GaussIndexList* editGaussIndex() { return &mGaussIndex; }
159                 
160     /**
161      * Returns the name of all the scalar fields.
162      * \return the name of all the scalar fields.
163      */
164     std::vector<std::string> getNameScalarFields() const; 
165     
166     /**
167      * Returns the number of iteration for a given field.
168      * \return the number of iteration for a given field.
169      */
170     int getTimeStamps(const char* pFieldName) const; 
171     
172     /**
173      * Returns a Field from its name; NULL if it does not exist.
174      * \param  pFieldName name of the field to be retrieved.
175      * \param  pGeomType The type of the mesh.
176      * \return the Field pFieldName of it exists, NULL otherwise.
177      * \throw  NullArgumentException if pFieldName is NULL.
178      */
179     Field* getFieldByName(const char* pFieldName, eMeshType pGeomType = eMaxMedMesh) const;
180     
181     /**
182      * Get the minimum and maximum value of the field.
183      * \param  pFieldName The name of the field.
184      * \param pMin The mininum value to fill.
185      * \param pMax The maxinum value to fill.
186      */
187     void getFieldMinMax(const char* pFieldName, float& pMin, float& pMax) const;
188     
189     /**
190      * Returns a GaussLoc from its name; NULL if it does not exist.
191      * \param  pGaussLocName name of the GaussLoc to be retrieved.
192      * \return the GaussLoc pGaussLocName if it exists, NULL otherwise.
193      * \throw  NullArgumentException if pGaussLocName is NULL.
194      */
195     GaussLoc* getGaussLocByName(const char* pGaussLocName) const;    
196      
197     /**
198      * Returns the number of elements for all geometry type (TETRA4 AND HEXA8 AND etc).
199      * \return the number of elements.
200      */
201     int getNumberOfElements() const;
202     
203         /**
204          * Returns the number of elements for the specified geometry type.
205          * \param pGeomType The type of geometry (eMED_TETRA4 OR eMED_HEXA20 OR etc)
206          * \return the number of elements.
207          */
208         int     getNumberOfElements(eMeshType pGeomType) const;
209         
210     /**
211      * Add a profile to the mesh.
212      * \param pProfil The profile to add.
213      */
214     void addProfile(Profil* pProfil) { this->mProfils.push_back(pProfil); }
215
216     /**
217      * Get the vector of profiles of this mesh.
218      * \return A vector of profiles (of this mesh...).
219      */    
220     std::vector<Profil*>& getProfils() { return mProfils; }
221     
222     /**
223      * Get the profile by its name.
224      * \param pProfilName The name of the profil to get.
225      * \return A Profil or NULL.
226      */
227     Profil* getProfil(const std::string pProfilName);
228     
229     //---------------------------------------------------------------------
230     // Algorithms
231     //---------------------------------------------------------------------
232     
233     /**
234      * Creates a Mesh from a subset of its elements (cells).
235      * \param  pSetOfElements subset of elements to keep.
236      * \param  pNewMeshName   name of the new Mesh.
237      * \return a new Mesh which is a restriction of this Mesh to the given set of elements.
238      * \throw  NullArgumentException if pNewMeshName is NULL.
239      */
240     Mesh* createFromSetOfElements(const std::set<med_int>* pSetOfElements, const char* pNewMeshName);
241     
242     /**
243      * Creates a Mesh from one of its group.
244      * \param  pGroup       any group of this Mesh.  
245      * \param  pNewMeshName name of the new Mesh.
246      * \return a new Mesh which is a restriction of this Mesh to pGroup.
247      * \throw  NullArgumentException if pGroup or pNewMeshName is NULL.
248      */
249     Mesh* createFromGroup(const Group* pGroup, const char* pNewMeshName);
250
251     /**
252      * Creates a Mesh from one of its family.
253      * \param  pFamily       any family of this Mesh.  
254      * \param  pNewMeshName name of the new Mesh.
255      * \return a new Mesh which is a restriction of this Mesh to pFamily.
256      * \throw  NullArgumentException if pGroup or pNewMeshName is NULL.
257      */
258     Mesh* createFromFamily(const Family* pFamily, const char* pNewMeshName);
259             
260     /**
261      * Creates a Mesh by merging this one with the given one.
262      * Warning: not all the data are merged (e.g. bounding box if not computed and family/groups are partially filled).
263      * This method is intended to be used to build mesh for visualization (VISU integration).
264      * Merge is partial to improve speed.
265      * \param  pMesh any Mesh
266      * \return a new Mesh which is a the union of this and pMesh.
267      * \throw  NullArgumentException if pGroup or pNewMeshName is NULL.
268      */
269     //Mesh* mergePartial(const Mesh* pMesh);
270     Mesh* mergePartial(std::vector<Mesh*> pMeshes, const char* pFieldName, int pFieldIt);
271     
272     /**
273      * Creates a distributed mesh (MeshDis) by creating a new mesh for each group of elements in this Mesh.
274      * \return a distributed mesh from groups of this Mesh.
275      */
276     MeshDis* splitGroupsOfElements();
277     
278     /**
279      * Creates a new mesh by decimating this one.
280      * \param  pFilterName  name of the filter to be used for decimation (e.g. Filtre_GradientMoyen); should not be NULL.
281      * \param  pArgv        all the arguments for filtering as a single string.
282      * \param  pNameNewMesh name of the new mesh.
283      * \return the decimated mesh.
284      * \throw  NullArgumentException if one of the arguments is NULL.
285      * \throw  RuntimeException if any error occurs while decimating data.
286      */
287     Mesh* decimate(
288         const char* pFilterName,
289         const char* pArgv,
290         const char* pNameNewMesh);
291     
292     /**
293      * Gets all the points in a field. Each point has coordinates and a value.
294      * \param  pField      any field of this Mesh.
295      * \param  pTimeStepIt time step iteration.
296      * \param  pPoints     (out) list of points.
297          * \param  pGeomType   Get the points from this type of geometry. If the values are on the node, this parameter is ignored.
298      * \throw  NullArgumentException if pField is NULL.
299      * \throw  IllegalArgumentException if pTimeStepIt is invalid.
300      */
301      void getAllPointsOfField(Field* pField, int pTimeStepIt, std::vector<PointOfField>& pPoints, eMeshType pGeomType);
302     
303     /**
304      * Returns a default value for neighborhood radius.
305      * Return value is such that, for any point in the field, average number of neighbours is pN.
306      * \param  pN average number of neighbours.
307      * \return a default value for neighborhood radius; 1.0 if some error occurs.
308      */
309     float evalDefaultRadius(int pN) const;
310     
311     //---------------------------------------------------------------------
312     // I/O
313     //---------------------------------------------------------------------
314     
315     /**
316      * Reads a Mesh from a sequential MED file. Resets the object before.
317      * \param  pMEDfilename
318      * \param  pMeshName
319      * \param  pReadFields Set this to false to skip field.
320      * \throw  IOException if any i/o error occurs.
321      */
322     void readSequentialMED(const char* pMEDfilename, const char* pMeshName, bool pReadFields = true);
323
324     /**
325      * Reads a Mesh from a sequential MED file. Resets the object before.
326      * \param  pMEDfilename
327      * \param  pMeshNumber
328      * \param  pReadFields Set this to false to skip field.
329      * \throw  IOException if any i/o error occurs.
330      */
331     void readSequentialMED(const char* pMEDfilename, med_int pMeshNumber, bool pReadFields = true);
332
333     /**
334      * Writes this Mesh and all related things into a MED file.
335      * \param  pMEDfilename
336      * \throw  IOException if any i/o error occurs.
337      */
338     void writeMED(const char* pMEDfilename);
339     
340     /**
341      * Writes this Mesh and all related things into a MED file.
342      * \param  pMEDfilename
343      * \param  pMeshName
344      * \throw  IOException if any i/o error occurs.
345      */
346     void writeMED(const char* pMEDfilename, const char* pMeshName);
347     
348     /**
349      * Sets the flag which control the stream operator <<.
350      * \param pFlag new flag value.
351      */
352     void setPrintAll(bool pFlag) { mFlagPrintAll = pFlag; }
353         
354     /**
355      * Dumps any Mesh to the given output stream.
356      * \param  pOs any output stream.
357      * \param  pM  any Mesh.
358      * \return the output stream pOs.
359      */
360     friend std::ostream& operator<<(std::ostream& pOs, Mesh& pM);
361     
362 private:
363      
364     /**
365      * Opens a MED file for the given file name.
366      * \param  pMEDfilename
367      * \param  pMEDModeAccess
368      * \throw  IOException if any i/o error occurs.
369      */
370     void _openMEDFile(const char* pMEDfilename, med_mode_acces pMEDModeAccess = MED_LECTURE);
371
372     /**
373      * Reads a Mesh from a sequential MED file. Resets the object before.
374      * \param  pMeshName
375      * \param  pReadFields Set this to false to skip field.
376      * \throw  IOException if any i/o error occurs.
377      */
378     void _readSequentialMED(const char* pMeshName, bool pReadFields);
379
380     /**
381      * Reads all Gauss localizations in the current MED file.
382      * \throw  IOException if an i/o error occurs.
383      */
384     void readGaussLoc();
385      
386     /**
387      * Reads families in the currentMED file and build groups.
388      * \throw  IOException if an i/o error occurs.
389      */
390     void readFamilies();
391     
392     /**
393      * Finalizes the constructions of families and groups. 
394      * Fill structures with elements.
395      */
396     void finalizeFamiliesAndGroups();
397     
398     /**
399      * Reads fields related to this mesh in the current MED file.
400      * \throw  IOException if an i/o error occurs.
401      */
402     void readFields();
403     
404 private:
405
406     /**
407      * Name of the associated MED file.
408      */
409     char                              mMEDfilename[256];
410     
411     /**
412      * MED file handle.
413      */
414     med_idt                           mMEDfile;
415     
416     /**
417      * Name of this mesh.
418      */
419     char                              mMeshName[MED_TAILLE_NOM + 1];
420     
421     /**
422      * Universal name of this mesh.
423      */ 
424     char                              mMeshUName[MED_TAILLE_DESC + 1];
425     
426     /**
427      * Description.
428      */
429     char                              mMeshDesc[MED_TAILLE_DESC + 1]; 
430     
431     /**
432      * Dimension.
433      */
434     med_int                           mMeshDim;
435     
436     /**
437      * Type of mesh (MED_NON_STRUCTURE or MED_STRUCTURE (=grid)) 
438      */
439     med_maillage                      mMeshType;
440     
441     /** 
442      * Axis aligned bounding box of this mesh.
443      */
444     med_float                         mMeshBBoxMin[3];
445     med_float                         mMeshBBoxMax[3];
446
447     /**
448      * All the nodes used by this mesh. 
449      */
450     Nodes*                            mNodes;
451     
452     /**
453      * All the TETRA10 elements used by this mesh.
454      */
455     Elements*                         mElements[eMaxMedMesh];
456     
457     /**
458      * Table of families used by this mesh.
459      */
460     std::vector<Family*>              mFamilies;
461     
462     /**
463      * Map to retrieve a Family from its id.
464      */
465     std::map<med_int, Family*>        mFamIdToFam;
466     
467     /**
468      * Table of groups used by this mesh.
469      */
470     std::vector<Group*>               mGroups;
471     
472     /**
473      * Map to retrieve a Group from its name.
474      */
475     std::map<std::string, Group*>     mGroupNameToGroup;
476     
477     /**
478      * Table of GaussLoc. 
479      */
480     std::vector<GaussLoc*>            mGaussLoc; 
481     
482     /**
483      * Map to retrieve a Gauss info from its name.
484      */
485     std::map<std::string, GaussLoc*>  mGaussLocNameToGaussLoc;
486     
487     /**
488      * Table of fields related to this mesh.
489      * Number of fields = mFields.size().
490      */
491     std::vector<Field*>               mFields;
492     
493     /**
494      * Table of profils.
495      */
496     std::vector<Profil*>              mProfils;
497     
498     /** 
499      * Flag to control the behaviour of the stream operator <<. 
500      */
501     bool                              mFlagPrintAll;
502     
503         /**
504          * List of gauss points index for optimized domain split.
505          */
506         GaussIndexList                                    mGaussIndex;
507         
508 private:
509
510     // do not allow copy constructor
511     Mesh(const Mesh&);
512     
513     // do not allow copy
514     Mesh& operator=(const Mesh&);
515     
516     // do not allow operator ==
517     bool operator==(const Mesh&); 
518     
519 }; // class Mesh
520
521
522 } // namespace MULTIPR
523
524
525 #endif // MULTIPR_MESH_HXX
526
527 // EOF