Salome HOME
*** empty log message ***
[modules/multipr.git] / src / MULTIPR / MULTIPR_MeshDis.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_MeshDis.hxx
6  *
7  * \brief   Class MeshDis: distributed mesh.
8  *          = MASTER file (ASCII) -> list of sequential MED file.
9  *
10  * \author  Olivier LE ROUX - CS, Virtual Reality Dpt
11  * 
12  * \date    01/2007
13  */
14
15 #ifndef MULTIPR_MESHDIS_HXX
16 #define MULTIPR_MESHDIS_HXX
17
18 //*****************************************************************************
19 // Includes section
20 //*****************************************************************************
21
22 extern "C"
23 {
24     #include "med.h"
25 }
26
27 #include <iostream>
28 #include <vector>
29
30 // include MEDSPLITTER used to split mesh using METIS or SCOTCH
31 #include "MEDMEM_define.hxx"
32 #include "MEDMEM_Mesh.hxx"
33 #include "MEDMEM_Family.hxx"
34 #include "MEDSPLITTER_Graph.hxx"
35 #include "MEDSPLITTER_MESHCollection.hxx"
36 #include "MEDSPLITTER_Topology.hxx"
37
38
39 namespace multipr
40 {
41
42 //*****************************************************************************
43 // Pre-declaration
44 //*****************************************************************************
45
46 class Mesh;
47
48
49 //*****************************************************************************
50 // Class MeshDisPart = a sub-part of a distributed mesh.
51 //
52 // It can be :
53 // - a sequential MED file representing a Group (scenario 1)
54 // - a sequential MED file representing a part of a Group (scenario 2 -> MEDSPLITTER)
55 // - a lower resolution of a part (decimation)
56 //*****************************************************************************
57
58 class MeshDisPart
59 {
60
61 public:
62
63     /**
64      * Action to be done for this part on next writing on disk.
65      */
66     enum OnNextWrite
67     {
68         MULTIPR_UNDEFINED,
69         MULTIPR_KEEP_AS_IT,
70         MULTIPR_WRITE_MESH,
71         MULTIPR_WRITE_PARTS
72     };
73     
74 public:
75
76     /**
77      * Builds an empty part of a distributed mesh (default constructor).
78      */
79     MeshDisPart();
80     
81     /**
82      * Destructor. Removes everything.
83      */
84     ~MeshDisPart();
85     
86     /**
87      * Resets this object in its state by default (empty). Cleans memory.
88      */
89     void reset();
90     
91     /**
92      * Creates a MeshDisPart.
93      * \param  pToDoOnNextWrite
94      * \param  pMeshName
95      * \param  pId
96      * \param  pPartName
97      * \param  pPath
98      * \param  pMEDFileName file name excluding the path.
99      * \param  pMesh can be NULL.
100      */
101     void create(
102         OnNextWrite pToDoOnNextWrite,
103         const char* pMeshName, 
104         int         pId,
105         const char* pPartName,
106         const char* pPath,
107         const char* pMEDFileName,
108         Mesh*       pMesh);
109     
110     //---------------------------------------------------------------------
111     // Basic accessors/mutators
112     //---------------------------------------------------------------------
113     
114     /**
115      * Returns the name of this part.
116      * \return the name of this part.
117      */
118     const char* getPartName() const { return mPartName; }
119     
120     /**
121      * Returns the name of the mesh of this part.
122      * \return the name of the mesh of this part.
123      */
124     const char* getMeshName() const { return mMeshName; }
125     
126     /**
127      * Returns the MED filename which contain this part.
128      * \return the MED filename which contain this part.
129      */
130     const char* getMEDFileName() const { return mMEDFileName; }
131     
132     /**
133      * Returns the suffix of the related MED filename (without .med extension).
134      * For examples:
135      * 1. "agregat100grains_12pas_grain97.med"                       -> "grain97"
136      * 2. "agregat100grains_12pas_grain100_part2.med"                -> "grain100_part2"
137      * 3. "aagregat100grains_12pas_grain98_gradmoy-low-25.0-0.3.med" -> "grain98_gradmoy-low-25-0.3"
138      */
139     const char* getMEDFileNameSuffix() const;
140     
141     /**
142      * Returns the action to be performed on this part on next write.
143      * \return the action to be performed on this part on next write.
144      */
145     OnNextWrite getOnNextWrite() const { return mToDoOnNextWrite; }
146      
147     //---------------------------------------------------------------------
148     // I/O
149     //---------------------------------------------------------------------
150     
151     /**
152      * Reads the sequentiel MED file corresponding to this part.
153      * \throw  IOException if an i/o error occurs.
154      */
155     void readMED();
156      
157     /**
158      * Dumps any MeshDisPart to the given output stream.
159      * \param  pOs any output stream.
160      * \param  pM  any MeshDisPart.
161      * \return the output stream pOs.
162      */
163     friend std::ostream& operator<<(std::ostream& pOs, MeshDisPart& pM);
164     
165 private:
166
167     // MeshDisPart can be used:
168     // 1 (KEEP_AS_IT)  : To store data read from one line of an ASCII master file (distributed MED file)
169     // 2 (WRITE_MESH)  : As a temporary structure to store all infos about a mesh corresponding to a group (before writing on disk).
170     // 3 (WRITE_PARTS) : As a temporary structure to store all infos about splitting using MEDSPLITTER.
171     
172     OnNextWrite  mToDoOnNextWrite;               /**< See enum OnNextWrite. */
173     
174     //---------------------------------------------------------------------
175     // Case 1, 2, and 3
176     //---------------------------------------------------------------------        
177     char   mMeshName[MED_TAILLE_NOM + 1];        /**< Name of the mesh. */
178     int    mId;                                  /**< Id of this part in [1..n]. */
179     char   mPartName[MED_TAILLE_NOM + 1];        /**< Name of this part. */
180     char   mPath[256];                           /**< Path of the MED file. */
181     char   mMEDFileName[256];                    /**< Name of the MED file which contain this part. */
182     
183     //---------------------------------------------------------------------
184     // Case 2: mesh of the related sequential MED file (can be NULL if not loaded)
185     //---------------------------------------------------------------------
186     Mesh*  mMesh;                                /**< Mesh associated with this part; can be NULL. */
187     
188     //---------------------------------------------------------------------
189     // Case 3 only: temporary result of MEDSPLITTER
190     //---------------------------------------------------------------------
191     int                          mSplit;         /**< For MEDSPLITTER: number of parts. Temporary. */
192     MEDSPLITTER::MESHCollection* mCollection;    /**< New data after splitting. */
193     MEDSPLITTER::MESHCollection* mOldCollection; /**< Data before splitting (we need them when we want to write new data on disk. */
194     
195 private:
196
197     // do not allow copy constructor
198     MeshDisPart(const MeshDisPart&);
199     
200     // do not allow copy
201     MeshDisPart& operator=(const MeshDisPart&);
202     
203     // do not allow operator ==
204     bool operator==(const MeshDisPart&); 
205     
206     //---------------------------------------------------------------------
207     // Friends
208     //---------------------------------------------------------------------    
209     friend class MeshDis;
210     
211 }; // class MeshDisPart
212
213
214 //*****************************************************************************
215 // Class MeshDis
216 //*****************************************************************************
217
218 class MeshDis
219 {
220 public:
221
222     /**
223      * Builds an empty mesh (default constructor).
224      */
225     MeshDis();
226      
227     /**
228      * Destructor. Removes everything.
229      */
230     ~MeshDis();
231      
232     /**
233      * Resets this object in its state by default (empty). Clean memory.
234      */
235     void reset();
236     
237     //---------------------------------------------------------------------
238     // Basic accessors/mutators
239     //---------------------------------------------------------------------
240
241     /**
242      * Sets the name of the associated sequential MED file (=original MED file).
243      * \param  pFilename name of the associated sequential MED file.
244      */
245     void setSequentialMEDFilename(const char* pFilename);
246     
247     /**
248      * Returns the name of this sequential MED file (=original MED file).
249      * \return the name of this sequential MED file (=original MED file).
250      */
251     const char* getSequentialMEDFilename() const { return mSequentialMEDFilename; }
252        
253     /**
254      * Returns the name of this distributed MED file (=name of the master file).
255      * \return the name of this distributed MED file (=name of the master file).
256      */
257     const char* getDistributedMEDFilename() const { return mDistributedMEDFilename; }
258      
259     /**
260      * Adds a new part to this distributed mesh.
261      * Used by the split process (extract groups).
262      * \param  pToDoOnNextWrite
263      * \param  pMeshName
264      * \param  pId
265      * \param  pPartName
266      * \param  pPath
267      * \param  pMEDFileName
268      * \param  pMesh can be NULL.
269      */
270     void addMesh(
271         MeshDisPart::OnNextWrite pToDoOnNextWrite,
272         const char* pMeshName, 
273         int         pId,
274         const char* pPartName,
275         const char* pPath,
276         const char* pMEDFileName,
277         Mesh*       pMesh);
278     
279     /**
280      * Inserts a new part to this distributed mesh.
281      * Used by the decimation process.
282      * \param  pToDoOnNextWrite
283      * \param  pMeshName
284      * \param  pId
285      * \param  pPartName
286      * \param  pPath
287      * \param  pMEDFileName
288      * \param  pMesh can be NULL.
289      * \param  pPosition insert after this position. Start at 1.
290      */
291     void insertMesh(
292         MeshDisPart::OnNextWrite pToDoOnNextWrite,
293         const char* pMeshName, 
294         int         pId,
295         const char* pPartName,
296         const char* pPath,
297         const char* pMEDFileName,
298         Mesh*       pMesh,
299         int         pPosition);
300     
301     /**
302      * Removes all the part beginning by pPrefixPartName from this distributed mesh.
303      * Example: if pPrefixPartName="PART_4" => remove "PART_4" and all sub-parts "PART_4_*", but not "PART41".
304      * \param  pPrefixPartName name of the part.
305      */
306     void removeParts(const char* pPrefixPartName);
307     
308     /**
309      * Returns the current number of parts in this distributed mesh.
310      * \return the current number of parts in this distributed mesh.
311      */
312     int getNumParts() const { return mParts.size(); }
313     
314     /**
315      * Returns the nth part of this distributed mesh.
316      * \param  pIndex index of the part (in 0..getNumParts()-1).
317      * \return the nth part of this distributed mesh.
318      */
319     MeshDisPart* getPart(int pIndex) const { return mParts[pIndex]; }
320     
321     /**
322      * Returns the list of meshes contained in this distributed MED file.
323      * \return the list of meshes contained in this distributed MED file.
324      */
325     std::vector<std::string> getMeshes() const; 
326     
327     /**
328      * Returns the list of fields contained in this distributed MED file.
329      * \return the list of fields contained in this distributed MED file.
330      */
331     std::vector<std::string> getFields() const; 
332     
333     /**
334      * Returns the number of iteration for a given field.
335      * \param  pFieldName field name.
336      * \return the number of iteration for a given field.
337      */
338     int getTimeStamps(const char* pFieldName) const; 
339     
340     /**
341      * Returns all information about a part.
342      * \param  pPartName name of the part.
343      * \return all information about a part.
344      */
345     std::string getPartInfo(const char* pPartName);
346      
347     //---------------------------------------------------------------------
348     // Algorithms
349     //---------------------------------------------------------------------
350     
351     /**
352      * Finds a part of this distributed mesh by its name.
353      * Returns NULL if the part does not exist.
354      * \param  pPartName part to be found; must not be NULL.
355      * \return a pointer towards the part if it exists, NULL otherwise.
356      * \throw  NullArgumentException if pPartName is NULL.
357      */
358     MeshDisPart* findPart(const char* pPartName);
359     
360     /**
361      * Updates this distributed mesh by splitting one of its part.
362      * This splitting method leans on medsplitter, by V. Bergeaud (CEA).
363      * \param  pPartName     name of the part to be splitted.
364      * \param  pNbParts      number of sub-parts.
365      * \param  pPartitionner MULTIPR_METIS or MULTIPR_SCOTCH.
366      * \throw  RuntimeException if any error occurs.
367      */
368     void splitPart(const char* pPartName, int pNbParts, int pPartitionner);
369     
370     /**
371      * Creates 3 resolution (CURRENT = FULL, MEDIUM and LOW) of a part of this distributed mesh.
372      * Names of new meshes are <original_name>_MED and <original_name>_LOW.
373      * \param  pPartName
374      * \param  pFielName
375      * \param  pFieldIt
376      * \param  pFilterName
377      * \param  pTMed        threshold used to generate MEDIUM resolution.
378      * \param  pTLow        threshold used to generate LOW resolution (must be >= pTMed).
379      * \param  pRadius
380      * \param  pBoxing number of cells along each axis; e.g. if 100 then grid will have 100*100*100 = 10**6 cells; 100 by default.
381      * \throw  RuntimeException if any error occurs.
382      */
383     void decimatePart(
384         const char* pPartName, 
385         const char* pFieldName,
386         med_int     pFieldIt,
387         const char* pFilterName,
388         med_float   pTMed, 
389         med_float   pTLow,
390         med_float   pRadius,
391         int         pBoxing = 100);
392         
393     /**
394      * Returns useful information to configure decimation parameters.
395      * Depends on part, field and filter: generic operation.
396      * \param  pPartName     name of the part.
397      * \param  pFieldName    name of the field used for decimation.
398      * \param  pFieldIt      iteration (time step) of the field.
399      * \param  pFilterName   name of the filter to be used.
400      * \param  pFilterParams params to be used with the filter (depends on filter; this string will be parsed).
401      * \return 
402      */
403     std::string evalDecimationParams(
404         const char* pPartName, 
405         const char* pFieldName, 
406         int         pFieldIt, 
407         const char* pFilterName,
408         const char* pFilterParams);
409     
410     //---------------------------------------------------------------------
411     // I/O
412     //---------------------------------------------------------------------
413     
414     /**
415      * Reads the master file of a distributed MED file.
416      * \param  pMEDfilename
417      * \throw  NullArgumentException if pMEDfilename is NULL.
418      * \throw  IOException if any i/o error occurs.
419      */
420     void readDistributedMED(const char* pMEDfilename);
421     
422     /**
423      * Writes this distributed MED file (including master file and sub MED files if necessary).
424      * \param  pMEDfilenamePrefix
425      * \throw  NullArgumentException if pMEDfilename is NULL.
426      * \throw  IOException if any i/o error occurs.
427      */
428     void writeDistributedMED(const char* pMEDfilenamePrefix);
429     
430     /**
431      * Dumps any MeshDis to the given output stream.
432      * \param  pOs any output stream.
433      * \param  pM  any MeshDis.
434      * \return the output stream pOs.
435      */
436     friend std::ostream& operator<<(std::ostream& pOs, MeshDis& pM);
437     
438 private:
439
440     /**
441      * Recomputes the number of parts in this distributed mesh.
442      * This method is used by writeDistributedMED().
443      * \return the number of parts in this distributed mesh.
444      */
445     int computeNumParts();
446     
447 private:
448
449     char                      mSequentialMEDFilename[256];  /**< Name of the original MED file used to build distribyuted MED. */
450     char                      mDistributedMEDFilename[256]; /**< Name of this distributed MED file (= name of the master file). */
451     std::vector<MeshDisPart*> mParts;                       /**< Table of sub-parts; a distributed mesh is composed of N sub-part, where N = mParts.size(). */
452     //MULTIPR_ProgressCallback*   mProgressCallback;
453     
454 private:
455
456     // do not allow copy constructor
457     MeshDis(const MeshDis&);
458     
459     // do not allow copy
460     MeshDis& operator=(const MeshDis&);
461     
462     // do not allow operator ==
463     bool operator==(const MeshDis&); 
464     
465 }; // class MeshDis
466
467
468 } // namespace MULTIPR
469
470
471 #endif // MULTIPR_MESHDIS_HXX
472
473 // EOF