]> SALOME platform Git repositories - modules/multipr.git/blob - src/MULTIPR/MULTIPR_Family.cxx
Salome HOME
*** empty log message ***
[modules/multipr.git] / src / MULTIPR / MULTIPR_Family.cxx
1 // Project MULTIPR, IOLS WP1.2.1 - EDF/CS
2 // Partitioning/decimation module for the SALOME v3.2 platform
3
4 /**
5  * \file    MULTIPR_Family.cxx
6  *
7  * \brief   see MULTIPR_Family.hxx
8  *
9  * \author  Olivier LE ROUX - CS, Virtual Reality Dpt
10  * 
11  * \date    01/2007
12  */
13
14 //*****************************************************************************
15 // Includes section
16 //*****************************************************************************
17
18 #include "MULTIPR_Family.hxx"
19 #include "MULTIPR_Exceptions.hxx"
20
21 #include <iostream>
22
23 using namespace std;
24
25
26 namespace multipr
27 {
28
29
30 //*****************************************************************************
31 // Class Attributs implementation
32 //*****************************************************************************
33
34 Attributs::Attributs()
35 {
36     mId   = NULL;
37     mVal  = NULL;
38     mDesc = NULL;
39     
40     reset();
41 }
42
43
44 Attributs::~Attributs()
45 {
46     reset();
47 }
48
49
50 Attributs& Attributs::operator=(const Attributs& pAttr)
51 {
52     if (this != &pAttr) // check for self-assignement
53     {
54         reset();
55         
56         mNum = pAttr.mNum;
57         
58         if (mNum < 0) throw IllegalStateException("", __FILE__, __LINE__);
59         
60         if (pAttr.mId != NULL)
61         {
62             mId = new med_int[mNum];
63             memcpy(mId, pAttr.mId, sizeof(med_int) * mNum);
64         }
65         
66         if (pAttr.mVal != NULL)
67         {
68             mVal = new med_int[mNum];
69             memcpy(mVal, pAttr.mVal, sizeof(med_int) * mNum);
70         }
71         
72         if (pAttr.mDesc != NULL)
73         {
74             mDesc = new char[MED_TAILLE_DESC * mNum + 1];
75             memcpy(mDesc, pAttr.mDesc, MED_TAILLE_DESC * mNum + 1);
76         }
77     }
78     
79     return *this;
80 }
81
82
83 void Attributs::reset()
84 {
85     mNum = 0;
86     
87     if (mId   != NULL) { delete[] mId;   mId   = NULL; }
88     if (mVal  != NULL) { delete[] mVal;  mVal  = NULL; }
89     if (mDesc != NULL) { delete[] mDesc; mDesc = NULL; }
90 }
91
92
93 ostream& operator<<(ostream& pOs, Attributs& pA)
94 {
95     if (pA.mNum == 0)
96     {
97         pOs << "NONE" << endl;
98     }
99     else
100     {
101         pOs << endl << "        #attr=" << pA.mNum << endl;
102         
103         if (pA.mId != NULL)
104         {
105             pOs << "        Id  =[";
106             for (int i = 0 ; i < pA.mNum ; i++)
107             {
108                 pOs << pA.mId[i] << " ";
109             }
110             pOs << "]" << endl;
111         }
112         else
113         {
114             pOs << "        Id  =NULL" << endl;
115         }
116         
117         if (pA.mVal != NULL)
118         {
119             pOs << "        Val =[";
120             for (int i = 0 ; i < pA.mNum ; i++)
121             {
122                 pOs << pA.mVal[i] << " ";
123             }
124             pOs << "]" << endl;
125         }
126         else
127         {
128             pOs << "        Val =NULL";
129         }
130         
131         if (pA.mDesc != NULL)
132         {
133             pOs << "        Desc=|" << pA.mDesc << "|" << endl;
134         }
135         else
136         {
137             pOs << "        Desc=NULL" << endl;
138         }
139     }
140     
141     return pOs;
142 }
143
144
145 //*****************************************************************************
146 // Class Family implementation
147 //*****************************************************************************
148
149 Family::Family() 
150 {
151     reset(); 
152 }
153
154
155 Family::~Family()  
156
157     reset();  
158 }
159
160
161 void Family::reset() 
162
163     mName[0]       = '\0';
164     mId            = 0;
165     mStrNameGroups = "";
166     
167     mElt.clear();
168     mNameGroups.clear();
169     mAttributs.reset();
170     
171     mIsFamilyOfNodes = true;
172     
173     mFlagPrintAll = false;
174 }
175
176
177 void Family::insertElt(med_int pIndexElt) 
178
179     if (pIndexElt < 1) throw new IllegalArgumentException("", __FILE__, __LINE__);
180     
181     mElt.insert(pIndexElt); 
182 }
183
184
185 void Family::buildGroups(vector<Group*>& pGroups, map<string, Group*>& pGroupNameToGroup) const
186 {
187     // pGroups / pGroupNameToGroup can be empty or not
188     
189     // for each group in this family
190     for (unsigned itGroup = 0 ; itGroup < mNameGroups.size() ; itGroup++)
191     {
192         const string& keyName = mNameGroups[itGroup];
193         
194         // check if the group already exist
195         map<string, Group*>::iterator it = pGroupNameToGroup.find(keyName);
196         
197         Group* group = NULL;
198         if (it != pGroupNameToGroup.end())
199         {
200             // the group already exists
201             group = (*it).second;
202         }
203         else
204         {
205             // a new group have been identified: create a new entry
206             group = new Group();
207             group->setName(keyName);
208             group->setIsGroupOfNodes(isFamilyOfNodes());
209             
210             pGroups.push_back(group);
211             pGroupNameToGroup.insert(make_pair(keyName, group));
212         }
213         
214         // add all elements of the this family to the group
215         for (set<med_int>::iterator itElt = mElt.begin() ; itElt != mElt.end() ; itElt++)
216         {
217             group->insertElt(*itElt);
218         }
219         
220     }
221 }
222
223
224 Family* Family::extractGroup(const char* pGroupName)
225 {
226     Family* family = new Family();
227     
228     strcpy(family->mName, mName);
229     family->mId = mId;
230     family->mAttributs = mAttributs;
231     
232     if (pGroupName == NULL)
233     {
234         family->mStrNameGroups = mStrNameGroups;
235         family->mNameGroups = mNameGroups;
236     }
237     else
238     {
239         if (strlen(pGroupName) > MED_TAILLE_LNOM) throw IllegalArgumentException("", __FILE__, __LINE__);
240         if (strlen(pGroupName) == 0) throw IllegalArgumentException("", __FILE__, __LINE__);
241         
242         if (strstr(mStrNameGroups.c_str(), pGroupName) == 0)
243         {
244             // pGroupName found in the list of groups => just keep pGroupName
245             family->mStrNameGroups = mStrNameGroups;
246             family->mNameGroups = mNameGroups;
247         }
248         else
249         {
250             // pGroupName not found in the current list of groups 
251             // probably not a group of the same nature => keep all the groups
252             family->mStrNameGroups = pGroupName;
253             family->mNameGroups.push_back(pGroupName);
254         }
255     }
256     
257     return family;
258 }
259
260
261 void Family::readMED(med_idt pMEDfile, char* pMeshName, med_int pIndex)
262 {
263     if (pMEDfile == 0) throw IOException("", __FILE__, __LINE__);
264     if (pMeshName == NULL) throw NullArgumentException("", __FILE__, __LINE__);
265     if (strlen(pMeshName) > MED_TAILLE_NOM) throw IllegalArgumentException("", __FILE__, __LINE__);
266     if (pIndex < 1) throw IllegalArgumentException("", __FILE__, __LINE__);
267     
268     reset();
269     
270     med_int numGroups = MEDnGroupe(pMEDfile, pMeshName, pIndex);
271     
272     if (numGroups < 0) throw IOException("i/o error while reading number of groups in MED file", __FILE__, __LINE__);
273     
274     med_int numAttr = MEDnAttribut(pMEDfile, pMeshName, pIndex);
275     
276     med_int* attrId   = new med_int[numAttr];
277     med_int* attrVal  = new med_int[numAttr];
278     char*    attrDesc = new char[MED_TAILLE_DESC * numAttr + 1];
279     attrDesc[0] = '\0';
280     
281     char* nameGroups = new char[MED_TAILLE_LNOM * numGroups + 1];
282     nameGroups[0] = '\0';
283     
284     med_err ret = MEDfamInfo(
285         pMEDfile, 
286         pMeshName, 
287         pIndex, 
288         mName, 
289         &mId, 
290         attrId, 
291         attrVal, 
292         attrDesc, 
293         &numAttr, 
294         nameGroups, 
295         &numGroups);
296     
297     if (ret != 0) throw IOException("i/o error while reading family information in MED file", __FILE__, __LINE__);
298     
299     attrDesc[MED_TAILLE_DESC * numAttr] = '\0';
300     
301     mAttributs.mNum  = numAttr;
302     mAttributs.mId   = attrId;
303     mAttributs.mVal  = attrVal;
304     mAttributs.mDesc = attrDesc;
305     
306     mStrNameGroups = nameGroups;
307     
308     // split nameGroups
309     for (int itGroup = 0 ; itGroup < numGroups ; itGroup++)
310     {
311         char str[MED_TAILLE_LNOM + 1];
312         strncpy(str, nameGroups + itGroup * MED_TAILLE_LNOM, MED_TAILLE_LNOM);
313         str[MED_TAILLE_LNOM] = '\0';
314         mNameGroups.push_back(str);
315     }
316     
317     delete[] nameGroups;
318     
319     // MEDfamLire is not necessary as we used MEDnoeudsLire/MEDelementsLire instead
320 }
321
322
323 void Family::writeMED(med_idt pMEDfile, char* pMeshName)
324 {
325     if (pMEDfile == 0) throw IOException("", __FILE__, __LINE__);
326     if (pMeshName == NULL) throw NullArgumentException("", __FILE__, __LINE__);
327     if (strlen(pMeshName) > MED_TAILLE_NOM) throw IllegalArgumentException("", __FILE__, __LINE__);
328     if (strlen(mName) > MED_TAILLE_NOM) throw IllegalArgumentException("", __FILE__, __LINE__);
329     if (mAttributs.mVal == NULL) throw IllegalStateException("", __FILE__, __LINE__);
330     if (mAttributs.mDesc == NULL) throw IllegalStateException("", __FILE__, __LINE__);
331     if (mAttributs.mId == NULL) throw IllegalStateException("", __FILE__, __LINE__);
332         
333     med_err ret = MEDfamCr(
334         pMEDfile,
335         pMeshName,
336         mName,
337         mId,
338         mAttributs.mId,
339         mAttributs.mVal,
340         mAttributs.mDesc,
341         mAttributs.mNum,
342         const_cast<char*>(mStrNameGroups.c_str()),
343         mNameGroups.size());
344     
345     if (ret != 0) throw IOException("i/o error while creating family in MED file", __FILE__, __LINE__);
346     
347     // MEDfamEcr is not necessary as we used MEDnoeudsEcr/MEDelementsEcr instead
348
349 }
350
351
352 ostream& operator<<(ostream& pOs, Family& pF)
353 {
354     pOs << "Family: " << endl;
355     pOs << "    Name      =|" << pF.mName << "| size=" << strlen(pF.mName) << endl;
356     pOs << "    Id        =" << pF.mId << endl;
357     pOs << "    Family of =" << (pF.isFamilyOfNodes()?"NODES":"ELEMENTS") << endl;    
358     
359     pOs << "    Groups: #groups=" << pF.mNameGroups.size() << endl;
360     for (unsigned itGroup = 0 ; itGroup < pF.mNameGroups.size() ; itGroup++)
361     {
362         pOs << "        Group " << (itGroup + 1) << ": |" << pF.mNameGroups[itGroup] << "| size=" << pF.mNameGroups[itGroup].length() << endl;
363     }
364     pOs << "    Attributs: " << pF.mAttributs;
365     
366     if (pF.mElt.size() != 0)
367     {
368         set<med_int>::iterator itSet = pF.mElt.end();
369         itSet--;
370         pOs << "    Elements: #elt=" << pF.mElt.size() << " min_id=" << (*(pF.mElt.begin())) << " max_id=" << (*itSet) << endl;
371         if (pF.mFlagPrintAll)
372         {
373             pOs << "        ";
374             for (set<med_int>::iterator itSet = pF.mElt.begin() ; itSet != pF.mElt.end() ; itSet++)
375             {
376                 pOs << (*itSet) << " ";
377             }
378             pOs << endl;
379         }
380     }
381     else
382     {
383         pOs << "    Elements: #elt=0" << endl;
384     }
385     
386     return pOs;
387 }
388
389
390 //*****************************************************************************
391 // Class Group implementation
392 //*****************************************************************************
393
394 Group::Group() 
395 {
396     reset(); 
397 }
398
399
400 Group::~Group()  
401
402     reset();  
403 }
404
405
406 void Group::reset() 
407
408     mName = "";
409     mElt.clear();
410     mIsGroupOfNodes = true;
411     
412     mFlagPrintAll = false;
413 }
414
415
416 void Group::setName(const string& pName) 
417
418     if (pName.length() > MED_TAILLE_LNOM) throw IllegalArgumentException("", __FILE__, __LINE__);
419     
420     mName = pName; 
421 }
422
423
424 void Group::insertElt(med_int pIndexElt) 
425
426     if (pIndexElt < 1) throw IllegalArgumentException("", __FILE__, __LINE__);
427     
428     mElt.insert(pIndexElt); 
429 }
430
431 ostream& operator<<(ostream& pOs, Group& pG)
432 {
433     pOs << "Group: " << endl;
434     pOs << "    Name     =|" << pG.mName << "| size=" << pG.mName.length() << endl;
435     pOs << "    Group of =" << (pG.isGroupOfNodes()?"NODES":"ELEMENTS") << endl;    
436
437     if (pG.mElt.size() != 0)
438     {
439         set<med_int>::iterator itSet = pG.mElt.end();
440         itSet--;
441         pOs << "    Elements: #elt=" << pG.mElt.size() << " min_id=" << (*(pG.mElt.begin())) << " max_id=" << (*itSet) << endl;
442         if (pG.mFlagPrintAll)
443         {
444             pOs << "        ";
445             for (set<med_int>::iterator itSet = pG.mElt.begin() ; itSet != pG.mElt.end() ; itSet++)
446             {
447                 pOs << (*itSet) << " ";
448             }
449             pOs << endl;
450         }
451     }
452     else
453     {
454         pOs << "    Elements: #elt=0" << endl;
455     }
456     
457     return pOs;
458 }
459
460
461 } // namespace  multipr
462
463 // EOF