1 // Copyright (C) 2007-2016 CEA/DEN, EDF R&D
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 extern INTERP_KERNEL::NormalizedCellType typmai2[MED_N_CELL_FIXED_GEO];
39 extern med_geometry_type typmainoeud[1];
40 extern med_geometry_type typmai3[34];
42 using namespace MEDCoupling;
46 MEDFileFields *MEDFileFields::New()
48 return new MEDFileFields;
51 MEDFileFields *MEDFileFields::New(const std::string& fileName, bool loadAll)
53 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
54 return New(fid,loadAll);
57 MEDFileFields *MEDFileFields::NewAdv(const std::string& fileName, bool loadAll, const MEDFileEntities *entities)
59 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
60 return NewAdv(fid,loadAll,entities);
63 MEDFileFields *MEDFileFields::NewAdv(med_idt fid, bool loadAll, const MEDFileEntities *entities)
65 return new MEDFileFields(fid,loadAll,0,entities);
68 MEDFileFields *MEDFileFields::NewWithDynGT(const std::string& fileName, const MEDFileStructureElements *se, bool loadAll)
70 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
71 return NewWithDynGT(fid,se,loadAll);
74 MEDFileFields *MEDFileFields::NewWithDynGT(med_idt fid, const MEDFileStructureElements *se, bool loadAll)
77 throw INTERP_KERNEL::Exception("MEDFileFields::NewWithDynGT : null struct element pointer !");
78 INTERP_KERNEL::AutoCppPtr<MEDFileEntities> entities(MEDFileEntities::BuildFrom(*se));
79 return new MEDFileFields(fid,loadAll,0,entities);
82 MEDFileFields *MEDFileFields::New(med_idt fid, bool loadAll)
84 return new MEDFileFields(fid,loadAll,0,0);
87 MEDFileFields *MEDFileFields::LoadPartOf(const std::string& fileName, bool loadAll, const MEDFileMeshes *ms)
89 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
90 return new MEDFileFields(fid,loadAll,ms,0);
93 MEDFileFields *MEDFileFields::LoadSpecificEntities(const std::string& fileName, const std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> >& entities, bool loadAll)
95 MEDFileUtilities::CheckFileForRead(fileName);
96 INTERP_KERNEL::AutoCppPtr<MEDFileEntities> ent(new MEDFileStaticEntities(entities));
97 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
98 return new MEDFileFields(fid,loadAll,0,ent);
101 std::size_t MEDFileFields::getHeapMemorySizeWithoutChildren() const
103 std::size_t ret(MEDFileFieldGlobsReal::getHeapMemorySizeWithoutChildren());
104 ret+=_fields.capacity()*sizeof(MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA>);
108 std::vector<const BigMemoryObject *> MEDFileFields::getDirectChildrenWithNull() const
110 std::vector<const BigMemoryObject *> ret;
111 for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++)
112 ret.push_back((const MEDFileAnyTypeFieldMultiTSWithoutSDA *)*it);
116 MEDFileFields *MEDFileFields::deepCopy() const
118 MCAuto<MEDFileFields> ret(shallowCpy());
120 for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++,i++)
122 if((const MEDFileAnyTypeFieldMultiTSWithoutSDA*)*it)
123 ret->_fields[i]=(*it)->deepCopy();
125 ret->deepCpyGlobs(*this);
129 MEDFileFields *MEDFileFields::shallowCpy() const
131 return new MEDFileFields(*this);
135 * 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
136 * 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.
137 * If \a areThereSomeForgottenTS is set to true, only the sorted intersection of time steps present for all fields in \a this will be returned.
139 * \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.
140 * \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.
142 * \sa MEDFileFields::partOfThisLyingOnSpecifiedTimeSteps, MEDFileFields::partOfThisNotLyingOnSpecifiedTimeSteps
144 std::vector< std::pair<int,int> > MEDFileFields::getCommonIterations(bool& areThereSomeForgottenTS) const
146 std::set< std::pair<int,int> > s;
148 areThereSomeForgottenTS=false;
149 for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++)
151 if(!(const MEDFileAnyTypeFieldMultiTSWithoutSDA*)*it)
153 std::vector< std::pair<int,int> > v=(*it)->getIterations();
154 std::set< std::pair<int,int> > s1; std::copy(v.begin(),v.end(),std::inserter(s1,s1.end()));
156 { s=s1; firstShot=false; }
159 std::set< std::pair<int,int> > s2; std::set_intersection(s.begin(),s.end(),s1.begin(),s1.end(),std::inserter(s2,s2.end()));
161 areThereSomeForgottenTS=true;
165 std::vector< std::pair<int,int> > ret;
166 std::copy(s.begin(),s.end(),std::back_insert_iterator< std::vector< std::pair<int,int> > >(ret));
170 int MEDFileFields::getNumberOfFields() const
172 return _fields.size();
175 std::vector<std::string> MEDFileFields::getFieldsNames() const
177 std::vector<std::string> ret(_fields.size());
179 for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++,i++)
181 const MEDFileAnyTypeFieldMultiTSWithoutSDA *f=(*it);
188 std::ostringstream oss; oss << "MEDFileFields::getFieldsNames : At rank #" << i << " field is not defined !";
189 throw INTERP_KERNEL::Exception(oss.str());
195 std::vector<std::string> MEDFileFields::getMeshesNames() const
197 std::vector<std::string> ret;
198 for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++)
200 const MEDFileAnyTypeFieldMultiTSWithoutSDA *cur(*it);
202 ret.push_back(cur->getMeshName());
207 std::string MEDFileFields::simpleRepr() const
209 std::ostringstream oss;
210 oss << "(*****************)\n(* MEDFileFields *)\n(*****************)\n\n";
215 void MEDFileFields::simpleRepr(int bkOffset, std::ostream& oss) const
217 int nbOfFields(getNumberOfFields());
218 std::string startLine(bkOffset,' ');
219 oss << startLine << "There are " << nbOfFields << " fields in this :" << std::endl;
221 for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++,i++)
223 const MEDFileAnyTypeFieldMultiTSWithoutSDA *cur=(*it);
226 oss << startLine << " - # "<< i << " has the following name : \"" << cur->getName() << "\"." << std::endl;
230 oss << startLine << " - not defined !" << std::endl;
234 for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++,i++)
236 const MEDFileAnyTypeFieldMultiTSWithoutSDA *cur=(*it);
237 std::string chapter(17,'0'+i);
238 oss << startLine << chapter << std::endl;
241 cur->simpleRepr(bkOffset+2,oss,i);
245 oss << startLine << " - not defined !" << std::endl;
247 oss << startLine << chapter << std::endl;
249 simpleReprGlobs(oss);
252 MEDFileFields::MEDFileFields()
256 MEDFileFields::MEDFileFields(med_idt fid, bool loadAll, const MEDFileMeshes *ms, const MEDFileEntities *entities)
257 try:MEDFileFieldGlobsReal(fid)
259 int nbFields(MEDnField(fid));
260 _fields.resize(nbFields);
261 med_field_type typcha;
262 for(int i=0;i<nbFields;i++)
264 std::vector<std::string> infos;
265 std::string fieldName,dtunit,meshName;
266 int nbOfStep(MEDFileAnyTypeField1TS::LocateField2(fid,i,false,fieldName,typcha,infos,dtunit,meshName));
271 _fields[i]=MEDFileFieldMultiTSWithoutSDA::New(fid,fieldName,meshName,typcha,infos,nbOfStep,dtunit,loadAll,ms,entities);
276 _fields[i]=MEDFileIntFieldMultiTSWithoutSDA::New(fid,fieldName,meshName,typcha,infos,nbOfStep,dtunit,loadAll,ms,entities);
281 _fields[i]=MEDFileFloatFieldMultiTSWithoutSDA::New(fid,fieldName,meshName,typcha,infos,nbOfStep,dtunit,loadAll,ms,entities);
286 if(sizeof(med_int)==sizeof(int))
288 _fields[i]=MEDFileIntFieldMultiTSWithoutSDA::New(fid,fieldName,meshName,typcha,infos,nbOfStep,dtunit,loadAll,ms,entities);
294 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] !";
295 throw INTERP_KERNEL::Exception(oss.str());
299 loadAllGlobals(fid,entities);
301 catch(INTERP_KERNEL::Exception& e)
306 void MEDFileFields::writeLL(med_idt fid) const
309 writeGlobals(fid,*this);
310 for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++,i++)
312 const MEDFileAnyTypeFieldMultiTSWithoutSDA *elt=*it;
315 std::ostringstream oss; oss << "MEDFileFields::write : at rank #" << i << "/" << _fields.size() << " field is empty !";
316 throw INTERP_KERNEL::Exception(oss.str());
318 elt->writeLL(fid,*this);
323 * This method alloc the arrays and load potentially huge arrays contained in this field.
324 * This method should be called when a MEDFileAnyTypeFieldMultiTS::New constructor has been with false as the last parameter.
325 * This method can be also called to refresh or reinit values from a file.
327 * \throw If the fileName is not set or points to a non readable MED file.
329 void MEDFileFields::loadArrays()
331 if(getFileName().empty())
332 throw INTERP_KERNEL::Exception("MEDFileFields::loadArrays : the structure does not come from a file !");
333 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(getFileName()));
334 for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::iterator it=_fields.begin();it!=_fields.end();it++)
336 MEDFileAnyTypeFieldMultiTSWithoutSDA *elt(*it);
338 elt->loadBigArraysRecursively(fid,*elt);
343 * This method behaves as MEDFileFields::loadArrays does, the first call, if \a this was built using a file without loading big arrays.
344 * But once data loaded once, this method does nothing.
346 * \throw If the fileName is not set or points to a non readable MED file.
347 * \sa MEDFileFields::loadArrays, MEDFileFields::unloadArrays
349 void MEDFileFields::loadArraysIfNecessary()
351 if(!getFileName().empty())
353 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(getFileName()));
354 for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::iterator it=_fields.begin();it!=_fields.end();it++)
356 MEDFileAnyTypeFieldMultiTSWithoutSDA *elt(*it);
358 elt->loadBigArraysRecursivelyIfNecessary(fid,*elt);
364 * This method releases potentially big data arrays and so returns to the same heap memory than status loaded with 'loadAll' parameter set to false.
365 * \b WARNING, this method does release arrays even if \a this does not come from a load of a MED file.
366 * So this method can lead to a loss of data. If you want to unload arrays safely call MEDFileFields::unloadArraysWithoutDataLoss instead.
368 * \sa MEDFileFields::loadArrays, MEDFileFields::loadArraysIfNecessary, MEDFileFields::unloadArraysWithoutDataLoss
370 void MEDFileFields::unloadArrays()
372 for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::iterator it=_fields.begin();it!=_fields.end();it++)
374 MEDFileAnyTypeFieldMultiTSWithoutSDA *elt(*it);
381 * 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.
382 * This method is the symmetrical method of MEDFileFields::loadArraysIfNecessary.
383 * This method is useful to reduce \b safely amount of heap memory necessary for \a this by using MED file as database.
385 * \sa MEDFileFields::loadArraysIfNecessary
387 void MEDFileFields::unloadArraysWithoutDataLoss()
389 if(!getFileName().empty())
393 std::vector<std::string> MEDFileFields::getPflsReallyUsed() const
395 std::vector<std::string> ret;
396 std::set<std::string> ret2;
397 for(std::vector< MCAuto< MEDFileAnyTypeFieldMultiTSWithoutSDA > >::const_iterator it=_fields.begin();it!=_fields.end();it++)
399 std::vector<std::string> tmp=(*it)->getPflsReallyUsed2();
400 for(std::vector<std::string>::const_iterator it2=tmp.begin();it2!=tmp.end();it2++)
401 if(ret2.find(*it2)==ret2.end())
410 std::vector<std::string> MEDFileFields::getLocsReallyUsed() const
412 std::vector<std::string> ret;
413 std::set<std::string> ret2;
414 for(std::vector< MCAuto< MEDFileAnyTypeFieldMultiTSWithoutSDA > >::const_iterator it=_fields.begin();it!=_fields.end();it++)
416 std::vector<std::string> tmp((*it)->getLocsReallyUsed2());
417 for(std::vector<std::string>::const_iterator it2=tmp.begin();it2!=tmp.end();it2++)
418 if(ret2.find(*it2)==ret2.end())
427 std::vector<std::string> MEDFileFields::getPflsReallyUsedMulti() const
429 std::vector<std::string> ret;
430 for(std::vector< MCAuto< MEDFileAnyTypeFieldMultiTSWithoutSDA > >::const_iterator it=_fields.begin();it!=_fields.end();it++)
432 std::vector<std::string> tmp((*it)->getPflsReallyUsedMulti2());
433 ret.insert(ret.end(),tmp.begin(),tmp.end());
438 std::vector<std::string> MEDFileFields::getLocsReallyUsedMulti() const
440 std::vector<std::string> ret;
441 for(std::vector< MCAuto< MEDFileAnyTypeFieldMultiTSWithoutSDA > >::const_iterator it=_fields.begin();it!=_fields.end();it++)
443 std::vector<std::string> tmp((*it)->getLocsReallyUsed2());
444 ret.insert(ret.end(),tmp.begin(),tmp.end());
449 void MEDFileFields::changePflsRefsNamesGen(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif)
451 for(std::vector< MCAuto< MEDFileAnyTypeFieldMultiTSWithoutSDA > >::iterator it=_fields.begin();it!=_fields.end();it++)
452 (*it)->changePflsRefsNamesGen2(mapOfModif);
455 void MEDFileFields::changeLocsRefsNamesGen(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)->changeLocsRefsNamesGen2(mapOfModif);
461 void MEDFileFields::resize(int newSize)
463 _fields.resize(newSize);
466 void MEDFileFields::pushFields(const std::vector<MEDFileAnyTypeFieldMultiTS *>& fields)
468 for(std::vector<MEDFileAnyTypeFieldMultiTS *>::const_iterator it=fields.begin();it!=fields.end();it++)
472 void MEDFileFields::pushField(MEDFileAnyTypeFieldMultiTS *field)
475 throw INTERP_KERNEL::Exception("MEDFileFields::pushMesh : invalid input pointer ! should be different from 0 !");
476 _fields.push_back(field->getContent());
477 appendGlobs(*field,1e-12);
480 void MEDFileFields::setFieldAtPos(int i, MEDFileAnyTypeFieldMultiTS *field)
483 throw INTERP_KERNEL::Exception("MEDFileFields::setFieldAtPos : invalid input pointer ! should be different from 0 !");
484 if(i>=(int)_fields.size())
486 _fields[i]=field->getContent();
487 appendGlobs(*field,1e-12);
490 void MEDFileFields::destroyFieldAtPos(int i)
492 destroyFieldsAtPos(&i,&i+1);
495 void MEDFileFields::destroyFieldsAtPos(const int *startIds, const int *endIds)
497 std::vector<bool> b(_fields.size(),true);
498 for(const int *i=startIds;i!=endIds;i++)
500 if(*i<0 || *i>=(int)_fields.size())
502 std::ostringstream oss; oss << "MEDFileFields::destroyFieldsAtPos : Invalid given id in input (" << *i << ") should be in [0," << _fields.size() << ") !";
503 throw INTERP_KERNEL::Exception(oss.str());
507 std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> > fields(std::count(b.begin(),b.end(),true));
509 for(std::size_t i=0;i<_fields.size();i++)
511 fields[j++]=_fields[i];
515 void MEDFileFields::destroyFieldsAtPos2(int bg, int end, int step)
517 static const char msg[]="MEDFileFields::destroyFieldsAtPos2";
518 int nbOfEntriesToKill(DataArrayInt::GetNumberOfItemGivenBESRelative(bg,end,step,msg));
519 std::vector<bool> b(_fields.size(),true);
521 for(int i=0;i<nbOfEntriesToKill;i++,k+=step)
523 if(k<0 || k>=(int)_fields.size())
525 std::ostringstream oss; oss << "MEDFileFields::destroyFieldsAtPos2 : Invalid given id in input (" << k << ") should be in [0," << _fields.size() << ") !";
526 throw INTERP_KERNEL::Exception(oss.str());
530 std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> > fields(std::count(b.begin(),b.end(),true));
532 for(std::size_t i=0;i<_fields.size();i++)
534 fields[j++]=_fields[i];
538 bool MEDFileFields::changeMeshNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
541 for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::iterator it=_fields.begin();it!=_fields.end();it++)
543 MEDFileAnyTypeFieldMultiTSWithoutSDA *cur(*it);
545 ret=cur->changeMeshNames(modifTab) || ret;
551 * \param [in] meshName the name of the mesh that will be renumbered.
552 * \param [in] oldCode is of format returned by MEDCouplingUMesh::getDistributionOfTypes. And for each *i* oldCode[3*i+2] gives the position (MEDFileUMesh::PutInThirdComponentOfCodeOffset).
553 * This code corresponds to the distribution of types in the corresponding mesh.
554 * \param [in] newCode idem to param \a oldCode except that here the new distribution is given.
555 * \param [in] renumO2N the old to new renumber array.
556 * \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
559 bool MEDFileFields::renumberEntitiesLyingOnMesh(const std::string& meshName, const std::vector<int>& oldCode, const std::vector<int>& newCode, const DataArrayInt *renumO2N)
562 for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::iterator it=_fields.begin();it!=_fields.end();it++)
564 MEDFileAnyTypeFieldMultiTSWithoutSDA *fmts(*it);
567 ret=fmts->renumberEntitiesLyingOnMesh(meshName,oldCode,newCode,renumO2N,*this) || ret;
574 * Return an extraction of \a this using \a extractDef map to specify the extraction.
575 * The keys of \a extractDef is level relative to max ext of \a mm mesh.
577 * \return A new object that the caller is responsible to deallocate.
579 MEDFileFields *MEDFileFields::extractPart(const std::map<int, MCAuto<DataArrayInt> >& extractDef, MEDFileMesh *mm) const
582 throw INTERP_KERNEL::Exception("MEDFileFields::extractPart : input mesh is NULL !");
583 MCAuto<MEDFileFields> fsOut(MEDFileFields::New());
584 int nbFields(getNumberOfFields());
585 for(int i=0;i<nbFields;i++)
587 MCAuto<MEDFileAnyTypeFieldMultiTS> fmts(getFieldAtPos(i));
590 std::ostringstream oss; oss << "MEDFileFields::extractPart : at pos #" << i << " field is null !";
591 throw INTERP_KERNEL::Exception(oss.str());
593 MCAuto<MEDFileAnyTypeFieldMultiTS> fmtsOut(fmts->extractPart(extractDef,mm));
594 fsOut->pushField(fmtsOut);
599 void MEDFileFields::accept(MEDFileFieldVisitor& visitor) const
601 for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++)
602 if((*it).isNotNull())
604 visitor.newFieldEntry(*it);
605 (*it)->accept(visitor);
606 visitor.endFieldEntry(*it);
610 class MEDFileFieldLin2QuadVisitor : public MEDFileFieldVisitor
613 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) { }
614 void newFieldEntry(const MEDFileAnyTypeFieldMultiTSWithoutSDA *field) { if(field->getMeshName()!=_lin->getName()) return; _cur_fmts=MEDFileFieldMultiTS::New(); }
615 void endFieldEntry(const MEDFileAnyTypeFieldMultiTSWithoutSDA *field) { if(_cur_fmts.isNotNull()) { if(_cur_fmts->getNumberOfTS()>0) _out_fs->pushField(_cur_fmts); } }
617 void newTimeStepEntry(const MEDFileAnyTypeField1TSWithoutSDA *ts);
618 void endTimeStepEntry(const MEDFileAnyTypeField1TSWithoutSDA *ts);
620 void newMeshEntry(const MEDFileFieldPerMesh *fpm);
621 void endMeshEntry(const MEDFileFieldPerMesh *fpm) { }
623 void newPerMeshPerTypeEntry(const MEDFileFieldPerMeshPerTypeCommon *pmpt);
624 void endPerMeshPerTypeEntry(const MEDFileFieldPerMeshPerTypeCommon *pmpt) { }
626 void newPerMeshPerTypePerDisc(const MEDFileFieldPerMeshPerTypePerDisc *pmptpd);
628 void updateData(MEDFileFieldPerMeshPerTypePerDisc *pmtd);
630 const MEDFileUMesh *_lin;
631 const MEDFileUMesh *_quad;
632 const MEDFileFieldGlobsReal *_lin_globs;
633 MEDFileFields *_out_fs;
634 MCAuto<MEDFileFieldMultiTS> _cur_fmts;
635 MCAuto<MEDFileField1TS> _cur_f1ts;
636 INTERP_KERNEL::NormalizedCellType _gt;
637 // Info on 1TS modification
638 bool _1ts_update_requested;
639 // Cache of matrix to compute faster the values on newly created points
641 MCAuto<DataArrayInt> _matrix;
642 MCAuto<DataArrayInt> _new_pts_ids;
645 void MEDFileFieldLin2QuadVisitor::newPerMeshPerTypePerDisc(const MEDFileFieldPerMeshPerTypePerDisc *pmptpd)
647 if(_cur_f1ts.isNull())
649 if(pmptpd->getType()!=ON_NODES)
650 throw INTERP_KERNEL::Exception("Not managed yet for ON_CELLS ON_GAUSS_NE and ON_GAUSS_PT");
651 _1ts_update_requested=true;
652 MEDFileAnyTypeField1TSWithoutSDA *ct(_cur_f1ts->contentNotNullBase());
653 int locId(pmptpd->getFather()->locIdOfLeaf(pmptpd));
654 MEDFileFieldPerMeshPerTypePerDisc *pmtdToModify(ct->getLeafGivenMeshAndTypeAndLocId(_lin->getName(),_gt,locId));
655 std::string pflName(pmptpd->getProfile());
656 if(pflName==_pfl && _matrix.isNotNull())
658 updateData(pmtdToModify);
661 _pfl=pflName; _matrix.nullify(); _new_pts_ids.nullify();
662 MCAuto<DataArrayInt> pfl;
664 pfl=DataArrayInt::Range(0,pmptpd->getNumberOfVals(),1);
666 pfl=_lin_globs->getProfile(pflName)->deepCopy();
668 MCAuto<MEDCouplingUMesh> mesh3D(_lin->getMeshAtLevel(0)),mesh3DQuadratic(_quad->getMeshAtLevel(0));
669 MCAuto<DataArrayInt> cellIds(mesh3D->getCellIdsLyingOnNodes(pfl->begin(),pfl->end(),true));
670 MCAuto<MEDCouplingUMesh> mesh3DQuadraticRestricted(mesh3DQuadratic->buildPartOfMySelf(cellIds->begin(),cellIds->end(),true));
671 MCAuto<DataArrayInt> mesh3DQuadraticRestrictedNodeIds(mesh3DQuadraticRestricted->computeFetchedNodeIds());
672 MCAuto<DataArrayInt> orphansNodes;
674 MCAuto<MEDCouplingUMesh> tmp1(mesh3D->buildPartOfMySelf(cellIds->begin(),cellIds->end(),true));
675 MCAuto<DataArrayInt> tmp2(tmp1->computeFetchedNodeIds());
676 orphansNodes=pfl->buildSubstraction(tmp2);
678 mesh3DQuadraticRestrictedNodeIds->checkMonotonic(true);
679 _new_pts_ids=mesh3DQuadraticRestrictedNodeIds->buildSubstraction(pfl);
680 MCAuto<MEDCoupling1SGTUMesh> allSeg3;
682 MCAuto<DataArrayInt> a,b,c,d;
683 MCAuto<MEDCouplingUMesh> seg3Tmp(mesh3DQuadraticRestricted->explodeIntoEdges(a,b,c,d));
684 allSeg3=MEDCoupling1SGTUMesh::New(seg3Tmp);
686 if(allSeg3->getCellModelEnum()!=INTERP_KERNEL::NORM_SEG3)
687 throw INTERP_KERNEL::Exception("MEDFileFieldLin2QuadVisitor::newPerMeshPerTypePerDisc : invalid situation where SEG3 expected !");
688 MCAuto<DataArrayInt> midPts,cellSeg3Ids;
690 DataArrayInt *nodeConn(allSeg3->getNodalConnectivity());
691 nodeConn->rearrange(3);
693 std::vector<int> v(1,2);
694 midPts=nodeConn->keepSelectedComponents(v);
696 cellSeg3Ids=DataArrayInt::FindPermutationFromFirstToSecond(midPts,_new_pts_ids);
698 std::vector<int> v(2); v[0]=0; v[1]=1;
699 MCAuto<DataArrayInt> tmp(nodeConn->keepSelectedComponents(v));
700 _matrix=tmp->selectByTupleId(cellSeg3Ids->begin(),cellSeg3Ids->end());
702 nodeConn->rearrange(1);
704 updateData(pmtdToModify);
708 void MEDFileFieldLin2QuadVisitor::updateData(MEDFileFieldPerMeshPerTypePerDisc *pmtd)
710 pmtd->incrementNbOfVals(_new_pts_ids->getNumberOfTuples());
713 void MEDFileFieldLin2QuadVisitor::newPerMeshPerTypeEntry(const MEDFileFieldPerMeshPerTypeCommon *pmpt)
715 const MEDFileFieldPerMeshPerType *pmpt2(dynamic_cast<const MEDFileFieldPerMeshPerType *>(pmpt));
717 throw INTERP_KERNEL::Exception("MEDFileFieldLin2QuadVisitor::newPerMeshPerTypeEntry : not managed for structure elements !");
718 if(pmpt2->getNumberOfLoc()!=1)
719 throw INTERP_KERNEL::Exception("MEDFileFieldLin2QuadVisitor::newPerMeshPerTypeEntry : not managed for multi discr per timestep !");
720 _gt=pmpt->getGeoType();
723 void MEDFileFieldLin2QuadVisitor::newMeshEntry(const MEDFileFieldPerMesh *fpm)
725 if(fpm->getMeshName()!=_lin->getName())
726 throw INTERP_KERNEL::Exception("MEDFileFieldLin2QuadVisitor::newMeshEntry : mismatch into meshName !");
729 void MEDFileFieldLin2QuadVisitor::newTimeStepEntry(const MEDFileAnyTypeField1TSWithoutSDA *ts)
731 _1ts_update_requested=false;
734 const MEDFileField1TSWithoutSDA *tsd(dynamic_cast<const MEDFileField1TSWithoutSDA *>(ts));
737 MCAuto<MEDFileAnyTypeField1TSWithoutSDA> contentCpy(ts->deepCopy());
738 MCAuto<MEDFileField1TSWithoutSDA> contentCpy2(DynamicCastSafe<MEDFileAnyTypeField1TSWithoutSDA,MEDFileField1TSWithoutSDA>(contentCpy));
739 if(contentCpy2.isNull())
741 _cur_f1ts=MEDFileField1TS::New(*contentCpy2,true);
742 _cur_f1ts->shallowCpyGlobs(*_lin_globs);
745 void MEDFileFieldLin2QuadVisitor::endTimeStepEntry(const MEDFileAnyTypeField1TSWithoutSDA *ts)
747 if(_cur_f1ts.isNull())
749 if(_1ts_update_requested)
753 int locId(_cur_f1ts->getLocalizationId(_pfl));
754 DataArrayInt *pfl(_cur_f1ts->getProfile(_pfl));
755 MCAuto<DataArrayInt> newPfl;
757 std::vector<const DataArrayInt *> vs(2);
758 vs[0]=pfl; vs[1]=_new_pts_ids;
759 newPfl=DataArrayInt::Aggregate(vs);
761 newPfl->setName(_pfl);
763 std::vector<int> locToKill(1,locId);
764 _cur_f1ts->killLocalizationIds(locToKill);
766 _cur_f1ts->appendProfile(newPfl);
768 DataArrayDouble *arr(_cur_f1ts->getUndergroundDataArray());
769 MCAuto<DataArrayDouble> res;
771 std::vector<int> v(1,0),v2(1,1);
772 MCAuto<DataArrayInt> pts0(_matrix->keepSelectedComponents(v));
773 MCAuto<DataArrayInt> pts1(_matrix->keepSelectedComponents(v2));
774 MCAuto<DataArrayDouble> part0(arr->selectByTupleId(*pts0));
775 MCAuto<DataArrayDouble> part1(arr->selectByTupleId(*pts1));
776 res=DataArrayDouble::Add(part0,part1);
777 res->applyLin(0.5,0.);
779 res=DataArrayDouble::Aggregate(arr,res);
780 _cur_f1ts->setArray(res);
782 if(_cur_fmts.isNotNull())
783 { _cur_fmts->pushBackTimeStep(_cur_f1ts); }
784 _1ts_update_requested=false;
788 * \a newQuad is expected to be the result of MEDFileUMesh::linearToQuadratic of \a oldLin
790 MCAuto<MEDFileFields> MEDFileFields::linearToQuadratic(const MEDFileMeshes *oldLin, const MEDFileMeshes *newQuad) const
792 if(!oldLin || !newQuad)
793 throw INTERP_KERNEL::Exception("MEDFileFields::linearToQuadratic : input meshes must be non NULL !");
794 MCAuto<MEDFileFields> ret(MEDFileFields::New());
795 for(int i=0;i<oldLin->getNumberOfMeshes();i++)
797 MEDFileMesh *mm(oldLin->getMeshAtPos(i));
800 MEDFileUMesh *mmu(dynamic_cast<MEDFileUMesh *>(mm));
803 MEDFileMesh *mmq(newQuad->getMeshWithName(mmu->getName()));
804 MEDFileUMesh *mmqu(dynamic_cast<MEDFileUMesh *>(mmq));
807 std::ostringstream oss; oss << "MEDFileFields::linearToQuadratic : mismatch of name between input meshes for name \"" << mmu->getName() << "\"";
808 throw INTERP_KERNEL::Exception(oss.str());
810 MEDFileFieldLin2QuadVisitor vis(mmu,mmqu,this,ret);
816 MEDFileAnyTypeFieldMultiTS *MEDFileFields::getFieldAtPos(int i) const
818 if(i<0 || i>=(int)_fields.size())
820 std::ostringstream oss; oss << "MEDFileFields::getFieldAtPos : Invalid given id in input (" << i << ") should be in [0," << _fields.size() << ") !";
821 throw INTERP_KERNEL::Exception(oss.str());
823 const MEDFileAnyTypeFieldMultiTSWithoutSDA *fmts=_fields[i];
826 MCAuto<MEDFileAnyTypeFieldMultiTS> ret;
827 const MEDFileFieldMultiTSWithoutSDA *fmtsC(dynamic_cast<const MEDFileFieldMultiTSWithoutSDA *>(fmts));
828 const MEDFileIntFieldMultiTSWithoutSDA *fmtsC2(dynamic_cast<const MEDFileIntFieldMultiTSWithoutSDA *>(fmts));
829 const MEDFileFloatFieldMultiTSWithoutSDA *fmtsC3(dynamic_cast<const MEDFileFloatFieldMultiTSWithoutSDA *>(fmts));
831 ret=MEDFileFieldMultiTS::New(*fmtsC,false);
833 ret=MEDFileIntFieldMultiTS::New(*fmtsC2,false);
835 ret=MEDFileFloatFieldMultiTS::New(*fmtsC3,false);
838 std::ostringstream oss; oss << "MEDFileFields::getFieldAtPos : At pos #" << i << " field is neither double (FLOAT64) nor float (FLOAT32) nor integer (INT32) !";
839 throw INTERP_KERNEL::Exception(oss.str());
841 ret->shallowCpyGlobs(*this);
846 * Return a shallow copy of \a this reduced to the fields ids defined in [ \a startIds , endIds ).
847 * This method is accessible in python using __getitem__ with a list in input.
848 * \return a new object that the caller should deal with.
850 MEDFileFields *MEDFileFields::buildSubPart(const int *startIds, const int *endIds) const
852 MCAuto<MEDFileFields> ret=shallowCpy();
853 std::size_t sz=std::distance(startIds,endIds);
854 std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> > fields(sz);
856 for(const int *i=startIds;i!=endIds;i++,j++)
858 if(*i<0 || *i>=(int)_fields.size())
860 std::ostringstream oss; oss << "MEDFileFields::buildSubPart : Invalid given id in input (" << *i << ") should be in [0," << _fields.size() << ") !";
861 throw INTERP_KERNEL::Exception(oss.str());
863 fields[j]=_fields[*i];
869 MEDFileAnyTypeFieldMultiTS *MEDFileFields::getFieldWithName(const std::string& fieldName) const
871 return getFieldAtPos(getPosFromFieldName(fieldName));
875 * This method removes, if any, fields in \a this having no time steps.
876 * 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.
878 * If false is returned \a this does not contain such fields. If false is returned this method can be considered as const.
880 bool MEDFileFields::removeFieldsWithoutAnyTimeStep()
882 std::vector<MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> > newFields;
883 for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++)
885 const MEDFileAnyTypeFieldMultiTSWithoutSDA *elt(*it);
888 if(elt->getNumberOfTS()>0)
889 newFields.push_back(*it);
892 if(_fields.size()==newFields.size())
899 * This method returns a new object containing part of \a this fields lying on mesh name specified by the input parameter \a meshName.
900 * This method can be seen as a filter applied on \a this, that returns an object containing
901 * 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
902 * shallow copied from \a this.
904 * \param [in] meshName - the name of the mesh on w
905 * \return a new object that the caller should deal with.
907 MEDFileFields *MEDFileFields::partOfThisLyingOnSpecifiedMeshName(const std::string& meshName) const
909 MCAuto<MEDFileFields> ret(MEDFileFields::New());
910 for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++)
912 const MEDFileAnyTypeFieldMultiTSWithoutSDA *cur(*it);
915 if(cur->getMeshName()==meshName)
918 MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> cur2(const_cast<MEDFileAnyTypeFieldMultiTSWithoutSDA *>(cur));
919 ret->_fields.push_back(cur2);
922 ret->shallowCpyOnlyUsedGlobs(*this);
927 * This method returns a new object containing part of \a this fields lying ** exactly ** on the time steps specified by input parameter \a timeSteps.
928 * Input time steps are specified using a pair of integer (iteration, order).
929 * 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,
930 * but for each multitimestep only the time steps in \a timeSteps are kept.
931 * Typically the input parameter \a timeSteps comes from the call of MEDFileFields::getCommonIterations.
933 * The returned object points to shallow copy of elements in \a this.
935 * \param [in] timeSteps - the time steps given by a vector of pair of integers (iteration,order)
936 * \throw If there is a field in \a this that is \b not defined on a time step in the input \a timeSteps.
937 * \sa MEDFileFields::getCommonIterations, MEDFileFields::partOfThisNotLyingOnSpecifiedTimeSteps
939 MEDFileFields *MEDFileFields::partOfThisLyingOnSpecifiedTimeSteps(const std::vector< std::pair<int,int> >& timeSteps) 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 MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> elt=cur->partOfThisLyingOnSpecifiedTimeSteps(timeSteps);
948 ret->_fields.push_back(elt);
950 ret->shallowCpyOnlyUsedGlobs(*this);
955 * \sa MEDFileFields::getCommonIterations, MEDFileFields::partOfThisLyingOnSpecifiedTimeSteps
957 MEDFileFields *MEDFileFields::partOfThisNotLyingOnSpecifiedTimeSteps(const std::vector< std::pair<int,int> >& timeSteps) const
959 MCAuto<MEDFileFields> ret=MEDFileFields::New();
960 for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++)
962 const MEDFileAnyTypeFieldMultiTSWithoutSDA *cur(*it);
965 MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> elt=cur->partOfThisNotLyingOnSpecifiedTimeSteps(timeSteps);
966 if(elt->getNumberOfTS()!=0)
967 ret->_fields.push_back(elt);
969 ret->shallowCpyOnlyUsedGlobs(*this);
973 bool MEDFileFields::presenceOfStructureElements() const
975 for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++)
976 if((*it).isNotNull())
977 if((*it)->presenceOfStructureElements())
982 void MEDFileFields::killStructureElements()
984 std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> > ret;
985 for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::iterator it=_fields.begin();it!=_fields.end();it++)
986 if((*it).isNotNull())
988 if((*it)->presenceOfStructureElements())
990 if(!(*it)->onlyStructureElements())
992 (*it)->killStructureElements();
1004 void MEDFileFields::keepOnlyStructureElements()
1006 std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> > ret;
1007 for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::iterator it=_fields.begin();it!=_fields.end();it++)
1008 if((*it).isNotNull())
1010 if((*it)->presenceOfStructureElements())
1012 if(!(*it)->onlyStructureElements())
1013 (*it)->keepOnlyStructureElements();
1020 void MEDFileFields::keepOnlyOnMeshSE(const std::string& meshName, const std::string& seName)
1022 std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> > ret;
1023 for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::iterator it=_fields.begin();it!=_fields.end();it++)
1024 if((*it).isNotNull())
1026 if((*it)->getMeshName()!=meshName)
1028 std::vector< std::pair<std::string,std::string> > ps;
1029 (*it)->getMeshSENames(ps);
1030 std::pair<std::string,std::string> p(meshName,seName);
1031 if(std::find(ps.begin(),ps.end(),p)!=ps.end())
1032 (*it)->keepOnlyOnSE(seName);
1038 void MEDFileFields::getMeshSENames(std::vector< std::pair<std::string,std::string> >& ps) const
1040 for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++)
1041 if((*it).isNotNull())
1042 (*it)->getMeshSENames(ps);
1045 void MEDFileFields::blowUpSE(MEDFileMeshes *ms, const MEDFileStructureElements *ses)
1047 MEDFileBlowStrEltUp::DealWithSE(this,ms,ses);
1050 MCAuto<MEDFileFields> MEDFileFields::partOfThisOnStructureElements() const
1052 MCAuto<MEDFileFields> ret(deepCopy());
1053 ret->keepOnlyStructureElements();
1057 MCAuto<MEDFileFields> MEDFileFields::partOfThisLyingOnSpecifiedMeshSEName(const std::string& meshName, const std::string& seName) const
1059 MCAuto<MEDFileFields> ret(deepCopy());
1060 ret->keepOnlyOnMeshSE(meshName,seName);
1064 void MEDFileFields::aggregate(const MEDFileFields& other)
1066 int nbFieldsToAdd(other.getNumberOfFields());
1067 std::vector<std::string> fsn(getFieldsNames());
1068 for(int i=0;i<nbFieldsToAdd;i++)
1070 MCAuto<MEDFileAnyTypeFieldMultiTS> elt(other.getFieldAtPos(i));
1071 std::string name(elt->getName());
1072 if(std::find(fsn.begin(),fsn.end(),name)!=fsn.end())
1074 std::ostringstream oss; oss << "MEDFileFields::aggregate : name \"" << name << "\" already appears !";
1075 throw INTERP_KERNEL::Exception(oss.str());
1081 MEDFileFieldsIterator *MEDFileFields::iterator()
1083 return new MEDFileFieldsIterator(this);
1086 int MEDFileFields::getPosFromFieldName(const std::string& fieldName) const
1088 std::string tmp(fieldName);
1089 std::vector<std::string> poss;
1090 for(std::size_t i=0;i<_fields.size();i++)
1092 const MEDFileAnyTypeFieldMultiTSWithoutSDA *f(_fields[i]);
1095 std::string fname(f->getName());
1099 poss.push_back(fname);
1102 std::ostringstream oss; oss << "MEDFileFields::getPosFromFieldName : impossible to find field '" << tmp << "' in this ! Possibilities are : ";
1103 std::copy(poss.begin(),poss.end(),std::ostream_iterator<std::string>(oss,", "));
1105 throw INTERP_KERNEL::Exception(oss.str());
1108 MEDFileFieldsIterator::MEDFileFieldsIterator(MEDFileFields *fs):_fs(fs),_iter_id(0),_nb_iter(0)
1113 _nb_iter=fs->getNumberOfFields();
1117 MEDFileFieldsIterator::~MEDFileFieldsIterator()
1121 MEDFileAnyTypeFieldMultiTS *MEDFileFieldsIterator::nextt()
1123 if(_iter_id<_nb_iter)
1125 MEDFileFields *fs(_fs);
1127 return fs->getFieldAtPos(_iter_id++);