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