Salome HOME
Merge from BR_V5_DEV 16Feb09
[modules/med.git] / src / MULTIPR / MULTIPR_Obj.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_GaussLoc.hxx
23  *
24  * \brief   Class MULTIPR_Obj. 
25  *          This class is used as an interface to implement MULTIPR services in the salome MODULE 
26  *          as described in the spec/design doc.
27  *
28  * \author  Olivier LE ROUX - CS, Virtual Reality Dpt
29  * 
30  * \date    01/2007
31  */
32
33 #ifndef MULTIPR_OBJ_HXX
34 #define MULTIPR_OBJ_HXX
35
36 //*****************************************************************************
37 // Includes section
38 //*****************************************************************************
39
40 #include <iostream>
41 #include <string>
42 #include <vector>
43 #include <list>
44
45 #include <boost/thread/recursive_mutex.hpp>
46
47 #include "MULTIPR_Globals.hxx"
48
49 namespace multipr
50 {
51
52 class MeshDis;
53 class Group;
54 class Profil;
55
56 //*****************************************************************************
57 // Class Obj
58 //*****************************************************************************
59
60 enum ObjState
61 {
62     MULTIPR_OBJ_STATE_ERROR,
63     MULTIPR_OBJ_STATE_RESET,
64     MULTIPR_OBJ_STATE_SEQ_INIT,
65     MULTIPR_OBJ_STATE_SEQ,
66     MULTIPR_OBJ_STATE_DIS,
67     MULTIPR_OBJ_STATE_DIS_MEM
68 }; // enum ObjState
69
70
71 class Obj
72 {
73 public:
74
75     /** 
76      * Builds an empty Gauss reference (default constructor).
77      */
78     Obj();
79     
80     /**
81      * Destructor. Removes everything.
82      */
83     ~Obj();
84     
85     /**
86      * Resets this object in its state by default (empty). Cleans memory.
87      */
88     void reset();
89     
90     /**
91      * Associate a MED file (sequential or distributed) with this object.
92      * This method also:
93      * - reset everything before starting
94      * - determine if the given file is a sequential (SEQ) or a distributed (DIS) MED file
95      * - read the ASCII master file if it is a distributed MED file
96      * - set state
97      */
98     void create(const char* pMEDfilename);
99      
100     //---------------------------------------------------------------------
101     // Basic accessors/mutators
102     //--------------------------------------------------------------------
103     
104     /**
105      * Returns true iff this obj represents a valid sequential MED file.
106      * \return true iff this obj represents a valid sequential MED file.
107      */
108     bool isValidSequentialMEDFile() const { return (mState == MULTIPR_OBJ_STATE_SEQ) || (mState == MULTIPR_OBJ_STATE_SEQ_INIT); }
109     
110     /**
111      * Returns true iff this obj represents a valid distributed MED file.
112      * \return true iff this obj represents a valid distributed  MED file.
113      */
114     bool isValidDistributedMEDFile() const { return (mState == MULTIPR_OBJ_STATE_DIS) || (mState == MULTIPR_OBJ_STATE_DIS_MEM); }
115      
116     /**
117      * Returns the name of the associated MED file.
118      * \return the name of the associated MED file.
119      */
120     std::string getMEDFilename() const { return mMEDfilename; }
121     
122     /**
123      * Returns the name of the associated sequential MED file.
124      * \return the name of the associated sequential MED file.
125      */
126     std::string getSequentialMEDFilename() const;
127     
128     /**
129      * Defines the mesh to be processed.
130      * \param  pMeshName name of the mesh to be partitionned.
131      */
132     void setMesh(const char* pMeshName);
133      
134     /**
135      * Returns the name of mesh, defined via setMesh().
136      * \return the name of mesh, defined via setMesh().
137      */
138     std::string getMeshName() const { return mMeshName; }
139     
140     /**
141      * Returns the list of meshes contained in the sequential MED file.
142      * Assumes this object encapsulates a sequential MED file.
143      * \return the list of meshes contained in the sequential MED file.
144      */
145     std::vector<std::string> getMeshes() const;
146     
147     /**
148      * Returns the list of fields contained in the sequential MED file.
149      * Assumes this object encapsulates a sequential MED file.
150      * \param pPartList The list of parts to get the fields from (separator is '|').
151      * \return the list of fields contained in the sequential MED file.
152      */
153     std::vector<std::string> getFields(const char* pPartList) const;
154     
155     /**
156      * Returns the number of timestamps for a given field.
157      * Assumes this object encapsulates a sequential MED file.
158      * \param  pFieldName name of any field.
159      * \param pPartList The list of parts to get the time stamps from (separator is '|').        
160      * \return the number of timestamps for a given field; 0 if field not found.
161      */
162     int getTimeStamps(const char* pPartList, const char* pFieldName) const;
163
164     /**
165      * Get the minimum and maximum value of a part's field.
166      * \param pPartName The name of the part.
167      * \param pFieldName The name of the field.
168      * \param pMin The mininum value to fill.
169      * \param pMax The maxinum value to fill.
170      */
171     void getFieldMinMax(const char* pPartName, const char* pFieldName, float& pMin, float& pMax);
172         
173     /**
174      * Returns the name of all partitions.
175      * Assumes this object encapsulates a distributed MED file.
176      * \return the name of all partitions.
177      */
178     std::vector<std::string> getParts() const;
179     
180     /**
181      * Returns all information about a part.
182      * \param  pPartName name of the part.
183      * \return all information about a part.
184      */
185     std::string getPartInfo(const char* pPartName) const;
186     
187     /**
188      * Removes all the part beginning by pPrefixPartName from the distributed MED file.
189      * Example: if pPrefixPartName="PART_4" => remove "PART_4" and all sub-parts "PART_4_*", but not "PART41".
190      * Assume this object encapsulates a distributed MED file.
191      * \param  pPrefixPartName name of the part.
192      */
193     void removeParts(const char* pPrefixPartName);
194     
195       
196     //---------------------------------------------------------------------
197     // Algorithms
198     //--------------------------------------------------------------------
199     
200     /**
201      * Creates a distributed MED file (v2.3) by extracting all the groups from the current mesh of the current MED sequential MED file.
202      *         Assumes:
203      *         - the file is in MED format and can be read using MED file v2.3.
204      *         - the file is sequential (not a distributed MED).
205      *         - the file only contains TETRA10 elements (dimension of space and mesh is 3).
206      *         - the file have no profil.
207      * \return the name of each part.
208      * \throw  RuntimeException if any error occurs.
209      */
210     std::vector<std::string> partitionneDomaine();
211     
212     /** 
213      * Creates a distributed MED file (V2.3) by splitting a group of a MED file previously created by partitionneDomaine.
214      *         Assumes:
215      *         - the file is a distributed MED file, previously created by partitionneDomaine()
216      *           (=> each part only contain 1 mesh, TETRA10 elements only)
217      *         - nbPart > 1
218      * \param  pPartName     name of the part to be splitted.
219      * \param  pNbParts      number of parts; must be > 1.
220      * \param  pPartitionner use value 0=MULTIPR_METIS for Metis or 1=MULTIPR_SCOTCH for Scotch.
221      * \return the name of each part.
222      * \throw  RuntimeException if any error occurs.
223      */
224     std::vector<std::string> partitionneGroupe(
225         const char* pPartName, 
226         int         pNbParts, 
227         int         pPartitionner=0);
228     
229     /**
230      * Creates 3 resolutions of the given part of a distributed MED file (V2.3).
231      *         Assumes:
232      *         - the file is a distributed MED file, previously created by partitionneDomaine() or partitionneGroupe()
233      *           (=> each part only contain 1 mesh, TETRA10 elements only)
234      * \param  pPartName    name of the part to be decimated.
235      * \param  pFieldName   name of the field used for decimation.
236      * \param  pFieldIt     iteration (time step) of the field.
237      * \param  pFilterName  name of the filter to be used.
238      * \param  pFilterParams params to be used with the filter (depends on filter; this string will be parsed).
239      * \return the name of each part.
240      * \throw  RuntimeException if any error occurs.
241      */
242     std::vector<std::string> decimePartition(
243         const char* pPartName,
244         const char* pFieldName,
245         int         pFieldIt,
246         const char* pFilterName,
247         const char* pFilterParam);
248
249     /**
250      * Works exactly like the above method and has the same parameters
251      * and returning value meaning, except the last additional parameter.
252      * \param  pEmptyMeshes list of names of empty meshes, corresponding to medium and/or lower resolution.
253      */
254     std::vector<std::string> decimePartition(
255         const char* pPartName,
256         const char* pFieldName,
257         int         pFieldIt,
258         const char* pFilterName,
259         const char* pFilterParam,
260         std::list<std::string>& pEmptyMeshes);
261
262     /**
263      * Returns useful information to configure decimation parameters.
264      * Depends on part, field and filter: generic operation.
265      * \param  pPartName     name of the part.
266      * \param  pFieldName    name of the field used for decimation.
267      * \param  pFieldIt      iteration (time step) of the field.
268      * \param  pFilterName   name of the filter to be used.
269      * \param  pFilterParams params to be used with the filter (depends on filter; this string will be parsed).
270      */
271     std::string evalDecimationParams(
272         const char* pPartName, 
273         const char* pFieldName, 
274         int         pFieldIt, 
275         const char* pFilterName,
276         const char* pFilterParams);
277     
278         /**
279          * Get mesh statistics.
280          * \param pStats [the number of mesh] space [number of gauss points]
281          * \param pPartName The path to the part.
282          */
283         void getMEDInfo(char* pStats, char* pPartName);
284         
285     //---------------------------------------------------------------------
286     // I/O
287     //---------------------------------------------------------------------
288     
289     /**
290      * Saves the associated MED file if necessary.
291      * \param  pPath path where to save the file.
292      * \throw  IOException if any i/o error occurs.
293      */
294     void save(const char* pPath);
295
296     /**
297      * Reset save progress to zero.
298      * \param pPercents current save progress in percents.
299      */
300     void resetProgress();
301
302     /**
303      * Obtain save progress.
304      * \return current save progress in percents.
305      */
306     int getProgress();
307
308     /**
309      * Saves the associated MED file to the given location.
310      * Calling this method does not influence the object state.
311      *
312      * \note This method is mentioned to be used only in persistence.
313      *
314      * \param  pPath path where to save the file.
315      * \throw  IOException if any i/o error occurs.
316      */
317     void savePersistent(const char* pPath);
318
319     /**
320      * Works like \a create(), but assumes that the distributed MED file was moved
321      * from the original location and its ASCII master file needs to be updated.
322      *
323      * \note This method is mentioned to be used only in persistence.
324      */
325     void restorePersistent(const char* pMEDfilename);
326     
327     /**
328      * Dumps any Obj to the given output stream.
329      * \param  pOs any output stream.
330      * \param  pO  any Obj.
331      * \return the output stream pOs.
332      */
333     friend std::ostream& operator<<(std::ostream& pOs, Obj& pO);
334     
335 private:
336
337     /**
338      * Returns the list of parts contained in the current distributed mesh.
339      * \return the list of parts contained in the current distributed mesh.
340      * \throw  IllegalStateException if the distributed mesh does not still exist.
341      */
342     std::vector<std::string> getListParts() const;
343
344 private:
345     
346     std::string            mMEDfilename;      /**< Name of the MED file: sequential or distributed. */
347     std::string            mMeshName;         /**< Mesh to be partitionned. */
348     ObjState               mState;            /**< State of this object. */
349     MeshDis*               mMeshDis;          /**< Distributed mesh. */
350     bool                   mDoReadWriteFields;/**< Flag for optimized domain split. */
351     std::vector<Group*>    mGroups;           /**< We need to keep the groups for optimized domain split. */
352     GaussIndexList         mGaussList;        /**< We need to keep gauss information for optimized domain split. */
353     std::vector<Profil*>   mProfils;          /**< We need to keep the profiles for optimized domain split. */
354     boost::recursive_mutex mWriteMutex;       /**< Write progress thread safe access. */
355
356     std::string            mPrevPath;
357
358 private:
359
360     // do not allow copy constructor
361     Obj(const Obj&);
362     
363     // do not allow copy
364     Obj& operator=(const Obj&);
365     
366     // do not allow operator ==
367     bool operator==(const Obj&); 
368     
369 }; // class Obj
370
371
372 } // namespace MULTIPR
373
374
375 #endif // MULTIPR_OBJ_HXX
376
377 // EOF