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__);
139 // WARNING : do not manage profil for the moment
140 // if there is a profil,
141 // 1. we should set mProfil to NO_PROFIL for this time_step
142 // 2. we should extract data according to the profil
144 int nval = pSetIndices.size() * subset->mNGauss[itTimeStep];
145 subset->mNVal.push_back(nval);
147 int sizeOfData = nval * mSizeOfType * mNumComponents;
148 subset->mSizeOfData.push_back(sizeOfData);
150 unsigned char* data = new unsigned char[sizeOfData];
151 unsigned char* dest = data;
152 int sizeOfOneData = mSizeOfType * mNumComponents * subset->mNGauss[itTimeStep];
154 //cout << "Size of 1 data = " << sizeOfOneData << endl; // debug
156 // for each element to extract
157 for (set<med_int>::iterator itSet = pSetIndices.begin() ; itSet != pSetIndices.end() ; itSet++)
159 int indexElt = (*itSet);
161 // MED index start at 1.
162 if (indexElt < 1) throw new IllegalArgumentException("", __FILE__, __LINE__);
164 unsigned char* src = mVal[itTimeStep] + (indexElt - 1) * sizeOfOneData;
165 memcpy(dest, src, sizeOfOneData);
167 dest += sizeOfOneData;
169 subset->mVal.push_back(data);
176 void Field::getSetOfGaussLoc(set<string>& pSetOfGaussLoc) const
178 for (unsigned itGaussLoc = 0 ; itGaussLoc < mGaussLoc.size() ; itGaussLoc++)
180 const string& gaussLocName = mGaussLoc[itGaussLoc];
182 if (gaussLocName.length() != 0)
184 pSetOfGaussLoc.insert(gaussLocName);
190 void Field::readMED(med_idt pMEDfile, med_int pIndex, char* pMeshName)
192 if (pMEDfile == 0) throw IOException("", __FILE__, __LINE__);
193 if (pMeshName == NULL) throw NullArgumentException("", __FILE__, __LINE__);
194 if (strlen(pMeshName) > MED_TAILLE_NOM) throw IllegalArgumentException("", __FILE__, __LINE__);
195 if (pIndex < 1) throw IllegalArgumentException("", __FILE__, __LINE__);
199 mNumComponents = MEDnChamp(pMEDfile, pIndex);
201 if (mNumComponents < 0) throw IOException("", __FILE__, __LINE__);
203 char* strComponent = new char[mNumComponents * MED_TAILLE_PNOM + 1];
204 char* strUnit = new char[mNumComponents * MED_TAILLE_PNOM + 1];
206 strComponent[0] = '\0';
209 med_err ret = MEDchampInfo(
218 if (ret != 0) throw IOException("", __FILE__, __LINE__);
220 mStrComponent = strComponent;
224 delete[] strComponent;
228 case MED_FLOAT64: mSizeOfType = 8; break;
229 case MED_INT64: mSizeOfType = 8; break;
230 case MED_INT32: mSizeOfType = 4; break;
231 case MED_INT: mSizeOfType = 4; break;
232 default: throw IllegalStateException("should not be there", __FILE__, __LINE__);
235 //---------------------------------------------------------------------
236 // Read fields over nodes
237 //---------------------------------------------------------------------
238 bool fieldOnNodes = false;
240 med_int numTimeStepNodes = MEDnPasdetemps(
244 (med_geometrie_element) 0);
246 if (numTimeStepNodes < 0) throw IOException("", __FILE__, __LINE__);
248 if (numTimeStepNodes != 0)
252 mGeom = (med_geometrie_element) 0;
253 readMEDtimeSteps(pMEDfile, numTimeStepNodes, pMeshName);
257 //---------------------------------------------------------------------
258 // Read fields over elements
259 //---------------------------------------------------------------------
261 med_int numTimeStepElt = MEDnPasdetemps(
267 if (numTimeStepElt < 0) throw IOException("", __FILE__, __LINE__);
269 if (numTimeStepElt != 0)
271 if (fieldOnNodes) throw IllegalStateException("", __FILE__, __LINE__);
273 mEntity = MED_MAILLE;
275 readMEDtimeSteps(pMEDfile, numTimeStepElt, pMeshName);
281 void Field::readMEDtimeSteps(med_idt pMEDfile, med_int pNumberOfTimeSteps, char* pMeshName)
283 if (pMEDfile == 0) throw IOException("", __FILE__, __LINE__);
284 if (pMeshName == NULL) throw NullArgumentException("", __FILE__, __LINE__);
285 if (strlen(pMeshName) > MED_TAILLE_NOM) throw IllegalArgumentException("", __FILE__, __LINE__);
286 if (pNumberOfTimeSteps < 0) throw IllegalArgumentException("", __FILE__, __LINE__);
293 case MED_MAILLE: strcpy(strEntity, "CELLS"); break;
294 case MED_NOEUD: strcpy(strEntity, "NODES"); break;
295 default: strcpy(strEntity, "UNKNOWN"); break;
298 // iterates over time step
299 for (int itTimeStep = 1 ; itTimeStep <= pNumberOfTimeSteps ; itTimeStep++)
304 char dtunit[MED_TAILLE_PNOM + 1];
306 char maa[MED_TAILLE_NOM + 1];
310 med_err ret = MEDpasdetempsInfo(
325 if (ret != 0) throw IOException("i/o error while reading #timesteps in MED file", __FILE__, __LINE__);
327 // mesh must be local
328 if (local != MED_VRAI) throw IllegalStateException("only local fields are currently supported", __FILE__, __LINE__);
331 if (nmaa != 1) throw IllegalStateException("field shoud be associated with 1 mesh only", __FILE__, __LINE__);
333 // mesh must be pMeshName
334 //MULTIPR_CHECK((strcmp(maa, pMeshName) == 0), MED_ILLEGAL_FILE, pMEDfile);
335 // if field does not apply on the current mesh, skip
336 if (strcmp(maa, pMeshName) != 0)
341 mNGauss.push_back(ngauss);
343 mNumDT.push_back(numdt);
344 mDTUnit.push_back(dtunit);
345 mNumO.push_back(numo);
347 //MULTIPR_LOG("Time step #" << itTimeStep << ": #gauss=" << ngauss << " dt=" << dt << " maa=" << maa << " has_dt?" << ((numdt==MED_NOPDT)?"no":"yes") << " numdt=" << numdt << " unit=" << dtunit << " has_order?" << ((numo==MED_NONOR)?"no":"yes") << " numo:" << numo << endl);
349 med_int nval = MEDnVal(
359 if (nval < 0) throw IOException("i/o error while reading field in MED file", __FILE__, __LINE__);
361 mNVal.push_back(nval);
363 char gaussLocName[MED_TAILLE_NOM + 1];
364 char profilName[MED_TAILLE_NOM + 1];
365 int sizeOfData = mSizeOfType * mNumComponents * nval;
366 mSizeOfData.push_back(sizeOfData);
367 unsigned char* fieldData = new unsigned char[sizeOfData];
378 MED_COMPACT, //MED_GLOBAL, MED_NO_PFLMOD, MED_COMPACT
384 if (ret != 0) throw IOException("i/o error while reading field in MED file", __FILE__, __LINE__);
386 mGaussLoc.push_back(gaussLocName);
387 mProfil.push_back(profilName);
388 mVal.push_back(fieldData);
393 void Field::writeMED(med_idt pMEDfile, char* pMeshName)
395 if (pMEDfile == 0) throw IOException("", __FILE__, __LINE__);
396 if (pMeshName == NULL) throw NullArgumentException("", __FILE__, __LINE__);
397 if (strlen(pMeshName) > MED_TAILLE_NOM) throw IllegalArgumentException("", __FILE__, __LINE__);
398 if (mNumComponents < 1) throw IllegalStateException("", __FILE__, __LINE__);
400 med_err ret = MEDchampCr(
402 mName, // name of the field
403 mType, // type of data (MED_FLOAT64, MED_INT32, etc.)
404 const_cast<char*>(mStrComponent.c_str()), // name of components
405 const_cast<char*>(mStrUnit.c_str()), // name of units
406 mNumComponents); // number of components
408 if (ret != 0) throw IOException("i/o error while creating field in MED file", __FILE__, __LINE__);
410 // for each time step
411 for (unsigned i = 0 ; i < mNGauss.size() ; i++)
414 if (mNVal[i] == 0) continue;
418 pMeshName, // name of the mesh (first call to MEDchampEcr => name of reference)
419 mName, // name of the field
420 mVal[i], // data (= values)
421 MED_FULL_INTERLACE, // data organization
422 mNVal[i], // number of values
423 const_cast<char*>(mGaussLoc[i].c_str()), // name of Gauss reference
424 MED_ALL, // components to be selected
425 const_cast<char*>(mProfil[i].c_str()), // name of profil
426 MED_GLOBAL, // how to read data: MED_NO_PFLMOD,MED_COMPACT,MED_GLOBAL
427 mEntity, // type of entity (MED_NOEUD, MED_MAILLE, etc.)
428 mGeom, // type of geometry (TETRA10, etc.)
429 mNumDT[i], // time step iteration
430 const_cast<char*>(mDTUnit[i].c_str()), // unit of time step
432 mNumO[i]); // order number
434 if (ret != 0) throw IOException("i/o error while writing field in MED file", __FILE__, __LINE__);
439 ostream& operator<<(ostream& pOs, Field& pF)
444 case MED_MAILLE: strcpy(strEntity, "MED_MAILLE"); break;
445 case MED_FACE: strcpy(strEntity, "MED_FACE"); break;
446 case MED_ARETE: strcpy(strEntity, "MED_ARETE"); break;
447 case MED_NOEUD: strcpy(strEntity, "MED_NOEUD"); break;
448 default: strcpy(strEntity, "UNKNOWN"); break;
454 case MED_FLOAT64: strcpy(strType, "MED_FLOAT64"); break;
455 case MED_INT32: strcpy(strType, "MED_INT32"); break;
456 case MED_INT64: strcpy(strType, "MED_INT64"); break;
457 case MED_INT: strcpy(strType, "MED_INT"); break;
458 default: strcpy(strType, "UNKNOWN"); break;
461 pOs << "Field: " << endl;
462 pOs << " Name =|" << pF.mName << "|" << endl;
463 pOs << " Entity =" << strEntity << endl;
464 pOs << " Geom =" << pF.mGeom << endl;
465 pOs << " Type =" << strType << " (size=" << pF.mSizeOfType << ")" << endl;
466 pOs << " #Components=" << pF.mNumComponents << endl;
467 pOs << " Name component=|" << pF.mStrComponent << "|" << endl;
468 pOs << " Unit component=|" << pF.mStrUnit << "|" << endl;
469 pOs << " #Time steps=" << pF.mNGauss.size() << endl;
471 for (unsigned itTimeStep = 0 ; itTimeStep < pF.mNGauss.size() ; itTimeStep++)
473 pOs << " Time=" << pF.mDT[itTimeStep];
474 pOs << " it=" << pF.mNumDT[itTimeStep];
475 pOs << " order=" << pF.mNumO[itTimeStep];
476 pOs << " #gauss=" << pF.mNGauss[itTimeStep];
477 pOs << " #val=" << pF.mNVal[itTimeStep];
478 pOs << " sizeof_val=" << pF.mSizeOfData[itTimeStep];
479 pOs << " gauss_loc=|" << ((pF.mGaussLoc[itTimeStep].size() == 0)?"NONE":pF.mGaussLoc[itTimeStep]) << "| size=" << pF.mGaussLoc[itTimeStep].size();
480 pOs << " profil=|" << ((pF.mProfil[itTimeStep].size() == 0)?"NONE":pF.mProfil[itTimeStep]) << "| size=" << pF.mProfil[itTimeStep].size() << endl;
482 if (pF.mFlagPrintAll)
489 med_float* src = reinterpret_cast<med_float*>(pF.mVal[itTimeStep]);
490 for (int itVal = 0 ; itVal < pF.mNVal[itTimeStep] * pF.mNumComponents ; itVal++)
492 cout << src[itVal] << " ";
499 med_int* src = reinterpret_cast<med_int*>(pF.mVal[itTimeStep]);
500 for (int itVal = 0 ; itVal < pF.mNVal[itTimeStep] * pF.mNumComponents ; itVal++)
502 cout << src[itVal] << " ";
507 // not yet implemented
508 throw UnsupportedOperationException("not yet implemented", __FILE__, __LINE__);
510 // should not be there
511 throw IllegalStateException("should not be there", __FILE__, __LINE__);
522 } // namespace multipr