1 // Project MULTIPR, IOLS WP1.2.1 - EDF/CS
2 // Partitioning/decimation module for the SALOME v3.2 platform
5 * \file MULTIPR_Elements.cxx
7 * \brief see MULTIPR_Elements.hxx
9 * \author Olivier LE ROUX - CS, Virtual Reality Dpt
14 //*****************************************************************************
16 //*****************************************************************************
18 #include "MULTIPR_Elements.hxx"
19 #include "MULTIPR_Nodes.hxx"
20 #include "MULTIPR_Exceptions.hxx"
33 //*****************************************************************************
34 // Class Elements implementation
35 //*****************************************************************************
54 void Elements::reset()
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; }
69 mFlagPrintAll = false;
73 med_int Elements::getFamilyIdentifier(med_int pIndex) const
75 if ((pIndex < 0) || (pIndex >= mNum)) throw IndexOutOfBoundsException("", __FILE__, __LINE__);
77 return mFamIdent[pIndex];
81 const med_int* Elements::getConnectivity(int pIndex) const
83 if ((pIndex < 0) || (pIndex >= mNum)) throw IndexOutOfBoundsException("", __FILE__, __LINE__);
85 return mCon + mNumNodesByElt * pIndex;
89 void Elements::getCoordinates(med_int pIndexElt, const Nodes* pNodes, med_float* pCoo, int pFirst) const
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__);
95 // get the list of nodes of the element
96 const med_int* con = getConnectivity(pIndexElt);
98 med_float* destCoo = pCoo;
99 int size = sizeof(med_float) * mDim;
101 // for each node of the element
102 int n = (mNumNodesByElt < pFirst) ? mNumNodesByElt : pFirst;
103 for (int i = 0 ; i < n ; i++)
105 // get index of node (MED index start at 1)
106 med_int indexNode = con[i] - 1;
108 // get coordinates of this node
109 const med_float* srcCoo = pNodes->getCoordinates(indexNode);
111 // copy coordinates to destCoo
112 memcpy(destCoo, srcCoo, size);
114 // prepare next point
120 Elements* Elements::extractSubSet(const set<med_int>& pSetIndices) const
122 Elements* subset = new Elements();
124 //---------------------------------------------------------------------
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
133 //---------------------------------------------------------------------
135 //---------------------------------------------------------------------
136 subset->mFamIdent = new med_int[subset->mNum];
137 subset->mCon = new med_int[mNumNodesByElt * subset->mNum];
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++)
146 med_int srcIndex = (*itSet) - 1; // MED index start at 1
147 subset->mFamIdent[itElt] = mFamIdent[srcIndex];
149 med_int* srcCon = mCon + srcIndex * mNumNodesByElt;
150 memcpy(destCon, srcCon, sizeof(med_int) * mNumNodesByElt);
152 destCon += mNumNodesByElt;
156 //---------------------------------------------------------------------
157 // Copy subset of identifiers if necessary
158 //---------------------------------------------------------------------
161 itSet = pSetIndices.begin();
162 subset->mId = new med_int[subset->mNum];
163 for (int itElt = 0 ; itElt < subset->mNum; itElt++)
165 med_int srcIndex = (*itSet) - 1; // MED index start at 1
166 subset->mId[itElt] = mId[srcIndex];
172 //---------------------------------------------------------------------
173 // Copy subset of names if necessary
174 //---------------------------------------------------------------------
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++)
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);
186 destPtr += MED_TAILLE_PNOM;
189 subset->mNames[MED_TAILLE_PNOM * subset->mNum] = '\0';
196 const set<med_int>& Elements::getSetOfNodes()
198 // lazy get: test if mSetOfNodes has already been built
199 if (mSetOfNodes.size() == 0)
208 set<med_int> Elements::getSetOfFamilies() const
210 // set of families is empty at the beginning
211 set<med_int> setOfFamilies;
213 // for each element, add its family to the set
214 for (int itElt = 0 ; itElt < mNum ; itElt++)
216 setOfFamilies.insert(mFamIdent[itElt]);
219 return setOfFamilies;
223 void Elements::remap()
225 // build set of nodes if necessary
226 if (mSetOfNodes.size() == 0)
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++)
236 med_int oldIndex = (*itSet);
237 mapOldIndexToNewIndex.insert(make_pair(oldIndex, newIndex));
241 // for each node referenced by this set of elements
242 for (int itNode = 0, size = mNum * mNumNodesByElt ; itNode < size ; itNode++)
244 // convert old index to new index (remap)
245 mCon[itNode] = mapOldIndexToNewIndex[mCon[itNode]];
252 void Elements::buildSetOfNodes()
254 if (mSetOfNodes.size() != 0)
259 // for each node referenced by this set of elements
260 for (int itNode = 0, size = mNum * mNumNodesByElt ; itNode < size ; itNode++)
262 // add the node to the set
263 mSetOfNodes.insert(mCon[itNode]);
268 void Elements::readMED(
272 med_entite_maillage pEntity,
273 med_geometrie_element pGeom)
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__);
283 mNumNodesByElt = mGeom % 100;
289 MED_CONN, // type of information requested = CONNECTIVITY
292 MED_NOD); // nodal connectivity
294 if (mNum < 0) throw IOException("i/o error while reading information about elements in MED file", __FILE__, __LINE__);
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];
301 med_booleen isIdentifiers;
303 med_err ret = MEDelementsLire(
317 MED_NOD); // NODAL CONNECTIVITY
319 if (ret != 0) throw IOException("i/o error while reading elements in MED file", __FILE__, __LINE__);
335 void Elements::writeMED(med_idt pMEDfile, char* pMeshName, med_int pMeshDim)
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__);
342 // special case: if no elements => do nothing
343 if (mNum == 0) return;
345 med_err ret = MEDelementsEcr(
352 isNames()?MED_VRAI:MED_FAUX,
354 isIdentifiers()?MED_VRAI:MED_FAUX,
359 MED_NOD); // NODAL CONNECTIVITY
361 if (ret != 0) throw IOException("i/o error while writing elements in MED file", __FILE__, __LINE__);
365 ostream& operator<<(ostream& pOs, Elements& pE)
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;
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;
385 set<med_int> setOfFam = pE.getSetOfFamilies();
386 if (setOfFam.size() == 0)
388 pOs << " Families: #fam=0" << endl;
392 set<med_int>::iterator itFam = setOfFam.end();
394 pOs << " Families: #fam=" << setOfFam.size() << " id_min=" << (*(setOfFam.begin())) << " id_max=" << (*itFam) << endl;
396 if (pE.mFlagPrintAll)
398 for (int i = 0 ; i < pE.mNum; i++)
400 pOs << " Elt " << (i + 1) << ": " << pE.mFamIdent[i] << endl;
407 set<med_int> setOfNodes = pE.getSetOfNodes();
408 if (setOfNodes.size() == 0)
410 pOs << " Connectivity: #nodes=0" << endl;
414 set<med_int>::iterator itNode = setOfNodes.end();
416 pOs << " Connectivity: #nodes=" << setOfNodes.size() << " id_min=" << (*(setOfNodes.begin())) << " id_max=" << (*itNode) << endl;
418 if (pE.mFlagPrintAll)
420 for (int i = 0 ; i < pE.mNum ; i++)
422 pOs << " Elt " << (i + 1) << ": ";
423 for (int j = 0 ; j < pE.mNumNodesByElt ; j++)
425 pOs << pE.mCon[i * pE.mNumNodesByElt + j] << " ";
433 if (pE.mFlagPrintAll)
436 if (pE.isIdentifiers())
438 pOs << " Num (identifier): " << endl;
439 for (int i = 0 ; i < pE.mNum; i++)
441 pOs << " Elt " << (i + 1) << ": " << pE.mId[i] << " " << endl;
447 pE.mNames[MED_TAILLE_PNOM * pE.mNum] = '\0';
448 pOs << " Names: |" << pE.mNames << "|" << endl;
457 } // namespace multipr