1 // Project MULTIPR, IOLS WP1.2.1 - EDF/CS
2 // Partitioning/decimation module for the SALOME v3.2 platform
5 * \file MULTIPR_Field.cxx
7 * \brief see MULTIPR_Field.hxx
9 * \author Olivier LE ROUX - CS, Virtual Reality Dpt
14 //*****************************************************************************
16 //*****************************************************************************
18 #include "MULTIPR_Field.hxx"
19 #include "MULTIPR_Exceptions.hxx"
30 //*****************************************************************************
31 // Class Field implementation
32 //*****************************************************************************
67 for (unsigned it = 0 ; it < mVal.size() ; it++)
73 mFlagPrintAll = false;
77 bool Field::isEmpty() const
79 return (mNGauss.size() == 0);
83 int Field::getNumberOfGaussPointsByElement(int pTimeStepIt) const
85 if ((pTimeStepIt < 1) || (pTimeStepIt > int(mNGauss.size()))) throw IndexOutOfBoundsException("", __FILE__, __LINE__);
87 return mNGauss[pTimeStepIt - 1];
91 const string& Field::getNameGaussLoc(int pTimeStepIt) const
93 if ((pTimeStepIt < 1) || (pTimeStepIt > int(mNGauss.size()))) throw IndexOutOfBoundsException("", __FILE__, __LINE__);
95 return mGaussLoc[pTimeStepIt - 1];
99 const unsigned char* Field::getValue(int pTimeStepIt, int pIndex) const
101 if ((pTimeStepIt < 1) || (pTimeStepIt > int(mNGauss.size()))) throw IndexOutOfBoundsException("", __FILE__, __LINE__);
102 if ((pIndex < 1) || (pIndex > mNVal[pTimeStepIt - 1] / mNGauss[pTimeStepIt - 1])) throw IndexOutOfBoundsException("", __FILE__, __LINE__);
104 // size of one data = size of type * number of components * number of Gauss points
105 int sizeOfOneData = mSizeOfType * mNumComponents * mNGauss[pTimeStepIt - 1];
107 unsigned char* ret = mVal[pTimeStepIt - 1] + (pIndex - 1) * sizeOfOneData;
113 Field* Field::extractSubSet(const set<med_int>& pSetIndices) const
115 Field* subset = new Field();
117 memcpy(subset->mName, mName, MED_TAILLE_NOM + 1);
118 subset->mEntity = mEntity;
119 subset->mGeom = mGeom;
120 subset->mType = mType;
121 subset->mSizeOfType = mSizeOfType;
122 subset->mNumComponents = mNumComponents;
123 subset->mStrComponent = mStrComponent;
124 subset->mStrUnit = mStrUnit;
126 subset->mNGauss = mNGauss;
128 subset->mNumDT = mNumDT;
129 subset->mDTUnit = mDTUnit;
130 subset->mNumO = mNumO;
131 subset->mGaussLoc = mGaussLoc;
132 subset->mProfil = mProfil;
134 // for each time step
135 for (unsigned itTimeStep = 0 ; itTimeStep < mNGauss.size() ; itTimeStep++)
137 if (mProfil[itTimeStep].size() != 0) throw UnsupportedOperationException("", __FILE__, __LINE__);
138 // WARNING : do not manage profil for the moment
139 // if there is a profil,
140 // 1. we should set mProfil to NO_PROFIL for this time_step
141 // 2. we should extract data according to the profil
143 int nval = pSetIndices.size() * subset->mNGauss[itTimeStep];
144 subset->mNVal.push_back(nval);
146 int sizeOfData = nval * mSizeOfType * mNumComponents;
147 subset->mSizeOfData.push_back(sizeOfData);
149 unsigned char* data = new unsigned char[sizeOfData];
150 unsigned char* dest = data;
151 int sizeOfOneData = mSizeOfType * mNumComponents * subset->mNGauss[itTimeStep];
153 // for each element to extract
154 for (set<med_int>::iterator itSet = pSetIndices.begin() ; itSet != pSetIndices.end() ; itSet++)
156 int indexElt = (*itSet);
158 // MED index start at 1.
159 if (indexElt < 1) throw new IllegalArgumentException("", __FILE__, __LINE__);
161 unsigned char* src = mVal[itTimeStep] + (indexElt - 1) * sizeOfOneData;
162 memcpy(dest, src, sizeOfOneData);
164 dest += sizeOfOneData;
166 subset->mVal.push_back(data);
173 void Field::getSetOfGaussLoc(set<string>& pSetOfGaussLoc) const
175 for (unsigned itGaussLoc = 0 ; itGaussLoc < mGaussLoc.size() ; itGaussLoc++)
177 const string& gaussLocName = mGaussLoc[itGaussLoc];
179 if (gaussLocName.length() != 0)
181 pSetOfGaussLoc.insert(gaussLocName);
187 void Field::readMED(med_idt pMEDfile, med_int pIndex, char* pMeshName)
189 if (pMEDfile == 0) throw IOException("", __FILE__, __LINE__);
190 if (pMeshName == NULL) throw NullArgumentException("", __FILE__, __LINE__);
191 if (strlen(pMeshName) > MED_TAILLE_NOM) throw IllegalArgumentException("", __FILE__, __LINE__);
192 if (pIndex < 1) throw IllegalArgumentException("", __FILE__, __LINE__);
196 mNumComponents = MEDnChamp(pMEDfile, pIndex);
198 if (mNumComponents < 0) throw IOException("", __FILE__, __LINE__);
200 char* strComponent = new char[mNumComponents * MED_TAILLE_PNOM + 1];
201 char* strUnit = new char[mNumComponents * MED_TAILLE_PNOM + 1];
203 strComponent[0] = '\0';
206 med_err ret = MEDchampInfo(
215 if (ret != 0) throw IOException("", __FILE__, __LINE__);
217 mStrComponent = strComponent;
221 delete[] strComponent;
225 case MED_FLOAT64: mSizeOfType = 8; break;
226 case MED_INT64: mSizeOfType = 8; break;
227 case MED_INT32: mSizeOfType = 4; break;
228 case MED_INT: mSizeOfType = 4; break;
229 default: throw IllegalStateException("should not be there", __FILE__, __LINE__);
232 //---------------------------------------------------------------------
233 // Read fields over nodes
234 //---------------------------------------------------------------------
235 bool fieldOnNodes = false;
237 med_int numTimeStepNodes = MEDnPasdetemps(
241 (med_geometrie_element) 0);
243 if (numTimeStepNodes < 0) throw IOException("", __FILE__, __LINE__);
245 if (numTimeStepNodes != 0)
249 mGeom = (med_geometrie_element) 0;
250 readMEDtimeSteps(pMEDfile, numTimeStepNodes, pMeshName);
254 //---------------------------------------------------------------------
255 // Read fields over elements
256 //---------------------------------------------------------------------
258 med_int numTimeStepElt = MEDnPasdetemps(
264 if (numTimeStepElt < 0) throw IOException("", __FILE__, __LINE__);
266 if (numTimeStepElt != 0)
268 if (fieldOnNodes) throw IllegalStateException("", __FILE__, __LINE__);
270 mEntity = MED_MAILLE;
272 readMEDtimeSteps(pMEDfile, numTimeStepElt, pMeshName);
278 void Field::readMEDtimeSteps(med_idt pMEDfile, med_int pNumberOfTimeSteps, char* pMeshName)
280 if (pMEDfile == 0) throw IOException("", __FILE__, __LINE__);
281 if (pMeshName == NULL) throw NullArgumentException("", __FILE__, __LINE__);
282 if (strlen(pMeshName) > MED_TAILLE_NOM) throw IllegalArgumentException("", __FILE__, __LINE__);
283 if (pNumberOfTimeSteps < 0) throw IllegalArgumentException("", __FILE__, __LINE__);
290 case MED_MAILLE: strcpy(strEntity, "CELLS"); break;
291 case MED_NOEUD: strcpy(strEntity, "NODES"); break;
292 default: strcpy(strEntity, "UNKNOWN"); break;
295 // iterates over time step
296 for (int itTimeStep = 1 ; itTimeStep <= pNumberOfTimeSteps ; itTimeStep++)
301 char dtunit[MED_TAILLE_PNOM + 1];
303 char maa[MED_TAILLE_NOM + 1];
307 med_err ret = MEDpasdetempsInfo(
322 if (ret != 0) throw IOException("i/o error while reading #timesteps in MED file", __FILE__, __LINE__);
324 // mesh must be local
325 if (local != MED_VRAI) throw IllegalStateException("only local fields are currently supported", __FILE__, __LINE__);
328 if (nmaa != 1) throw IllegalStateException("field shoud be associated with 1 mesh only", __FILE__, __LINE__);
330 // mesh must be pMeshName
331 // if field does not apply on the current mesh, skip
332 if (strcmp(maa, pMeshName) != 0)
337 mNGauss.push_back(ngauss);
339 mNumDT.push_back(numdt);
340 mDTUnit.push_back(dtunit);
341 mNumO.push_back(numo);
343 med_int nval = MEDnVal(
353 if (nval < 0) throw IOException("i/o error while reading field in MED file", __FILE__, __LINE__);
355 mNVal.push_back(nval);
357 char gaussLocName[MED_TAILLE_NOM + 1];
358 char profilName[MED_TAILLE_NOM + 1];
359 int sizeOfData = mSizeOfType * mNumComponents * nval;
360 mSizeOfData.push_back(sizeOfData);
361 unsigned char* fieldData = new unsigned char[sizeOfData];
372 MED_COMPACT, // should be: MED_GLOBAL, MED_NO_PFLMOD, MED_COMPACT
378 if (ret != 0) throw IOException("i/o error while reading field in MED file", __FILE__, __LINE__);
380 mGaussLoc.push_back(gaussLocName);
381 mProfil.push_back(profilName);
382 mVal.push_back(fieldData);
387 void Field::writeMED(med_idt pMEDfile, char* pMeshName)
389 if (pMEDfile == 0) throw IOException("", __FILE__, __LINE__);
390 if (pMeshName == NULL) throw NullArgumentException("", __FILE__, __LINE__);
391 if (strlen(pMeshName) > MED_TAILLE_NOM) throw IllegalArgumentException("", __FILE__, __LINE__);
392 if (mNumComponents < 1) throw IllegalStateException("", __FILE__, __LINE__);
394 med_err ret = MEDchampCr(
396 mName, // name of the field
397 mType, // type of data (MED_FLOAT64, MED_INT32, etc.)
398 const_cast<char*>(mStrComponent.c_str()), // name of components
399 const_cast<char*>(mStrUnit.c_str()), // name of units
400 mNumComponents); // number of components
402 if (ret != 0) throw IOException("i/o error while creating field in MED file", __FILE__, __LINE__);
404 // for each time step
405 for (unsigned i = 0 ; i < mNGauss.size() ; i++)
408 if (mNVal[i] == 0) continue;
412 pMeshName, // name of the mesh (first call to MEDchampEcr => name of reference)
413 mName, // name of the field
414 mVal[i], // data (= values)
415 MED_FULL_INTERLACE, // data organization
416 mNVal[i], // number of values
417 const_cast<char*>(mGaussLoc[i].c_str()), // name of Gauss reference
418 MED_ALL, // components to be selected
419 const_cast<char*>(mProfil[i].c_str()), // name of profil
420 MED_GLOBAL, // how to read data: MED_NO_PFLMOD,MED_COMPACT,MED_GLOBAL
421 mEntity, // type of entity (MED_NOEUD, MED_MAILLE, etc.)
422 mGeom, // type of geometry (TETRA10, etc.)
423 mNumDT[i], // time step iteration
424 const_cast<char*>(mDTUnit[i].c_str()), // unit of time step
426 mNumO[i]); // order number
428 if (ret != 0) throw IOException("i/o error while writing field in MED file", __FILE__, __LINE__);
433 ostream& operator<<(ostream& pOs, Field& pF)
438 case MED_MAILLE: strcpy(strEntity, "MED_MAILLE"); break;
439 case MED_FACE: strcpy(strEntity, "MED_FACE"); break;
440 case MED_ARETE: strcpy(strEntity, "MED_ARETE"); break;
441 case MED_NOEUD: strcpy(strEntity, "MED_NOEUD"); break;
442 default: strcpy(strEntity, "UNKNOWN"); break;
448 case MED_FLOAT64: strcpy(strType, "MED_FLOAT64"); break;
449 case MED_INT32: strcpy(strType, "MED_INT32"); break;
450 case MED_INT64: strcpy(strType, "MED_INT64"); break;
451 case MED_INT: strcpy(strType, "MED_INT"); break;
452 default: strcpy(strType, "UNKNOWN"); break;
455 pOs << "Field: " << endl;
456 pOs << " Name =|" << pF.mName << "|" << endl;
457 pOs << " Entity =" << strEntity << endl;
458 pOs << " Geom =" << pF.mGeom << endl;
459 pOs << " Type =" << strType << " (size=" << pF.mSizeOfType << ")" << endl;
460 pOs << " #Components=" << pF.mNumComponents << endl;
461 pOs << " Name component=|" << pF.mStrComponent << "|" << endl;
462 pOs << " Unit component=|" << pF.mStrUnit << "|" << endl;
463 pOs << " #Time steps=" << pF.mNGauss.size() << endl;
465 for (unsigned itTimeStep = 0 ; itTimeStep < pF.mNGauss.size() ; itTimeStep++)
467 pOs << " Time=" << pF.mDT[itTimeStep];
468 pOs << " it=" << pF.mNumDT[itTimeStep];
469 pOs << " order=" << pF.mNumO[itTimeStep];
470 pOs << " #gauss=" << pF.mNGauss[itTimeStep];
471 pOs << " #val=" << pF.mNVal[itTimeStep];
472 pOs << " sizeof_val=" << pF.mSizeOfData[itTimeStep];
473 pOs << " gauss_loc=|" << ((pF.mGaussLoc[itTimeStep].size() == 0)?"NONE":pF.mGaussLoc[itTimeStep]) << "| size=" << pF.mGaussLoc[itTimeStep].size();
474 pOs << " profil=|" << ((pF.mProfil[itTimeStep].size() == 0)?"NONE":pF.mProfil[itTimeStep]) << "| size=" << pF.mProfil[itTimeStep].size() << endl;
476 if (pF.mFlagPrintAll)
483 med_float* src = reinterpret_cast<med_float*>(pF.mVal[itTimeStep]);
484 for (int itVal = 0 ; itVal < pF.mNVal[itTimeStep] * pF.mNumComponents ; itVal++)
486 cout << src[itVal] << " ";
493 med_int* src = reinterpret_cast<med_int*>(pF.mVal[itTimeStep]);
494 for (int itVal = 0 ; itVal < pF.mNVal[itTimeStep] * pF.mNumComponents ; itVal++)
496 cout << src[itVal] << " ";
501 // not yet implemented
502 throw UnsupportedOperationException("not yet implemented", __FILE__, __LINE__);
504 // should not be there
505 throw IllegalStateException("should not be there", __FILE__, __LINE__);
516 } // namespace multipr