1 // Copyright (C) 2007-2023 CEA, EDF
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // Author : Anthony Geay (EDF R&D)
21 #include "MEDFileField.hxx"
22 #include "MEDFileMesh.hxx"
23 #include "MEDLoaderBase.hxx"
24 #include "MEDLoaderTraits.hxx"
25 #include "MEDFileSafeCaller.txx"
26 #include "MEDFileFieldOverView.hxx"
27 #include "MEDFileBlowStrEltUp.hxx"
28 #include "MEDFileFieldVisitor.hxx"
30 #include "MEDCouplingFieldDiscretization.hxx"
32 #include "InterpKernelAutoPtr.hxx"
33 #include "CellModel.hxx"
38 // From MEDLoader.cxx TU:
39 extern INTERP_KERNEL::NormalizedCellType typmai2[MED_N_CELL_FIXED_GEO];
40 extern med_geometry_type typmainoeud[1];
41 extern med_geometry_type typmai3[INTERP_KERNEL::NORM_MAXTYPE];
43 using namespace MEDCoupling;
47 MEDFileFields *MEDFileFields::New()
49 return new MEDFileFields;
52 MEDFileFields *MEDFileFields::New(const std::string& fileName, bool loadAll)
54 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
55 return New(fid,loadAll);
58 MEDFileFields *MEDFileFields::NewAdv(const std::string& fileName, bool loadAll, const MEDFileEntities *entities)
60 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
61 return NewAdv(fid,loadAll,entities);
64 MEDFileFields *MEDFileFields::NewAdv(med_idt fid, bool loadAll, const MEDFileEntities *entities)
66 return new MEDFileFields(fid,loadAll,0,entities);
69 MEDFileFields *MEDFileFields::NewWithDynGT(const std::string& fileName, const MEDFileStructureElements *se, bool loadAll)
71 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
72 return NewWithDynGT(fid,se,loadAll);
75 MEDFileFields *MEDFileFields::NewWithDynGT(med_idt fid, const MEDFileStructureElements *se, bool loadAll)
78 throw INTERP_KERNEL::Exception("MEDFileFields::NewWithDynGT : null struct element pointer !");
79 INTERP_KERNEL::AutoCppPtr<MEDFileEntities> entities(MEDFileEntities::BuildFrom(*se));
80 return new MEDFileFields(fid,loadAll,0,entities);
83 MEDFileFields *MEDFileFields::New(med_idt fid, bool loadAll)
85 return new MEDFileFields(fid,loadAll,0,0);
88 MEDFileFields *MEDFileFields::LoadPartOf(const std::string& fileName, bool loadAll, const MEDFileMeshes *ms)
90 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
91 return new MEDFileFields(fid,loadAll,ms,0);
94 MEDFileFields *MEDFileFields::LoadSpecificEntities(const std::string& fileName, const std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> >& entities, bool loadAll)
96 MEDFileUtilities::CheckFileForRead(fileName);
97 INTERP_KERNEL::AutoCppPtr<MEDFileEntities> ent(new MEDFileStaticEntities(entities));
98 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
99 return new MEDFileFields(fid,loadAll,0,ent);
102 std::size_t MEDFileFields::getHeapMemorySizeWithoutChildren() const
104 std::size_t ret(MEDFileFieldGlobsReal::getHeapMemorySizeWithoutChildren());
105 ret+=_fields.capacity()*sizeof(MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA>);
109 std::vector<const BigMemoryObject *> MEDFileFields::getDirectChildrenWithNull() const
111 std::vector<const BigMemoryObject *> ret;
112 for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++)
113 ret.push_back((const MEDFileAnyTypeFieldMultiTSWithoutSDA *)*it);
117 MEDFileFields *MEDFileFields::deepCopy() const
119 MCAuto<MEDFileFields> ret(shallowCpy());
121 for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++,i++)
123 if((const MEDFileAnyTypeFieldMultiTSWithoutSDA*)*it)
124 ret->_fields[i]=(*it)->deepCopy();
126 ret->deepCpyGlobs(*this);
130 MEDFileFields *MEDFileFields::shallowCpy() const
132 return new MEDFileFields(*this);
136 * This method scans for all fields in \a this which time steps ids are common. Time step are discriminated by the pair of integer (iteration,order) whatever
137 * the double time value. If all returned time steps are \b exactly those for all fields in \a this output parameter \a areThereSomeForgottenTS will be set to false.
138 * If \a areThereSomeForgottenTS is set to true, only the sorted intersection of time steps present for all fields in \a this will be returned.
140 * \param [out] areThereSomeForgottenTS - indicates to the caller if there is some time steps in \a this that are not present for all fields in \a this.
141 * \return the sorted list of time steps (specified with a pair of integer iteration first and order second) present for all fields in \a this.
143 * \sa MEDFileFields::partOfThisLyingOnSpecifiedTimeSteps, MEDFileFields::partOfThisNotLyingOnSpecifiedTimeSteps
145 std::vector< std::pair<int,int> > MEDFileFields::getCommonIterations(bool& areThereSomeForgottenTS) const
147 std::set< std::pair<int,int> > s;
149 areThereSomeForgottenTS=false;
150 for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++)
152 if(!(const MEDFileAnyTypeFieldMultiTSWithoutSDA*)*it)
154 std::vector< std::pair<int,int> > v=(*it)->getIterations();
155 std::set< std::pair<int,int> > s1; std::copy(v.begin(),v.end(),std::inserter(s1,s1.end()));
157 { s=s1; firstShot=false; }
160 std::set< std::pair<int,int> > s2; std::set_intersection(s.begin(),s.end(),s1.begin(),s1.end(),std::inserter(s2,s2.end()));
162 areThereSomeForgottenTS=true;
166 std::vector< std::pair<int,int> > ret;
167 std::copy(s.begin(),s.end(),std::back_insert_iterator< std::vector< std::pair<int,int> > >(ret));
171 int MEDFileFields::getNumberOfFields() const
173 return (int)_fields.size();
176 std::vector<std::string> MEDFileFields::getFieldsNames() const
178 std::vector<std::string> ret(_fields.size());
180 for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++,i++)
182 const MEDFileAnyTypeFieldMultiTSWithoutSDA *f=(*it);
189 std::ostringstream oss; oss << "MEDFileFields::getFieldsNames : At rank #" << i << " field is not defined !";
190 throw INTERP_KERNEL::Exception(oss.str());
196 std::vector<std::string> MEDFileFields::getMeshesNames() const
198 std::vector<std::string> ret;
199 for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++)
201 const MEDFileAnyTypeFieldMultiTSWithoutSDA *cur(*it);
203 ret.push_back(cur->getMeshName());
208 std::string MEDFileFields::simpleRepr() const
210 std::ostringstream oss;
211 oss << "(*****************)\n(* MEDFileFields *)\n(*****************)\n\n";
216 void MEDFileFields::simpleRepr(int bkOffset, std::ostream& oss) const
218 int nbOfFields(getNumberOfFields());
219 std::string startLine(bkOffset,' ');
220 oss << startLine << "There are " << nbOfFields << " fields in this :" << std::endl;
222 for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++,i++)
224 const MEDFileAnyTypeFieldMultiTSWithoutSDA *cur=(*it);
227 oss << startLine << " - # "<< i << " has the following name : \"" << cur->getName() << "\"." << std::endl;
231 oss << startLine << " - not defined !" << std::endl;
235 for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++,i++)
237 const MEDFileAnyTypeFieldMultiTSWithoutSDA *cur=(*it);
238 std::string chapter(17,(char)('0'+i));
239 oss << startLine << chapter << std::endl;
242 cur->simpleRepr(bkOffset+2,oss,i);
246 oss << startLine << " - not defined !" << std::endl;
248 oss << startLine << chapter << std::endl;
250 simpleReprGlobs(oss);
253 MEDFileFields::MEDFileFields()
257 MEDFileFields::MEDFileFields(med_idt fid, bool loadAll, const MEDFileMeshes *ms, const MEDFileEntities *entities)
258 try:MEDFileFieldGlobsReal(fid)
260 med_int nbFields(MEDnField(fid));
261 _fields.resize(nbFields);
262 med_field_type typcha;
263 for(int i=0;i<nbFields;i++)
265 std::vector<std::string> infos;
266 std::string fieldName,dtunit,meshName;
267 int nbOfStep(MEDFileAnyTypeField1TS::LocateField2(fid,i,false,fieldName,typcha,infos,dtunit,meshName));
272 _fields[i]=MEDFileFieldMultiTSWithoutSDA::New(fid,fieldName,meshName,typcha,infos,nbOfStep,dtunit,loadAll,ms,entities);
277 _fields[i]=MEDFileInt32FieldMultiTSWithoutSDA::New(fid,fieldName,meshName,typcha,infos,nbOfStep,dtunit,loadAll,ms,entities);
282 _fields[i]=MEDFileInt64FieldMultiTSWithoutSDA::New(fid,fieldName,meshName,typcha,infos,nbOfStep,dtunit,loadAll,ms,entities);
287 _fields[i]=MEDFileFloatFieldMultiTSWithoutSDA::New(fid,fieldName,meshName,typcha,infos,nbOfStep,dtunit,loadAll,ms,entities);
292 if(sizeof(med_int)==sizeof(int))
294 _fields[i]=MEDFileInt32FieldMultiTSWithoutSDA::New(fid,fieldName,meshName,typcha,infos,nbOfStep,dtunit,loadAll,ms,entities);
300 std::ostringstream oss; oss << "constructor MEDFileFields(fileName) : file \'" << FileNameFromFID(fid) << "\' at pos #" << i << " field has name \'" << fieldName << "\' but the type of field is not in [MED_FLOAT64, MED_INT32, MED_FLOAT32, MED_INT64] !";
301 throw INTERP_KERNEL::Exception(oss.str());
305 loadAllGlobals(fid,entities);
307 catch(INTERP_KERNEL::Exception& e)
312 void MEDFileFields::writeLL(med_idt fid) const
315 writeGlobals(fid,*this);
316 for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++,i++)
318 const MEDFileAnyTypeFieldMultiTSWithoutSDA *elt=*it;
321 std::ostringstream oss; oss << "MEDFileFields::write : at rank #" << i << "/" << _fields.size() << " field is empty !";
322 throw INTERP_KERNEL::Exception(oss.str());
324 elt->writeLL(fid,*this);
329 * This method alloc the arrays and load potentially huge arrays contained in this field.
330 * This method should be called when a MEDFileAnyTypeFieldMultiTS::New constructor has been with false as the last parameter.
331 * This method can be also called to refresh or reinit values from a file.
333 * \throw If the fileName is not set or points to a non readable MED file.
335 void MEDFileFields::loadArrays()
337 if(getFileName().empty())
338 throw INTERP_KERNEL::Exception("MEDFileFields::loadArrays : the structure does not come from a file !");
339 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(getFileName()));
340 for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::iterator it=_fields.begin();it!=_fields.end();it++)
342 MEDFileAnyTypeFieldMultiTSWithoutSDA *elt(*it);
344 elt->loadBigArraysRecursively(fid,*elt);
349 * This method behaves as MEDFileFields::loadArrays does, the first call, if \a this was built using a file without loading big arrays.
350 * But once data loaded once, this method does nothing.
352 * \throw If the fileName is not set or points to a non readable MED file.
353 * \sa MEDFileFields::loadArrays, MEDFileFields::unloadArrays
355 void MEDFileFields::loadArraysIfNecessary()
357 if(!getFileName().empty())
359 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(getFileName()));
360 for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::iterator it=_fields.begin();it!=_fields.end();it++)
362 MEDFileAnyTypeFieldMultiTSWithoutSDA *elt(*it);
364 elt->loadBigArraysRecursivelyIfNecessary(fid,*elt);
370 * This method releases potentially big data arrays and so returns to the same heap memory than status loaded with 'loadAll' parameter set to false.
371 * \b WARNING, this method does release arrays even if \a this does not come from a load of a MED file.
372 * So this method can lead to a loss of data. If you want to unload arrays safely call MEDFileFields::unloadArraysWithoutDataLoss instead.
374 * \sa MEDFileFields::loadArrays, MEDFileFields::loadArraysIfNecessary, MEDFileFields::unloadArraysWithoutDataLoss
376 void MEDFileFields::unloadArrays()
378 for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::iterator it=_fields.begin();it!=_fields.end();it++)
380 MEDFileAnyTypeFieldMultiTSWithoutSDA *elt(*it);
387 * This method potentially releases big data arrays if \a this is coming from a file. If \a this has been built from scratch this method will have no effect.
388 * This method is the symmetrical method of MEDFileFields::loadArraysIfNecessary.
389 * This method is useful to reduce \b safely amount of heap memory necessary for \a this by using MED file as database.
391 * \sa MEDFileFields::loadArraysIfNecessary
393 void MEDFileFields::unloadArraysWithoutDataLoss()
395 if(!getFileName().empty())
399 std::vector<std::string> MEDFileFields::getPflsReallyUsed() const
401 std::vector<std::string> ret;
402 std::set<std::string> ret2;
403 for(std::vector< MCAuto< MEDFileAnyTypeFieldMultiTSWithoutSDA > >::const_iterator it=_fields.begin();it!=_fields.end();it++)
405 std::vector<std::string> tmp=(*it)->getPflsReallyUsed2();
406 for(std::vector<std::string>::const_iterator it2=tmp.begin();it2!=tmp.end();it2++)
407 if(ret2.find(*it2)==ret2.end())
416 std::vector<std::string> MEDFileFields::getLocsReallyUsed() const
418 std::vector<std::string> ret;
419 std::set<std::string> ret2;
420 for(std::vector< MCAuto< MEDFileAnyTypeFieldMultiTSWithoutSDA > >::const_iterator it=_fields.begin();it!=_fields.end();it++)
422 std::vector<std::string> tmp((*it)->getLocsReallyUsed2());
423 for(std::vector<std::string>::const_iterator it2=tmp.begin();it2!=tmp.end();it2++)
424 if(ret2.find(*it2)==ret2.end())
433 std::vector<std::string> MEDFileFields::getPflsReallyUsedMulti() const
435 std::vector<std::string> ret;
436 for(std::vector< MCAuto< MEDFileAnyTypeFieldMultiTSWithoutSDA > >::const_iterator it=_fields.begin();it!=_fields.end();it++)
438 std::vector<std::string> tmp((*it)->getPflsReallyUsedMulti2());
439 ret.insert(ret.end(),tmp.begin(),tmp.end());
444 std::vector<std::string> MEDFileFields::getLocsReallyUsedMulti() const
446 std::vector<std::string> ret;
447 for(std::vector< MCAuto< MEDFileAnyTypeFieldMultiTSWithoutSDA > >::const_iterator it=_fields.begin();it!=_fields.end();it++)
449 std::vector<std::string> tmp((*it)->getLocsReallyUsed2());
450 ret.insert(ret.end(),tmp.begin(),tmp.end());
455 void MEDFileFields::changePflsRefsNamesGen(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif)
457 for(std::vector< MCAuto< MEDFileAnyTypeFieldMultiTSWithoutSDA > >::iterator it=_fields.begin();it!=_fields.end();it++)
458 (*it)->changePflsRefsNamesGen2(mapOfModif);
461 void MEDFileFields::changeLocsRefsNamesGen(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif)
463 for(std::vector< MCAuto< MEDFileAnyTypeFieldMultiTSWithoutSDA > >::iterator it=_fields.begin();it!=_fields.end();it++)
464 (*it)->changeLocsRefsNamesGen2(mapOfModif);
467 void MEDFileFields::resize(int newSize)
469 _fields.resize(newSize);
472 void MEDFileFields::pushFields(const std::vector<MEDFileAnyTypeFieldMultiTS *>& fields)
474 for(std::vector<MEDFileAnyTypeFieldMultiTS *>::const_iterator it=fields.begin();it!=fields.end();it++)
478 void MEDFileFields::pushField(MEDFileAnyTypeFieldMultiTS *field)
481 throw INTERP_KERNEL::Exception("MEDFileFields::pushMesh : invalid input pointer ! should be different from 0 !");
482 _fields.push_back(field->getContent());
483 appendGlobs(*field,1e-12);
486 void MEDFileFields::setFieldAtPos(int i, MEDFileAnyTypeFieldMultiTS *field)
489 throw INTERP_KERNEL::Exception("MEDFileFields::setFieldAtPos : invalid input pointer ! should be different from 0 !");
490 if(i>=(int)_fields.size())
492 _fields[i]=field->getContent();
493 appendGlobs(*field,1e-12);
496 void MEDFileFields::destroyFieldAtPos(int i)
498 destroyFieldsAtPos(&i,&i+1);
501 void MEDFileFields::destroyFieldsAtPos(const int *startIds, const int *endIds)
503 std::vector<bool> b(_fields.size(),true);
504 for(const int *i=startIds;i!=endIds;i++)
506 if(*i<0 || *i>=(int)_fields.size())
508 std::ostringstream oss; oss << "MEDFileFields::destroyFieldsAtPos : Invalid given id in input (" << *i << ") should be in [0," << _fields.size() << ") !";
509 throw INTERP_KERNEL::Exception(oss.str());
513 std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> > fields(std::count(b.begin(),b.end(),true));
515 for(std::size_t i=0;i<_fields.size();i++)
517 fields[j++]=_fields[i];
521 void MEDFileFields::destroyFieldsAtPos2(int bg, int end, int step)
523 static const char msg[]="MEDFileFields::destroyFieldsAtPos2";
524 mcIdType nbOfEntriesToKill(DataArrayIdType::GetNumberOfItemGivenBESRelative(bg,end,step,msg));
525 std::vector<bool> b(_fields.size(),true);
527 for(int i=0;i<nbOfEntriesToKill;i++,k+=step)
529 if(k<0 || k>=(int)_fields.size())
531 std::ostringstream oss; oss << "MEDFileFields::destroyFieldsAtPos2 : Invalid given id in input (" << k << ") should be in [0," << _fields.size() << ") !";
532 throw INTERP_KERNEL::Exception(oss.str());
536 std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> > fields(std::count(b.begin(),b.end(),true));
538 for(std::size_t i=0;i<_fields.size();i++)
540 fields[j++]=_fields[i];
544 bool MEDFileFields::changeMeshNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
547 for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::iterator it=_fields.begin();it!=_fields.end();it++)
549 MEDFileAnyTypeFieldMultiTSWithoutSDA *cur(*it);
551 ret=cur->changeMeshNames(modifTab) || ret;
557 * \param [in] meshName the name of the mesh that will be renumbered.
558 * \param [in] oldCode is of format returned by MEDCouplingUMesh::getDistributionOfTypes. And for each *i* oldCode[3*i+2] gives the position (MEDFileUMesh::PutInThirdComponentOfCodeOffset).
559 * This code corresponds to the distribution of types in the corresponding mesh.
560 * \param [in] newCode idem to param \a oldCode except that here the new distribution is given.
561 * \param [in] renumO2N the old to new renumber array.
562 * \return If true a renumbering has been performed. The structure in \a this has been modified. If false, nothing has been done: it is typically the case if \a meshName is not referred by any
565 bool MEDFileFields::renumberEntitiesLyingOnMesh(const std::string& meshName, const std::vector<mcIdType>& oldCode, const std::vector<mcIdType>& newCode, const DataArrayIdType *renumO2N)
568 for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::iterator it=_fields.begin();it!=_fields.end();it++)
570 MEDFileAnyTypeFieldMultiTSWithoutSDA *fmts(*it);
573 ret=fmts->renumberEntitiesLyingOnMesh(meshName,oldCode,newCode,renumO2N,*this) || ret;
580 * Return an extraction of \a this using \a extractDef map to specify the extraction.
581 * The keys of \a extractDef is level relative to max ext of \a mm mesh.
583 * \return A new object that the caller is responsible to deallocate.
585 MEDFileFields *MEDFileFields::extractPart(const std::map<int, MCAuto<DataArrayIdType> >& extractDef, MEDFileMesh *mm) const
588 throw INTERP_KERNEL::Exception("MEDFileFields::extractPart : input mesh is NULL !");
589 MCAuto<MEDFileFields> fsOut(MEDFileFields::New());
590 int nbFields(getNumberOfFields());
591 for(int i=0;i<nbFields;i++)
593 MCAuto<MEDFileAnyTypeFieldMultiTS> fmts(getFieldAtPos(i));
596 std::ostringstream oss; oss << "MEDFileFields::extractPart : at pos #" << i << " field is null !";
597 throw INTERP_KERNEL::Exception(oss.str());
599 MCAuto<MEDFileAnyTypeFieldMultiTS> fmtsOut(fmts->extractPart(extractDef,mm));
600 fsOut->pushField(fmtsOut);
605 void MEDFileFields::accept(MEDFileFieldVisitor& visitor) const
607 for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++)
608 if((*it).isNotNull())
610 visitor.newFieldEntry(*it);
611 (*it)->accept(visitor);
612 visitor.endFieldEntry(*it);
619 PFLData():_add_pts_in_pfl(0) { }
620 PFLData(const MCAuto<DataArrayIdType>& mat, const MCAuto<DataArrayIdType>& pfl, mcIdType nbOfNewPts):_matrix(mat),_pfl(pfl),_add_pts_in_pfl(nbOfNewPts) { }
621 std::string getPflName() const { if(_pfl.isNull()) { return std::string(); } else { return _pfl->getName(); } }
622 mcIdType getNbOfAddPtsInPfl() const { return _add_pts_in_pfl; }
623 MCAuto<DataArrayIdType> getProfile() const { return _pfl; }
624 MCAuto<DataArrayIdType> getMatrix() const { return _matrix; }
626 MCAuto<DataArrayIdType> _matrix;
627 MCAuto<DataArrayIdType> _pfl;
628 mcIdType _add_pts_in_pfl;
631 class MEDFileFieldLin2QuadVisitor : public MEDFileFieldVisitor
634 MEDFileFieldLin2QuadVisitor(const MEDFileUMesh *lin, const MEDFileUMesh *quad, const MEDFileFieldGlobsReal *linGlobs, MEDFileFields* outFs):_lin(lin),_quad(quad),_lin_globs(linGlobs),_out_fs(outFs),_gt(INTERP_KERNEL::NORM_ERROR),_1ts_update_requested(false) { }
635 void newFieldEntry(const MEDFileAnyTypeFieldMultiTSWithoutSDA *field) { if(field->getMeshName()!=_lin->getName()) return; _cur_fmts=MEDFileFieldMultiTS::New(); }
636 void endFieldEntry(const MEDFileAnyTypeFieldMultiTSWithoutSDA *field) { if(_cur_fmts.isNotNull()) { if(_cur_fmts->getNumberOfTS()>0) _out_fs->pushField(_cur_fmts); } }
638 void newTimeStepEntry(const MEDFileAnyTypeField1TSWithoutSDA *ts);
639 void endTimeStepEntry(const MEDFileAnyTypeField1TSWithoutSDA *ts);
641 void newMeshEntry(const MEDFileFieldPerMesh *fpm);
642 void endMeshEntry(const MEDFileFieldPerMesh *fpm) { }
644 void newPerMeshPerTypeEntry(const MEDFileFieldPerMeshPerTypeCommon *pmpt);
645 void endPerMeshPerTypeEntry(const MEDFileFieldPerMeshPerTypeCommon *pmpt) { }
647 void newPerMeshPerTypePerDisc(const MEDFileFieldPerMeshPerTypePerDisc *pmptpd);
649 void updateData(MEDFileFieldPerMeshPerTypePerDisc *pmtd, mcIdType deltaNbNodes);
651 const MEDFileUMesh *_lin;
652 const MEDFileUMesh *_quad;
653 const MEDFileFieldGlobsReal *_lin_globs;
654 MEDFileFields *_out_fs;
655 MCAuto<MEDFileFieldMultiTS> _cur_fmts;
656 MCAuto<MEDFileField1TS> _cur_f1ts;
657 INTERP_KERNEL::NormalizedCellType _gt;
658 // Info on 1TS modification
659 bool _1ts_update_requested;
660 // Cache of matrix to compute faster the values on newly created points
661 std::map< std::string, PFLData > _cache;
662 std::vector<std::string> _pfls_to_be_updated;
665 void MEDFileFieldLin2QuadVisitor::newPerMeshPerTypePerDisc(const MEDFileFieldPerMeshPerTypePerDisc *pmptpd)
667 if(_cur_f1ts.isNull())
669 if(pmptpd->getType()!=ON_NODES)
670 throw INTERP_KERNEL::Exception("Not managed yet for ON_CELLS ON_GAUSS_NE and ON_GAUSS_PT");
671 _1ts_update_requested=true;
672 MEDFileAnyTypeField1TSWithoutSDA *ct(_cur_f1ts->contentNotNullBase());
673 int locId(pmptpd->getFather()->locIdOfLeaf(pmptpd));
674 MEDFileFieldPerMeshPerTypePerDisc *pmtdToModify(ct->getLeafGivenMeshAndTypeAndLocId(_lin->getName(),_gt,locId));
675 std::string pflName(pmptpd->getProfile());
676 _pfls_to_be_updated.push_back(pflName);
677 std::map< std::string, PFLData >::iterator itCache(_cache.find(pflName));
678 if(itCache!=_cache.end())
680 updateData(pmtdToModify,(*itCache).second.getNbOfAddPtsInPfl());
683 MCAuto<DataArrayIdType> pfl;
685 pfl=DataArrayIdType::Range(0,pmptpd->getNumberOfVals(),1);
687 pfl=_lin_globs->getProfile(pflName)->deepCopy();
689 MCAuto<MEDCouplingUMesh> mesh3D(_lin->getMeshAtLevel(0)),mesh3DQuadratic(_quad->getMeshAtLevel(0));
690 MCAuto<DataArrayIdType> cellIds(mesh3D->getCellIdsLyingOnNodes(pfl->begin(),pfl->end(),true));
691 MCAuto<MEDCouplingUMesh> mesh3DQuadraticRestricted(mesh3DQuadratic->buildPartOfMySelf(cellIds->begin(),cellIds->end(),true));
692 MCAuto<DataArrayIdType> mesh3DQuadraticRestrictedNodeIds(mesh3DQuadraticRestricted->computeFetchedNodeIds());
693 mesh3DQuadraticRestrictedNodeIds->checkMonotonic(true);
694 MCAuto<DataArrayIdType> newPtsIds(mesh3DQuadraticRestrictedNodeIds->buildSubstraction(pfl));
695 MCAuto<MEDCoupling1SGTUMesh> allSeg3;
697 MCAuto<DataArrayIdType> a,b,c,d;
698 MCAuto<MEDCouplingUMesh> seg3Tmp(mesh3DQuadraticRestricted->explodeIntoEdges(a,b,c,d));
699 allSeg3=MEDCoupling1SGTUMesh::New(seg3Tmp);
701 if(allSeg3->getCellModelEnum()!=INTERP_KERNEL::NORM_SEG3)
702 throw INTERP_KERNEL::Exception("MEDFileFieldLin2QuadVisitor::newPerMeshPerTypePerDisc : invalid situation where SEG3 expected !");
703 MCAuto<DataArrayIdType> midPts,cellSeg3Ids,matrix;
705 DataArrayIdType *nodeConn(allSeg3->getNodalConnectivity());
706 nodeConn->rearrange(3);
708 std::vector<std::size_t> v(1,2);
709 midPts=nodeConn->keepSelectedComponents(v);
711 cellSeg3Ids=DataArrayIdType::FindPermutationFromFirstToSecond(midPts,newPtsIds);
713 std::vector<std::size_t> v(2); v[0]=0; v[1]=1;
714 MCAuto<DataArrayIdType> tmp(nodeConn->keepSelectedComponents(v));
715 matrix=tmp->selectByTupleId(cellSeg3Ids->begin(),cellSeg3Ids->end());
717 nodeConn->rearrange(1);
719 MCAuto<DataArrayIdType> pflq;
722 std::vector<const DataArrayIdType *> vs(2);
723 vs[0]=pfl; vs[1]=newPtsIds;
724 pflq=DataArrayIdType::Aggregate(vs);
725 pflq->setName(pflName);
727 PFLData pdata(matrix,pflq,newPtsIds->getNumberOfTuples());
728 _cache[pflName]=pdata;
729 updateData(pmtdToModify,pdata.getNbOfAddPtsInPfl());
732 void MEDFileFieldLin2QuadVisitor::updateData(MEDFileFieldPerMeshPerTypePerDisc *pmtd, mcIdType deltaNbNodes)
734 pmtd->incrementNbOfVals(deltaNbNodes);
737 void MEDFileFieldLin2QuadVisitor::newPerMeshPerTypeEntry(const MEDFileFieldPerMeshPerTypeCommon *pmpt)
739 const MEDFileFieldPerMeshPerType *pmpt2(dynamic_cast<const MEDFileFieldPerMeshPerType *>(pmpt));
741 throw INTERP_KERNEL::Exception("MEDFileFieldLin2QuadVisitor::newPerMeshPerTypeEntry : not managed for structure elements !");
742 if(pmpt2->getNumberOfLoc()!=1)
743 throw INTERP_KERNEL::Exception("MEDFileFieldLin2QuadVisitor::newPerMeshPerTypeEntry : not managed for multi discr per timestep !");
744 _gt=pmpt->getGeoType();
747 void MEDFileFieldLin2QuadVisitor::newMeshEntry(const MEDFileFieldPerMesh *fpm)
749 if(fpm->getMeshName()!=_lin->getName())
750 throw INTERP_KERNEL::Exception("MEDFileFieldLin2QuadVisitor::newMeshEntry : mismatch into meshName !");
753 void MEDFileFieldLin2QuadVisitor::newTimeStepEntry(const MEDFileAnyTypeField1TSWithoutSDA *ts)
755 _1ts_update_requested=false; _pfls_to_be_updated.clear();
758 const MEDFileField1TSWithoutSDA *tsd(dynamic_cast<const MEDFileField1TSWithoutSDA *>(ts));
761 MCAuto<MEDFileAnyTypeField1TSWithoutSDA> contentCpy(ts->deepCopy());
762 MCAuto<MEDFileField1TSWithoutSDA> contentCpy2(DynamicCastSafe<MEDFileAnyTypeField1TSWithoutSDA,MEDFileField1TSWithoutSDA>(contentCpy));
763 if(contentCpy2.isNull())
765 _cur_f1ts=MEDFileField1TS::New(*contentCpy2,true);
766 _cur_f1ts->deepCpyGlobs(*_lin_globs);
769 void MEDFileFieldLin2QuadVisitor::endTimeStepEntry(const MEDFileAnyTypeField1TSWithoutSDA *ts)
771 if(_cur_f1ts.isNull())
773 if(_1ts_update_requested)
775 MCAuto<DataArrayIdType> matrix,oldPfl;
776 for(std::vector<std::string>::const_iterator it=_pfls_to_be_updated.begin();it!=_pfls_to_be_updated.end();it++)
778 std::map< std::string, PFLData >::const_iterator it2(_cache.find(*it));
779 if(it2==_cache.end())
780 throw INTERP_KERNEL::Exception("MEDFileFieldLin2QuadVisitor::endTimeStepEntry : invalid situation !");
781 matrix=(*it2).second.getMatrix();
784 int locId(_cur_f1ts->getProfileId(*it));
785 oldPfl.takeRef(_cur_f1ts->getProfile(*it));
787 std::vector<int> locToKill(1,locId);
788 _cur_f1ts->killProfileIds(locToKill);
790 _cur_f1ts->appendProfile((*it2).second.getProfile());
792 DataArrayDouble *arr(_cur_f1ts->getUndergroundDataArray());
793 MCAuto<DataArrayDouble> res;
795 std::vector<std::size_t> v(1,0),v2(1,1);
796 MCAuto<DataArrayIdType> pts0(matrix->keepSelectedComponents(v));
797 MCAuto<DataArrayIdType> pts1(matrix->keepSelectedComponents(v2));
798 if(oldPfl.isNotNull())
800 pts0=oldPfl->findIdForEach(pts0->begin(),pts0->end());
801 pts1=oldPfl->findIdForEach(pts1->begin(),pts1->end());
803 MCAuto<DataArrayDouble> part0(arr->selectByTupleId(*pts0));
804 MCAuto<DataArrayDouble> part1(arr->selectByTupleId(*pts1));
805 res=DataArrayDouble::Add(part0,part1);
806 res->applyLin(0.5,0.);
808 res=DataArrayDouble::Aggregate(arr,res);
809 _cur_f1ts->setArray(res);
811 if(_cur_fmts.isNotNull())
812 { _cur_fmts->pushBackTimeStep(_cur_f1ts); }
813 _1ts_update_requested=false;
817 * \a newQuad is expected to be the result of MEDFileUMesh::linearToQuadratic of \a oldLin
819 MCAuto<MEDFileFields> MEDFileFields::linearToQuadratic(const MEDFileMeshes *oldLin, const MEDFileMeshes *newQuad) const
821 if(!oldLin || !newQuad)
822 throw INTERP_KERNEL::Exception("MEDFileFields::linearToQuadratic : input meshes must be non NULL !");
823 MCAuto<MEDFileFields> ret(MEDFileFields::New());
824 for(int i=0;i<oldLin->getNumberOfMeshes();i++)
826 MEDFileMesh *mm(oldLin->getMeshAtPos(i));
829 MEDFileUMesh *mmu(dynamic_cast<MEDFileUMesh *>(mm));
832 MEDFileMesh *mmq(newQuad->getMeshWithName(mmu->getName()));
833 MEDFileUMesh *mmqu(dynamic_cast<MEDFileUMesh *>(mmq));
836 std::ostringstream oss; oss << "MEDFileFields::linearToQuadratic : mismatch of name between input meshes for name \"" << mmu->getName() << "\"";
837 throw INTERP_KERNEL::Exception(oss.str());
839 MEDFileFieldLin2QuadVisitor vis(mmu,mmqu,this,ret);
845 MEDFileAnyTypeFieldMultiTS *MEDFileFields::getFieldAtPos(int i) const
847 if(i<0 || i>=(int)_fields.size())
849 std::ostringstream oss; oss << "MEDFileFields::getFieldAtPos : Invalid given id in input (" << i << ") should be in [0," << _fields.size() << ") !";
850 throw INTERP_KERNEL::Exception(oss.str());
852 const MEDFileAnyTypeFieldMultiTSWithoutSDA *fmts=_fields[i];
855 MCAuto<MEDFileAnyTypeFieldMultiTS> ret;
856 const MEDFileFieldMultiTSWithoutSDA *fmtsC(dynamic_cast<const MEDFileFieldMultiTSWithoutSDA *>(fmts));
857 const MEDFileInt32FieldMultiTSWithoutSDA *fmtsC2(dynamic_cast<const MEDFileInt32FieldMultiTSWithoutSDA *>(fmts));
858 const MEDFileInt64FieldMultiTSWithoutSDA *fmtsC4(dynamic_cast<const MEDFileInt64FieldMultiTSWithoutSDA *>(fmts));
859 const MEDFileFloatFieldMultiTSWithoutSDA *fmtsC3(dynamic_cast<const MEDFileFloatFieldMultiTSWithoutSDA *>(fmts));
861 ret=MEDFileFieldMultiTS::New(*fmtsC,false);
863 ret=MEDFileInt32FieldMultiTS::New(*fmtsC2,false);
865 ret=MEDFileInt64FieldMultiTS::New(*fmtsC4,false);
867 ret=MEDFileFloatFieldMultiTS::New(*fmtsC3,false);
870 std::ostringstream oss; oss << "MEDFileFields::getFieldAtPos : At pos #" << i << " field is neither double (FLOAT64) nor float (FLOAT32) nor integer (INT32) nor integer (INT64) !";
871 throw INTERP_KERNEL::Exception(oss.str());
873 ret->shallowCpyGlobs(*this);
878 * Return a shallow copy of \a this reduced to the fields ids defined in [ \a startIds , endIds ).
879 * This method is accessible in python using __getitem__ with a list in input.
880 * \return a new object that the caller should deal with.
882 MEDFileFields *MEDFileFields::buildSubPart(const int *startIds, const int *endIds) const
884 MCAuto<MEDFileFields> ret=shallowCpy();
885 std::size_t sz=std::distance(startIds,endIds);
886 std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> > fields(sz);
888 for(const int *i=startIds;i!=endIds;i++,j++)
890 if(*i<0 || *i>=(int)_fields.size())
892 std::ostringstream oss; oss << "MEDFileFields::buildSubPart : Invalid given id in input (" << *i << ") should be in [0," << _fields.size() << ") !";
893 throw INTERP_KERNEL::Exception(oss.str());
895 fields[j]=_fields[*i];
901 MEDFileAnyTypeFieldMultiTS *MEDFileFields::getFieldWithName(const std::string& fieldName) const
903 return getFieldAtPos(getPosFromFieldName(fieldName));
907 * This method removes, if any, fields in \a this having no time steps.
908 * If there is one or more than one such field in \a this true is returned and those fields will not be referenced anymore in \a this.
910 * If false is returned \a this does not contain such fields. If false is returned this method can be considered as const.
912 bool MEDFileFields::removeFieldsWithoutAnyTimeStep()
914 std::vector<MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> > newFields;
915 for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++)
917 const MEDFileAnyTypeFieldMultiTSWithoutSDA *elt(*it);
920 if(elt->getNumberOfTS()>0)
921 newFields.push_back(*it);
924 if(_fields.size()==newFields.size())
931 * This method returns a new object containing part of \a this fields lying on mesh name specified by the input parameter \a meshName.
932 * This method can be seen as a filter applied on \a this, that returns an object containing
933 * reduced the list of fields compared to those in \a this. The returned object is a new object but the object on which it lies are only
934 * shallow copied from \a this.
936 * \param [in] meshName - the name of the mesh on w
937 * \return a new object that the caller should deal with.
939 MEDFileFields *MEDFileFields::partOfThisLyingOnSpecifiedMeshName(const std::string& meshName) const
941 MCAuto<MEDFileFields> ret(MEDFileFields::New());
942 for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++)
944 const MEDFileAnyTypeFieldMultiTSWithoutSDA *cur(*it);
947 if(cur->getMeshName()==meshName)
950 MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> cur2(const_cast<MEDFileAnyTypeFieldMultiTSWithoutSDA *>(cur));
951 ret->_fields.push_back(cur2);
954 ret->shallowCpyOnlyUsedGlobs(*this);
959 * This method returns a new object containing part of \a this fields lying ** exactly ** on the time steps specified by input parameter \a timeSteps.
960 * Input time steps are specified using a pair of integer (iteration, order).
961 * This method can be seen as a filter applied on \a this, that returns an object containing the same number of fields than those in \a this,
962 * but for each multitimestep only the time steps in \a timeSteps are kept.
963 * Typically the input parameter \a timeSteps comes from the call of MEDFileFields::getCommonIterations.
965 * The returned object points to shallow copy of elements in \a this.
967 * \param [in] timeSteps - the time steps given by a vector of pair of integers (iteration,order)
968 * \throw If there is a field in \a this that is \b not defined on a time step in the input \a timeSteps.
969 * \sa MEDFileFields::getCommonIterations, MEDFileFields::partOfThisNotLyingOnSpecifiedTimeSteps
971 MEDFileFields *MEDFileFields::partOfThisLyingOnSpecifiedTimeSteps(const std::vector< std::pair<int,int> >& timeSteps) const
973 MCAuto<MEDFileFields> ret(MEDFileFields::New());
974 for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++)
976 const MEDFileAnyTypeFieldMultiTSWithoutSDA *cur(*it);
979 MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> elt=cur->partOfThisLyingOnSpecifiedTimeSteps(timeSteps);
980 ret->_fields.push_back(elt);
982 ret->shallowCpyOnlyUsedGlobs(*this);
987 * \sa MEDFileFields::getCommonIterations, MEDFileFields::partOfThisLyingOnSpecifiedTimeSteps
989 MEDFileFields *MEDFileFields::partOfThisNotLyingOnSpecifiedTimeSteps(const std::vector< std::pair<int,int> >& timeSteps) const
991 MCAuto<MEDFileFields> ret=MEDFileFields::New();
992 for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++)
994 const MEDFileAnyTypeFieldMultiTSWithoutSDA *cur(*it);
997 MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> elt=cur->partOfThisNotLyingOnSpecifiedTimeSteps(timeSteps);
998 if(elt->getNumberOfTS()!=0)
999 ret->_fields.push_back(elt);
1001 ret->shallowCpyOnlyUsedGlobs(*this);
1005 bool MEDFileFields::presenceOfStructureElements() const
1007 for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++)
1008 if((*it).isNotNull())
1009 if((*it)->presenceOfStructureElements())
1014 void MEDFileFields::killStructureElements()
1016 std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> > ret;
1017 for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::iterator it=_fields.begin();it!=_fields.end();it++)
1018 if((*it).isNotNull())
1020 if((*it)->presenceOfStructureElements())
1022 if(!(*it)->onlyStructureElements())
1024 (*it)->killStructureElements();
1036 void MEDFileFields::keepOnlyStructureElements()
1038 std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> > ret;
1039 for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::iterator it=_fields.begin();it!=_fields.end();it++)
1040 if((*it).isNotNull())
1042 if((*it)->presenceOfStructureElements())
1044 if(!(*it)->onlyStructureElements())
1045 (*it)->keepOnlyStructureElements();
1052 void MEDFileFields::keepOnlyOnMeshSE(const std::string& meshName, const std::string& seName)
1054 std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> > ret;
1055 for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::iterator it=_fields.begin();it!=_fields.end();it++)
1056 if((*it).isNotNull())
1058 if((*it)->getMeshName()!=meshName)
1060 std::vector< std::pair<std::string,std::string> > ps;
1061 (*it)->getMeshSENames(ps);
1062 std::pair<std::string,std::string> p(meshName,seName);
1063 if(std::find(ps.begin(),ps.end(),p)!=ps.end())
1064 (*it)->keepOnlyOnSE(seName);
1070 void MEDFileFields::getMeshSENames(std::vector< std::pair<std::string,std::string> >& ps) const
1072 for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++)
1073 if((*it).isNotNull())
1074 (*it)->getMeshSENames(ps);
1077 void MEDFileFields::blowUpSE(MEDFileMeshes *ms, const MEDFileStructureElements *ses)
1079 MEDFileBlowStrEltUp::DealWithSE(this,ms,ses);
1080 this->aggregateFieldsOnSameMeshes(ms);
1084 * This method is dedicated to explosed Structured Elements that can lead to exotic situation.
1085 * Especially when there are several structured elements for a same field.
1087 * This method looks into meshes into \a ms if there is presence of multiple mesh having same name.
1088 * If so, these meshes are aggregated in the same order than \a ms.
1089 * The fields in \a this lying on the same meshName are also aggregated in the same order than \a this.
1091 void MEDFileFields::aggregateFieldsOnSameMeshes(MEDFileMeshes *ms)
1094 THROW_IK_EXCEPTION("MEDFileFields::aggregateFieldsOnSameMeshes : ms is nullptr !");
1096 std::vector<std::string> msNames(ms->getMeshesNames());
1097 std::set<std::string> msNamesSet(msNames.begin(),msNames.end());
1098 if(msNames.size() == msNamesSet.size())
1101 std::map<std::string,std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA>> > fsByName;
1102 for(auto fmts : _fields)
1104 fsByName[fmts->getMeshName()].push_back(fmts);
1106 std::vector<std::string> fieldsNamesToBeAggregated;
1107 std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> > otherFields;
1108 std::set<std::string> expectedMeshNamesToMerge;
1109 for(auto fieldsWithSame : fsByName)
1111 if(fieldsWithSame.second.size() > 1)
1113 fieldsNamesToBeAggregated.push_back(fieldsWithSame.first);
1114 std::set< std::string > zeMeshNames;
1115 for(auto fmtsWithSameName : fieldsWithSame.second)
1116 zeMeshNames.insert(fmtsWithSameName->getMeshName());
1117 if(zeMeshNames.size()!=1)
1118 THROW_IK_EXCEPTION("MEDFileFields::aggregateFieldsOnSameMeshes : Presence of multiple MultiTS instances with same name but lying on same meshName. Looks bad !");
1119 std::string meshNameToMerge = *zeMeshNames.begin();
1120 if(expectedMeshNamesToMerge.find(meshNameToMerge) != expectedMeshNamesToMerge.end())
1121 THROW_IK_EXCEPTION("MEDFileFields::aggregateFieldsOnSameMeshes : unexpected situation ! Error in implementation !");
1122 expectedMeshNamesToMerge.insert(*zeMeshNames.begin());
1126 otherFields.push_back(fieldsWithSame.second.front());
1129 for(auto fieldNameToBeAggregated : fieldsNamesToBeAggregated)
1131 auto base_fs = fsByName[fieldNameToBeAggregated].front();
1132 auto fieldsToBeAggregated = fsByName[fieldNameToBeAggregated];
1133 std::vector< std::vector< std::pair<int,mcIdType> > > dtsToAggregate;
1134 std::vector< MCAuto<MEDFileAnyTypeFieldMultiTS> > eltsToAggregate;
1135 for(auto fieldToBeAggregated : fieldsToBeAggregated)
1137 std::vector< std::pair<std::pair<INTERP_KERNEL::NormalizedCellType,int>,std::pair<mcIdType,mcIdType> > > entries;
1138 int iteration,order;
1140 auto dtits = fieldToBeAggregated->getIterations();
1141 iteration = dtits.front().first;
1142 order = dtits.front().second;
1144 fieldToBeAggregated->getUndergroundDataArrayExt(iteration,order,entries);
1145 std::vector< std::pair<int,mcIdType> > dtsToPush;
1146 for(auto entry : entries)
1147 dtsToPush.push_back({entry.first.first,entry.second.second-entry.second.first});
1148 dtsToAggregate.push_back(dtsToPush);
1149 MCAuto<MEDFileAnyTypeFieldMultiTS> eltToAggregate = MEDFileAnyTypeFieldMultiTS::BuildNewInstanceFromContent(fieldToBeAggregated);
1150 eltsToAggregate.push_back(eltToAggregate);
1152 MCAuto<MEDFileAnyTypeFieldMultiTS> gg = MEDFileAnyTypeFieldMultiTS::Aggregate(FromVecAutoToVecOfConst(eltsToAggregate),dtsToAggregate);
1153 gg->setMeshName(base_fs->getMeshName());
1154 otherFields.push_back(gg->getContent());
1156 // now deal with meshes
1157 std::map<std::string,std::vector< MEDFileMesh *> > msByName;
1158 for(auto iMesh = 0 ; iMesh < ms->getNumberOfMeshes() ; ++iMesh)
1160 auto curMesh = ms->getMeshAtPos(iMesh);
1161 msByName[curMesh->getName()].push_back(curMesh);
1163 std::set<std::string> meshesNamesToBeAggregated;
1164 std::vector< MCAuto<MEDFileMesh> > otherMeshes;
1165 for(auto msWithSameName : msByName)
1167 if(msWithSameName.second.size()>1)
1168 meshesNamesToBeAggregated.insert(msWithSameName.first);
1171 otherMeshes.push_back( MCAuto<MEDFileMesh>::TakeRef(msWithSameName.second.front()) );
1174 if(meshesNamesToBeAggregated != expectedMeshNamesToMerge)
1175 THROW_IK_EXCEPTION("MEDFileFields::aggregateFieldsOnSameMeshes : mismatch between meshes to be aggregated and meshnames into fields to be aggregated");
1176 std::vector<const DataArrayDouble *> coos;
1177 for(auto meshNameToBeAggregated : meshesNamesToBeAggregated)
1179 for(auto curMesh : msByName[meshNameToBeAggregated])
1181 if(!curMesh->getNonEmptyLevels().empty())
1182 THROW_IK_EXCEPTION("MEDFileFields::aggregateFieldsOnSameMeshes : only meshes without cells supported.");
1183 MEDFileUMesh *curMeshU(dynamic_cast<MEDFileUMesh *>(curMesh));
1185 THROW_IK_EXCEPTION("MEDFileFields::aggregateFieldsOnSameMeshes : only unstructured mesh supported.");
1186 coos.push_back(curMeshU->getCoords());
1188 MCAuto<DataArrayDouble> coo=DataArrayDouble::Aggregate(coos);
1189 MCAuto<MEDFileUMesh> gg = MEDFileUMesh::New();
1190 gg->setName(meshNameToBeAggregated);
1192 otherMeshes.push_back(DynamicCast<MEDFileUMesh,MEDFileMesh>(gg));
1194 // until this point nothing has changed in \a this nor in \a ms as if a const method.
1196 for(auto mesh : otherMeshes)
1198 _fields = otherFields;
1201 MCAuto<MEDFileFields> MEDFileFields::partOfThisOnStructureElements() const
1203 MCAuto<MEDFileFields> ret(deepCopy());
1204 ret->keepOnlyStructureElements();
1208 MCAuto<MEDFileFields> MEDFileFields::partOfThisLyingOnSpecifiedMeshSEName(const std::string& meshName, const std::string& seName) const
1210 MCAuto<MEDFileFields> ret(deepCopy());
1211 ret->keepOnlyOnMeshSE(meshName,seName);
1215 void MEDFileFields::aggregate(const MEDFileFields& other)
1217 int nbFieldsToAdd(other.getNumberOfFields());
1218 std::vector<std::string> fsn(getFieldsNames());
1219 for(int i=0;i<nbFieldsToAdd;i++)
1221 MCAuto<MEDFileAnyTypeFieldMultiTS> elt(other.getFieldAtPos(i));
1222 std::string name(elt->getName());
1223 if(std::find(fsn.begin(),fsn.end(),name)!=fsn.end())
1225 std::ostringstream oss; oss << "MEDFileFields::aggregate : name \"" << name << "\" already appears !";
1226 throw INTERP_KERNEL::Exception(oss.str());
1232 MEDFileFieldsIterator *MEDFileFields::iterator()
1234 return new MEDFileFieldsIterator(this);
1237 int MEDFileFields::getPosFromFieldName(const std::string& fieldName) const
1239 std::string tmp(fieldName);
1240 std::vector<std::string> poss;
1241 for(unsigned int i=0;i<_fields.size();i++)
1243 const MEDFileAnyTypeFieldMultiTSWithoutSDA *f(_fields[i]);
1246 std::string fname(f->getName());
1250 poss.push_back(fname);
1253 std::ostringstream oss; oss << "MEDFileFields::getPosFromFieldName : impossible to find field '" << tmp << "' in this ! Possibilities are : ";
1254 std::copy(poss.begin(),poss.end(),std::ostream_iterator<std::string>(oss,", "));
1256 throw INTERP_KERNEL::Exception(oss.str());
1259 MEDFileFieldsIterator::MEDFileFieldsIterator(MEDFileFields *fs):_fs(fs),_iter_id(0),_nb_iter(0)
1264 _nb_iter=fs->getNumberOfFields();
1268 MEDFileFieldsIterator::~MEDFileFieldsIterator()
1272 MEDFileAnyTypeFieldMultiTS *MEDFileFieldsIterator::nextt()
1274 if(_iter_id<_nb_iter)
1276 MEDFileFields *fs(_fs);
1278 return fs->getFieldAtPos(_iter_id++);