Salome HOME
adding a new test for makeMesh method.
[modules/med.git] / src / MULTIPR / MULTIPR_Profil.cxx
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_Profil.cxx
23  *
24  * \brief   see MULTIPR_Profil.hxx
25  *
26  * \author  Olivier LE ROUX - CS, Virtual Reality Dpt
27  * 
28  * \date    01/2007
29  */
30
31 //*****************************************************************************
32 // Includes section
33 //*****************************************************************************
34
35 #include "MULTIPR_Profil.hxx"
36 #include "MULTIPR_Exceptions.hxx"
37 #include "MULTIPR_Mesh.hxx"
38
39 #include <iostream>
40
41 using namespace std;
42
43
44 namespace multipr
45 {
46
47
48 //*****************************************************************************
49 // Class Profil implementation
50 //*****************************************************************************
51
52 Profil::Profil() 
53 {
54     reset(); 
55 }
56
57 Profil::Profil(const Profil& pProfil)
58 {
59     strcpy(mName, pProfil.mName);
60     mTable = pProfil.mTable;
61     mBinding = pProfil.mBinding;
62     mGeomIdx = pProfil.mGeomIdx;
63 }
64
65 Profil::~Profil()  
66
67     reset();  
68 }
69
70
71 void Profil::reset() 
72
73     mName[0] = '\0'; 
74     mTable.clear();
75     mBinding = Undef;
76     mGeomIdx = 0;
77 }
78
79
80 void Profil::create(const char* pName)
81 {
82     if (pName == NULL) throw NullArgumentException("", __FILE__, __LINE__);
83     
84     reset();
85     strcpy(mName, pName);
86 }
87
88
89
90 const char* Profil::getName() const
91 {
92     return mName;
93 }
94
95 void Profil::add(med_int pElt) 
96 {
97     mTable.insert(pElt); 
98 }
99
100 bool    Profil::find(med_int pElt)
101 {
102     if (mTable.find(pElt) != mTable.end())
103     {
104         return true;
105     }
106     else
107     {
108         return false;
109     }
110 }
111
112 void    Profil::filterSetOfElement(std::set<med_int>& pIn, std::set<med_int>& pOut)
113 {
114     if (&pOut == &pIn) throw IllegalStateException("pIn and pOut must be different !", __FILE__, __LINE__);
115     int count = 1;
116
117     for (std::set< med_int>::iterator it = mTable.begin(); it != mTable.end(); ++it)
118     {
119         if (pIn.find(*it) != pIn.end())
120         {
121             pOut.insert(count);
122         }
123         ++count;
124     }
125 }
126
127 void    Profil::extractSetOfElement(const std::set<med_int>& pIn, std::set<med_int>& pOut)
128 {
129     if (&pOut == &pIn) throw IllegalStateException("pIn and pOut must be different !", __FILE__, __LINE__); 
130     int count = 1;
131     
132     for (std::set< med_int>::iterator it = pIn.begin(); it != pIn.end(); ++it)
133     {
134         if (mTable.find(*it) != mTable.end())
135         {
136             pOut.insert(count);
137         }
138         ++count;
139     }
140 }
141
142 void Profil::readMED(med_idt pMEDfile, med_int pIndexProfil)
143 {
144     if (pMEDfile == 0) throw IOException("", __FILE__, __LINE__);
145     if (pIndexProfil < 1) throw IllegalArgumentException("", __FILE__, __LINE__);
146     
147     reset();
148
149     // Get the profil info.
150     med_int numData;
151     med_err ret = MEDprofilInfo(
152         pMEDfile, 
153         pIndexProfil, 
154         mName, 
155         &numData);
156     if (ret != 0) throw IOException("", __FILE__, __LINE__);
157
158     // Read the data of the profil.    
159     med_int* dataTmp = new med_int[numData];
160     ret = MEDprofilLire(
161         pMEDfile, 
162         dataTmp, 
163         mName);
164     if (ret != 0) throw IOException("", __FILE__, __LINE__);
165     for (int itData = 0 ; itData < numData ; itData++)
166     {
167         mTable.insert(dataTmp[itData]);
168     }
169     
170     delete[] dataTmp;
171 }
172
173 void    Profil::readProfilBinding(med_idt pMEDfile, char* pMeshName)
174 {
175     if (strlen(mName) == 0) throw IllegalStateException("The name of the Profil is empty", __FILE__, __LINE__); 
176
177     int             nbField;
178     med_err         ret;
179     char            cha[MED_TAILLE_NOM + 1];
180     med_type_champ  type;
181     char*           comp;
182     char*           unit;
183     med_int         numComponents;
184     char            gaussLocName[MED_TAILLE_NOM + 1];
185     char            profilName[MED_TAILLE_NOM + 1];
186     int             sizeOfData;
187     int             sizeOfType;
188     unsigned char*  fieldData;
189     bool            fieldOnNodes = false;
190     med_entite_maillage     entity;
191     med_geometrie_element   geom;
192     med_int                 ngauss;
193     med_int                 numdt;
194     med_int                 numo;
195     char                    dtunit[MED_TAILLE_PNOM + 1];
196     med_float               dt;
197     char                    maa[MED_TAILLE_NOM + 1];
198     med_booleen             local;
199     med_int                 nmaa;
200     int                     geomIdx = 0;
201     
202     // Get the number of field in this file.
203     nbField = MEDnChamp(pMEDfile, 0);
204     if (nbField < 0) throw IOException("Can't read number of fields.", __FILE__, __LINE__);
205     // For each field.
206     for (int i = 1; i <= nbField; ++i)
207     {
208         // Get the number of component.
209         numComponents = MEDnChamp(pMEDfile, i);
210         comp = new char[numComponents * MED_TAILLE_PNOM + 1];
211         unit = new char[numComponents * MED_TAILLE_PNOM + 1];
212         // Get some information about the field.
213         ret = MEDchampInfo(pMEDfile, i, cha, &type, comp, unit, numComponents);
214         if (nbField < 0) throw IOException("Can't read fields info.", __FILE__, __LINE__);
215         // Get the size of one component.
216         switch (type)
217         {
218             case MED_FLOAT64: sizeOfType = 8; break;
219             case MED_INT64: sizeOfType = 8; break;
220             case MED_INT32: sizeOfType = 4; break;
221             case MED_INT: sizeOfType = 4; break;
222             default: throw IllegalStateException("Unknown field data type", __FILE__, __LINE__);
223         }
224
225         // Try to figure out if the field is on nodes or on elements.
226         med_int numTimeStepNodes = MEDnPasdetemps(
227             pMEDfile, 
228             cha, 
229             MED_NOEUD, 
230             (med_geometrie_element) 0);
231
232         if (numTimeStepNodes < 0) throw IOException("Can't read fields number of time steps.", __FILE__, __LINE__);
233         if (numTimeStepNodes > 0)
234         {
235             // Its on nodes.
236             fieldOnNodes = true;
237             entity = MED_NOEUD;
238             geom = (med_geometrie_element) 0;
239         }
240         else
241         {
242             // Its on elements.
243             fieldOnNodes = false;
244             entity = MED_MAILLE;
245             // Get the geometry.
246             for (int i = 0; i < eMaxMedMesh; ++i)
247             {
248                 if (MEDnPasdetemps(pMEDfile, cha, entity, CELL_TYPES[i]) > 0)
249                 {
250                     geom = CELL_TYPES[i];
251                     geomIdx = i;
252                     break;
253                 }
254             }
255         }
256
257         // Get some information about the first time step.
258         ret = MEDpasdetempsInfo(
259             pMEDfile, 
260             cha, 
261             entity, 
262             geom, 
263             1, 
264                         &ngauss, 
265             &numdt, 
266             &numo, 
267             dtunit, 
268             &dt, 
269             maa, 
270             &local, 
271             &nmaa);
272         if (ret < 0) throw IOException("Can't read fields time steps info.", __FILE__, __LINE__);
273         // Get the number of values for the first time step.
274         med_int nval = MEDnVal(
275             pMEDfile,
276             cha,
277             entity,
278             geom,
279             numdt,
280             numo,
281             pMeshName,
282             MED_GLOBAL);
283         if (nval < 0) throw IOException("Can't read fields number values.", __FILE__, __LINE__);
284         // Read the one time step of the field.                   
285         sizeOfData = sizeOfType * numComponents * nval * 10;
286         unsigned char* fieldData = new unsigned char[sizeOfData];
287         gaussLocName[0] = '\0';
288         ret = MEDchampLire(
289             pMEDfile,
290             pMeshName,
291             cha,
292             fieldData,
293             MED_FULL_INTERLACE,
294             MED_ALL,
295             gaussLocName,
296             profilName,
297             MED_GLOBAL,
298             entity,
299             geom,
300             numdt,
301             numo);
302         delete[] fieldData;
303         if (ret < 0) throw IOException("Can't read field.", __FILE__, __LINE__);
304         // Does this field use our profile ?
305         if (strncmp(profilName, mName, MED_TAILLE_NOM) == 0)
306         {
307             // It does !
308             if (fieldOnNodes)
309             {
310                 mBinding = OnNodes;
311                 mGeomIdx = geomIdx;
312             }
313             else
314             {
315                 mBinding = OnElements;
316                 mGeomIdx = geomIdx;
317             }
318             break;
319         }
320     }
321 }
322
323 void Profil::writeMED(med_idt pMEDfile)
324 {
325     if (pMEDfile == 0) throw IOException("pMEDfile is 0", __FILE__, __LINE__);
326     if (strlen(mName) > MED_TAILLE_NOM) throw IllegalStateException("Empty name", __FILE__, __LINE__);
327     if (mTable.size() == 0) throw IllegalStateException("Empty table", __FILE__, __LINE__);
328     int itData;
329     std::set<med_int>::iterator it;
330     med_int* dataTmp = new med_int[mTable.size()];
331     for (it = mTable.begin(), itData = 0; it != mTable.end(); ++it, ++itData)
332     {
333         dataTmp[itData] = *it;
334     }
335     med_err ret = MEDprofilEcr(
336         pMEDfile,
337         dataTmp,
338         mTable.size(),
339         mName);
340
341     if (ret != 0) throw IOException("Can't write profil", __FILE__, __LINE__);
342     
343     delete[] dataTmp;
344 }
345
346
347 ostream& operator<<(ostream& pOs, Profil& pP)
348 {
349     pOs << "Profil:" << endl;
350     pOs << "    Name=|" << pP.mName << "|" << endl;
351     pOs << "    Size=" << pP.mTable.size() << endl;
352     
353     pOs << "    Entities=[";
354     for (std::set<med_int>::iterator it = pP.mTable.begin();
355      it != pP.mTable.end(); ++it)
356     {
357         pOs << *it << " ";
358     }
359     pOs << "]";
360     
361     return pOs;
362 }
363
364
365 } // namespace  multipr
366
367 // EOF