]> SALOME platform Git repositories - modules/multipr.git/blob - src/MULTIPR/MULTIPR_Elements.cxx
Salome HOME
*** empty log message ***
[modules/multipr.git] / src / MULTIPR / MULTIPR_Elements.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_Elements.cxx
6  *
7  * \brief   see MULTIPR_Elements.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_Elements.hxx"
19 #include "MULTIPR_Nodes.hxx"
20 #include "MULTIPR_Exceptions.hxx"
21
22 #include <iostream>
23 #include <set>
24 #include <map>
25
26 using namespace std;
27
28
29 namespace multipr
30 {
31
32
33 //*****************************************************************************
34 // Class Elements implementation
35 //*****************************************************************************
36
37 Elements::Elements() 
38 {
39     mId       = NULL;
40     mFamIdent = NULL;
41     mNames    = NULL;
42     mCon      = NULL;
43     
44     reset(); 
45 }
46
47
48 Elements::~Elements()  
49
50     reset();  
51 }
52
53
54 void Elements::reset() 
55
56     mNum           = 0;
57     mEntity        = MED_MAILLE;
58     mGeom          = MED_NONE;
59     mNumNodesByElt = 0;
60     mDim           = 0;
61     
62     if (mId != NULL)       { delete[] mId;       mId       = NULL; }
63     if (mFamIdent != NULL) { delete[] mFamIdent; mFamIdent = NULL; }
64     if (mNames != NULL)    { delete[] mNames;    mNames    = NULL; }
65     if (mCon != NULL)      { delete[] mCon;      mCon      = NULL; }
66
67     mSetOfNodes.clear();
68     
69     mFlagPrintAll = false;
70 }
71
72
73 med_int Elements::getFamilyIdentifier(med_int pIndex) const 
74
75     if ((pIndex < 0) || (pIndex >= mNum)) throw IndexOutOfBoundsException("", __FILE__, __LINE__);
76     
77     return mFamIdent[pIndex]; 
78 }
79
80
81 const med_int* Elements::getConnectivity(int pIndex) const
82 {
83     if ((pIndex < 0) || (pIndex >= mNum)) throw IndexOutOfBoundsException("", __FILE__, __LINE__);
84     
85     return mCon + mNumNodesByElt * pIndex;
86 }
87
88
89 void Elements::getCoordinates(med_int pIndexElt, const Nodes* pNodes, med_float* pCoo, int pFirst) const
90 {
91     if ((pIndexElt < 0) || (pIndexElt >= mNum)) throw IndexOutOfBoundsException("", __FILE__, __LINE__);
92     if (pNodes == NULL) throw NullArgumentException("", __FILE__, __LINE__);
93     if (pCoo == NULL) throw NullArgumentException("", __FILE__, __LINE__);
94     
95     // get the list of nodes of the element
96     const med_int* con = getConnectivity(pIndexElt);
97     
98     med_float* destCoo = pCoo;
99     int size = sizeof(med_float) * mDim;
100     
101     // for each node of the element
102     int n = (mNumNodesByElt < pFirst) ? mNumNodesByElt : pFirst;
103     for (int i = 0 ; i < n ; i++)
104     {
105         // get index of node (MED index start at 1)
106         med_int indexNode = con[i] - 1;
107         
108         // get coordinates of this node
109         const med_float* srcCoo = pNodes->getCoordinates(indexNode);
110         
111         // copy coordinates to destCoo
112         memcpy(destCoo, srcCoo, size);
113         
114         // prepare next point
115         destCoo += mDim;
116     }
117 }
118
119
120 Elements* Elements::extractSubSet(const set<med_int>& pSetIndices) const
121 {
122     Elements* subset = new Elements();
123     
124     //---------------------------------------------------------------------
125     // Copy parameters
126     //---------------------------------------------------------------------
127     subset->mNum           = pSetIndices.size();
128     subset->mEntity        = mEntity;
129     subset->mGeom          = mGeom;          // e.g. 310 for a TETRA10
130     subset->mNumNodesByElt = mNumNodesByElt; // e.g. 10 for a TETRA10
131     subset->mDim           = mDim;           // e.g. 3 for a TETRA10
132     
133     //---------------------------------------------------------------------
134     // Allocate arrays
135     //---------------------------------------------------------------------
136     subset->mFamIdent     = new med_int[subset->mNum];
137     subset->mCon          = new med_int[mNumNodesByElt * subset->mNum];
138     
139     //---------------------------------------------------------------------
140     // Copy subset of familys id and connectivity.
141     //---------------------------------------------------------------------
142     med_int* destCon = subset->mCon;
143     set<med_int>::iterator itSet = pSetIndices.begin();
144     for (int itElt = 0 ; itElt < subset->mNum; itElt++)
145     {
146         med_int srcIndex = (*itSet) - 1; // MED index start at 1
147         subset->mFamIdent[itElt] = mFamIdent[srcIndex];
148         
149         med_int* srcCon = mCon + srcIndex * mNumNodesByElt;
150         memcpy(destCon, srcCon, sizeof(med_int) * mNumNodesByElt);
151         
152         destCon += mNumNodesByElt;
153         itSet++;
154     }
155     
156     //---------------------------------------------------------------------
157     // Copy subset of identifiers if necessary
158     //---------------------------------------------------------------------
159     if (isIdentifiers())  
160     { 
161         itSet = pSetIndices.begin();
162         subset->mId = new med_int[subset->mNum]; 
163         for (int itElt = 0 ; itElt < subset->mNum; itElt++)
164         {
165             med_int srcIndex = (*itSet) - 1; // MED index start at 1
166             subset->mId[itElt] = mId[srcIndex];
167             
168             itSet++;
169         }
170     }
171     
172     //---------------------------------------------------------------------
173     // Copy subset of names if necessary
174     //---------------------------------------------------------------------
175     if (isNames())       
176     { 
177         itSet = pSetIndices.begin();
178         subset->mNames = new char[MED_TAILLE_PNOM * subset->mNum + 1]; 
179         char* destPtr = subset->mNames;
180         for (int itElt = 0 ; itElt < subset->mNum; itElt++)
181         {
182             med_int srcIndex = (*itSet) - 1; // MED index start at 1
183             char* srcPtr = mNames + srcIndex * MED_TAILLE_PNOM;
184             memcpy(destPtr, srcPtr, MED_TAILLE_PNOM);
185             
186             destPtr += MED_TAILLE_PNOM;
187             itSet++;
188         }
189         subset->mNames[MED_TAILLE_PNOM * subset->mNum] = '\0';
190     }
191     
192     return subset;
193 }
194
195
196 const set<med_int>& Elements::getSetOfNodes()
197 {    
198     // lazy get: test if mSetOfNodes has already been built
199     if (mSetOfNodes.size() == 0)
200     {
201         buildSetOfNodes();
202     }
203     
204     return mSetOfNodes;
205 }
206
207
208 set<med_int> Elements::getSetOfFamilies() const
209 {
210     // set of families is empty at the beginning
211     set<med_int> setOfFamilies;
212     
213     // for each element, add its family to the set
214     for (int itElt = 0 ; itElt < mNum ; itElt++)
215     {
216         setOfFamilies.insert(mFamIdent[itElt]);
217     }
218     
219     return setOfFamilies;
220 }
221
222
223 void Elements::remap()
224 {
225     // build set of nodes if necessary
226     if (mSetOfNodes.size() == 0)
227     {
228         buildSetOfNodes();
229     }
230     
231     // build the map for indices convertion
232     map<med_int, med_int> mapOldIndexToNewIndex;
233     med_int newIndex = 1; // MED index start at 1
234     for (set<med_int>::iterator itSet = mSetOfNodes.begin(); itSet != mSetOfNodes.end() ; itSet++)
235     {
236         med_int oldIndex = (*itSet);
237         mapOldIndexToNewIndex.insert(make_pair(oldIndex, newIndex));
238         newIndex++;
239     }
240     
241     // for each node referenced by this set of elements
242     for (int itNode = 0, size = mNum * mNumNodesByElt ; itNode < size ; itNode++)
243     {
244         // convert old index to new index (remap)
245         mCon[itNode] = mapOldIndexToNewIndex[mCon[itNode]];
246     }
247     
248     buildSetOfNodes();
249 }
250
251
252 void Elements::buildSetOfNodes()
253 {
254     if (mSetOfNodes.size() != 0)
255     {
256         mSetOfNodes.clear();
257     }
258     
259     // for each node referenced by this set of elements
260     for (int itNode = 0, size = mNum * mNumNodesByElt ; itNode < size ; itNode++)
261     {
262         // add the node to the set
263         mSetOfNodes.insert(mCon[itNode]);
264     }
265 }
266
267
268 void Elements::readMED(
269     med_idt               pMEDfile, 
270     char*                 pMeshName, 
271     med_int               pMeshDim, 
272     med_entite_maillage   pEntity, 
273     med_geometrie_element pGeom)
274 {
275     if (pMEDfile == 0) throw IOException("", __FILE__, __LINE__);
276     if (pMeshName == NULL) throw NullArgumentException("", __FILE__, __LINE__);
277     if ((pMeshDim < 1) || (pMeshDim > 3)) throw IllegalArgumentException("", __FILE__, __LINE__);
278     
279     reset();
280     
281     mEntity        = pEntity;
282     mGeom          = pGeom;
283     mNumNodesByElt = mGeom % 100;
284     mDim           = mGeom / 100;
285     
286     mNum = MEDnEntMaa(
287         pMEDfile, 
288         pMeshName, 
289         MED_CONN,  // type of information requested = CONNECTIVITY
290         pEntity, 
291         pGeom, 
292         MED_NOD);  // nodal connectivity
293     
294     if (mNum < 0) throw IOException("i/o error while reading information about elements in MED file", __FILE__, __LINE__);
295     
296     mCon      = new med_int[mNumNodesByElt * mNum];
297     mNames    = new char[MED_TAILLE_PNOM * mNum + 1];
298     mId       = new med_int[mNum];
299     mFamIdent = new med_int[mNum]; 
300     med_booleen isNames;
301     med_booleen isIdentifiers;
302     
303     med_err ret = MEDelementsLire(
304         pMEDfile, 
305         pMeshName, 
306         pMeshDim, 
307         mCon, 
308         MED_FULL_INTERLACE,
309         mNames, 
310         &isNames,
311         mId,
312         &isIdentifiers,
313         mFamIdent,
314         mNum, 
315         mEntity, 
316         mGeom, 
317         MED_NOD); // NODAL CONNECTIVITY
318     
319     if (ret != 0) throw IOException("i/o error while reading elements in MED file", __FILE__, __LINE__);
320     
321     if (!isNames)
322     {
323         delete[] mNames;
324         mNames = NULL;
325     }
326     
327     if (!isIdentifiers)
328     {
329         delete[] mId;
330         mId = NULL;
331     }
332 }
333
334
335 void Elements::writeMED(med_idt pMEDfile, char* pMeshName, med_int pMeshDim)
336 {
337     if (pMEDfile == 0) throw IOException("", __FILE__, __LINE__);
338     if (pMeshName == NULL) throw NullArgumentException("", __FILE__, __LINE__);
339     if (strlen(pMeshName) > MED_TAILLE_NOM) throw IllegalArgumentException("", __FILE__, __LINE__);
340     if ((pMeshDim < 1) || (pMeshDim > 3)) throw IllegalArgumentException("", __FILE__, __LINE__);
341     
342     // special case: if no elements => do nothing
343     if (mNum == 0) return;
344     
345     med_err ret = MEDelementsEcr(
346         pMEDfile,
347         pMeshName,
348         pMeshDim,
349         mCon,
350         MED_FULL_INTERLACE,
351         mNames,
352         isNames()?MED_VRAI:MED_FAUX,
353         mId,
354         isIdentifiers()?MED_VRAI:MED_FAUX,
355         mFamIdent,
356         mNum,
357         mEntity,
358         mGeom,
359         MED_NOD); // NODAL CONNECTIVITY
360         
361     if (ret != 0) throw IOException("i/o error while writing elements in MED file", __FILE__, __LINE__);
362 }
363
364
365 ostream& operator<<(ostream& pOs, Elements& pE)
366 {
367     char strEntity[16];
368     switch (pE.mEntity) 
369     {
370         case MED_MAILLE: strcpy(strEntity, "MED_MAILLE"); break;
371         case MED_FACE:   strcpy(strEntity, "MED_FACE"); break;
372         case MED_ARETE:  strcpy(strEntity, "MED_ARETE"); break;
373         case MED_NOEUD:  strcpy(strEntity, "MED_NOEUD"); break;
374         default:         strcpy(strEntity, "UNKNOWN"); break;
375     }
376     
377     pOs << "Elements: " << endl;
378     pOs << "    #number  =" << pE.mNum << endl;
379     pOs << "    Entity   =" << strEntity << endl;
380     pOs << "    Geom     =" << pE.mGeom << endl; 
381     pOs << "    Has names?" << (pE.isNames()?"yes":"no") << endl;
382     pOs << "    Has id   ?" << (pE.isIdentifiers()?"yes":"no") << endl;
383
384     {
385         set<med_int> setOfFam = pE.getSetOfFamilies();
386         if (setOfFam.size() == 0)
387         {
388             pOs << "    Families: #fam=0" << endl;
389         }
390         else
391         {
392             set<med_int>::iterator itFam = setOfFam.end();
393             itFam--;
394             pOs << "    Families: #fam=" << setOfFam.size() << " id_min=" << (*(setOfFam.begin())) << " id_max=" << (*itFam) << endl;
395             
396             if (pE.mFlagPrintAll)
397             {
398                 for (int i = 0 ; i < pE.mNum; i++)
399                 {
400                     pOs << "        Elt " << (i + 1) << ": " << pE.mFamIdent[i] << endl;
401                 }
402             }
403         }
404     }
405     
406     {
407         set<med_int> setOfNodes = pE.getSetOfNodes();
408         if (setOfNodes.size() == 0)
409         {
410             pOs << "    Connectivity: #nodes=0" << endl;
411         }
412         else
413         {
414             set<med_int>::iterator itNode = setOfNodes.end();
415             itNode--;
416             pOs << "    Connectivity: #nodes=" << setOfNodes.size() << " id_min=" << (*(setOfNodes.begin())) << " id_max=" << (*itNode) << endl;
417             
418             if (pE.mFlagPrintAll)
419             {
420                 for (int i = 0 ; i < pE.mNum ; i++)
421                 {
422                     pOs << "        Elt " << (i + 1) << ": ";
423                     for (int j = 0 ; j < pE.mNumNodesByElt ; j++)
424                     {
425                         pOs << pE.mCon[i * pE.mNumNodesByElt + j] << " ";
426                     }
427                     pOs << endl;
428                 }
429             }
430         }
431     }
432     
433     if (pE.mFlagPrintAll)
434     {
435         
436         if (pE.isIdentifiers())
437         {
438             pOs << "    Num (identifier): " << endl;
439             for (int i = 0 ; i < pE.mNum; i++)
440             {
441                 pOs << "        Elt " << (i + 1) << ": " << pE.mId[i] << " " << endl;
442             }
443         }
444         
445         if (pE.isNames())
446         {
447             pE.mNames[MED_TAILLE_PNOM * pE.mNum] = '\0';
448             pOs << "    Names: |" << pE.mNames << "|" << endl;
449         }
450         
451     }
452     
453     return pOs;
454 }
455
456
457 } // namespace  multipr
458
459 // EOF