X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FMEDLoader%2FMEDFileBlowStrEltUp.cxx;h=8fa0d2d52bebee9a0144378989a9f757afd8df48;hb=b7e277ad50223814bc479c5bd64cf12abe8fc959;hp=0ee8ec16fea0b050a398a7294fce0696acbec836;hpb=e8d23862df98c569db3f255e0fce1dcb6d832f53;p=tools%2Fmedcoupling.git diff --git a/src/MEDLoader/MEDFileBlowStrEltUp.cxx b/src/MEDLoader/MEDFileBlowStrEltUp.cxx index 0ee8ec16f..8fa0d2d52 100644 --- a/src/MEDLoader/MEDFileBlowStrEltUp.cxx +++ b/src/MEDLoader/MEDFileBlowStrEltUp.cxx @@ -20,6 +20,9 @@ #include "MEDFileBlowStrEltUp.hxx" #include "MEDCouplingFieldDouble.hxx" +#include "MEDFileFieldVisitor.hxx" +#include "MEDCouplingPartDefinition.hxx" +#include "MCAuto.txx" using namespace MEDCoupling; @@ -117,16 +120,10 @@ MCAuto MEDFileBlowStrEltUp::dealWithMEDBALLInMesh(const M MCAuto md(zeStr->getMeshDef()); const DataArrayInt *ff0(md->getFam()); if(ff0) - { - MCAuto ff0o(ff0->duplicateEachTupleNTimes(nbCells)); - mOut->setFamilyFieldArr(0,ff0o); - } + mOut->setFamilyFieldArr(0,const_cast(ff0)); const DataArrayInt *nf0(md->getNum()); if(nf0) - { - MCAuto nf0o(ff0->duplicateEachTupleNTimes(nbCells)); - mOut->setRenumFieldArr(0,nf0o); - } + mOut->setRenumFieldArr(0,const_cast(nf0)); mOut->copyFamGrpMapsFrom(*mesh); const std::vector< MCAuto >& vars(zeStr->getVars()); for(std::vector< MCAuto >::const_iterator it=vars.begin();it!=vars.end();it++) @@ -159,7 +156,7 @@ MCAuto MEDFileBlowStrEltUp::dealWithMEDBALLInMesh(const M * \param [in] varAtt - fields containing var att of current structure element. WARNING at this stage the number of iteration are equal to one for each field in \a varAtt * \param [out] zeOutputs - ze fields that are the concatenation of fields in \a fs transformed and those in \a varAtt normalized in time space */ -void MEDFileBlowStrEltUp::dealWithSEInFields(const std::string& seName, const MEDFileFields *fs, const MEDFileEltStruct4Mesh *zeStr, const MEDFileFields *varAtt, MCAuto& zeOutputs) const +void MEDFileBlowStrEltUp::dealWithSEInFields(const std::string& seName, const MEDFileFields *fs, const MEDFileEltStruct4Mesh *zeStr, const MEDFileFields *varAtt, MEDFileFields *zeOutputs) const { if(!fs) throw INTERP_KERNEL::Exception("MEDFileBlowStrEltUp::dealWithSEInFields : null pointer !"); @@ -171,15 +168,93 @@ void MEDFileBlowStrEltUp::dealWithSEInFields(const std::string& seName, const ME throw INTERP_KERNEL::Exception("MEDFileBlowStrEltUp::dealWithSEInFields : only MED_BALL is managed for the moment, but if you are interested please send spec to anthony.geay@edf.fr !"); } -void MEDFileBlowStrEltUp::dealWithMEDBALLSInFields(const MEDFileFields *fs, const MEDFileEltStruct4Mesh *zeStr, const MEDFileFields *varAtt, MCAuto& zeOutputs) const +void MEDFileBlowStrEltUp::dealWithMEDBALLSInFields(const MEDFileFields *fs, const MEDFileEltStruct4Mesh *zeStr, const MEDFileFields *varAtt, MEDFileFields *zeOutputs) const { - + int nbf(fs->getNumberOfFields()); + std::vector< MCAuto > elts0; + std::vector< MEDFileAnyTypeFieldMultiTS * > elts1; + std::string zeMeshName; + for(int i=0;i elt(fs->getFieldAtPos(i)); + MCAuto eltOut(elt->buildNewEmpty()); + int nbTS(elt->getNumberOfTS()); + for(int j=0;j eltt(elt->getTimeStepAtPos(j)); + MCAuto elttOut(eltt->deepCopy()); + std::string meshName(eltt->getMeshName()); + zeMeshName=BuildNewMeshName(meshName,MED_BALL_STR); + elttOut->setMeshName(zeMeshName); + elttOut->convertMedBallIntoClassic(); + eltOut->pushBackTimeStep(elttOut); + } + elts0.push_back(eltOut); elts1.push_back(eltOut); + } + // + const MEDFileMesh *zeCurrentMesh(_ms->getMeshWithName(zeMeshName)); + // + std::size_t ii(0); + std::vector< std::vector > sp(MEDFileAnyTypeFieldMultiTS::SplitIntoCommonTimeSeries(elts1)); + for(std::vector< std::vector >::const_iterator it0=sp.begin();it0!=sp.end();it0++,ii++) + { + std::vector< MCAuto > fsc; + std::vector< std::vector > sp2(MEDFileAnyTypeFieldMultiTS::SplitPerCommonSupport(*it0,zeCurrentMesh,fsc)); + std::size_t jj(0); + for(std::vector< std::vector >::const_iterator it1=sp2.begin();it1!=sp2.end();it1++,jj++) + { + for(std::vector::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++) + zeOutputs->pushField(*it2); + // The most exciting part. Users that put profiles on struct elements part of fields. Reduce var att. + if((*it1).size()<1) + throw INTERP_KERNEL::Exception("MEDFileBlowStrEltUp::dealWithMEDBALLSInFields : take a deep breath !"); + MCAuto zeGuideForPfl;// This var is the reference for pfl management. + { + if(!(*it1)[0]) + throw INTERP_KERNEL::Exception("MEDFileBlowStrEltUp::dealWithMEDBALLSInFields : take a deep breath 2 !"); + int pdm((*it1)[0]->getNumberOfTS()); + if(pdm<1) + throw INTERP_KERNEL::Exception("MEDFileBlowStrEltUp::dealWithMEDBALLSInFields : take a deep breath 3 !"); + zeGuideForPfl=(*it1)[0]->getTimeStepAtPos(0); + } + if(zeGuideForPfl.isNull()) + throw INTERP_KERNEL::Exception("MEDFileBlowStrEltUp::dealWithMEDBALLSInFields : take a deep breath 4 !"); + std::vector pfls(zeGuideForPfl->getPflsReallyUsed()); + if(pfls.size()>=2) + throw INTERP_KERNEL::Exception("MEDFileBlowStrEltUp::dealWithMEDBALLSInFields : drink less coffee"); + MCAuto pflMyLove; + if(pfls.size()==1) + pflMyLove.takeRef(zeGuideForPfl->getProfile(pfls[0])); + // Yeah we have pfls + std::vector t2s; + std::vector< std::pair > t1s((*it1)[0]->getTimeSteps(t2s)); + std::size_t nbTS3(t2s.size()); + int nbf2(varAtt->getNumberOfFields()); + for(int i=0;i elt(varAtt->getFieldAtPos(i)); + int nbTS2(elt->getNumberOfTS()); + if(nbTS2!=1) + throw INTERP_KERNEL::Exception("MEDFileBlowStrEltUp::dealWithMEDBALLSInFields : internal error ! The dealWithMEDBALLInMesh is expected to return a single TS !"); + MCAuto elt2(elt->getTimeStepAtPos(0)); + MCAuto elt4(elt->buildNewEmpty()); + for(std::size_t j=0;j elt3(elt2->deepCopy()); + elt3->setTime(t1s[j].first,t1s[j].second,t2s[j]); + elt3->setName(BuildVarAttName(ii,sp.size(),jj,sp2.size(),elt3->getName())); + if(pflMyLove.isNotNull()) + elt3->makeReduction(INTERP_KERNEL::NORM_ERROR,ON_NODES,pflMyLove); + elt4->pushBackTimeStep(elt3); + } + zeOutputs->pushField(elt4); + } + } + } } -void MEDFileBlowStrEltUp::generate(MCAuto& msOut, MCAuto& allZeOutFields) +void MEDFileBlowStrEltUp::generate(MEDFileMeshes *msOut, MEDFileFields *allZeOutFields) { - msOut=MEDFileMeshes::New(); - allZeOutFields=MEDFileFields::New(); for(std::vector< MCAuto >::iterator elt=_elts.begin();elt!=_elts.end();elt++) { std::vector< std::pair > ps; @@ -192,13 +267,16 @@ void MEDFileBlowStrEltUp::generate(MCAuto& msOut, MCAuto(mesh)); if(!umesh) throw INTERP_KERNEL::Exception("MEDFileBlowStrEltUp::generateMeshes : Blow up of Stru Elt not managed yet for unstructured meshes !"); - MCAuto mOut; - MCAuto fsOut1; - MCAuto zeStr(dealWithSEInMesh(ps[0].second,umesh,mOut,fsOut1)); - msOut->pushMesh(umesh); - MCAuto fsOut2; - dealWithSEInFields(ps[0].second,*elt,zeStr,fsOut1,fsOut2); - allZeOutFields->aggregate(*fsOut2); + // + MCAuto classicalSEFields(splitFieldsPerLoc(*elt,umesh,msOut,allZeOutFields)); + if(classicalSEFields.isNotNull()) + { + MCAuto mOut; + MCAuto fsOut1; + MCAuto zeStr(dealWithSEInMesh(ps[0].second,umesh,mOut,fsOut1)); + msOut->pushMesh(mOut); + dealWithSEInFields(ps[0].second,classicalSEFields,zeStr,fsOut1,allZeOutFields); + } } } @@ -209,13 +287,631 @@ std::string MEDFileBlowStrEltUp::BuildNewMeshName(const std::string& meshName, c return mNameOut.str(); } -void MEDFileBlowStrEltUp::DealWithSE(MEDFileFields *fs, const MEDFileMeshes *ms, const MEDFileStructureElements *ses, MCAuto& fsOut, MCAuto& msOut) +std::string MEDFileBlowStrEltUp::BuildVarAttName(std::size_t iPart, std::size_t totINbParts, std::size_t jPart, std::size_t totJNbParts, const std::string& name) +{ + if(totINbParts==1 && totJNbParts==1) + return name; + std::ostringstream oss; + oss << name << "@" << iPart << "@" << jPart; + return oss.str(); +} + +void MEDFileBlowStrEltUp::DealWithSE(MEDFileFields *fs, MEDFileMeshes *ms, const MEDFileStructureElements *ses) { MCAuto fsSEOnly(fs->partOfThisOnStructureElements()); fs->killStructureElements(); MEDFileBlowStrEltUp bu(fsSEOnly,ms,ses); - MCAuto msOut1; - MCAuto allZeOutFields1; - bu.generate(msOut1,allZeOutFields1); - + bu.generate(ms,fs); + fs->killStructureElementsInGlobs(); +} + +// + +class FieldWalker2 +{ +public: + FieldWalker2(const MEDFileFieldPerMeshPerTypePerDisc *pmptpd); + std::string getLoc() const { return _loc; } + std::string getPfl() const { return _pfl; } + bool isClassic() const { return _is_classic; } + bool operator!=(const FieldWalker2& other) const; + bool operator==(const FieldWalker2& other) const; + const SlicePartDefinition *getPartDef() const { return _pd; } +private: + std::string _loc; + std::string _pfl; + bool _is_classic; + MCAuto _pd; +}; + +class LocInfo +{ +public: + LocInfo() { } + LocInfo(const std::vector& fw); + bool operator==(const LocInfo& other) const { return _locs==other._locs && _pfl==other._pfl; } + void push(const std::string& loc, const std::string& pfl) { checkUniqueLoc(loc); _locs.push_back(loc); _pfl.push_back(pfl); } + MCAuto generateNonClassicalData(int zePos, const MEDFileUMesh *mesh, const MEDFileFieldGlobsReal *globs) const; + const PartDefinition *getPartDef() const { return _pd; } +private: + void checkUniqueLoc(const std::string& loc) const; + static MCAuto BuildMeshFromAngleVrille(INTERP_KERNEL::NormalizedCellType gt, const DataArrayDouble *angleDeVrille, const std::string& pfl, const MEDFileFieldLoc& loc, const MEDFileEltStruct4Mesh *zeStr, const MEDFileUMesh *mesh, const MEDFileUMesh *section, const MEDFileFieldGlobsReal *globs); + static MCAuto BuildMeshFromEpaisseur(INTERP_KERNEL::NormalizedCellType gt, const DataArrayDouble *thikness, const std::string& pfl, const MEDFileFieldLoc& loc, const MEDFileEltStruct4Mesh *zeStr, const MEDFileUMesh *mesh, const MEDFileUMesh *section, const MEDFileFieldGlobsReal *globs); + static MCAuto BuildMeshCommon(INTERP_KERNEL::NormalizedCellType gt, const std::string& pfl, const MEDFileFieldLoc& loc, const MEDFileEltStruct4Mesh *zeStr, const MEDFileUMesh *mesh, const MEDFileUMesh *section, const MEDFileFieldGlobsReal *globs, MCAuto& ptsForLoc); + static MCAuto BuildMeshFromStructure(INTERP_KERNEL::NormalizedCellType gt, const std::string& pfl, const MEDFileFieldLoc& loc, const MEDFileEltStruct4Mesh *zeStr, const MEDFileUMesh *mesh, const MEDFileUMesh *section, const MEDFileFieldGlobsReal *globs); +public: + static const char ANGLE_DE_VRILLE[]; + static const char EPAISSEUR[]; +private: + std::vector _locs; + std::vector _pfl; + MCAuto _pd; +}; + +const char LocInfo::ANGLE_DE_VRILLE[]="ANGLE DE VRILLE"; + +const char LocInfo::EPAISSEUR[]="EPAISSEUR"; + +LocInfo::LocInfo(const std::vector& fw) +{ + std::size_t sz(fw.size()); + _locs.resize(sz); _pfl.resize(sz); + if(sz>0) + _pd=fw[0].getPartDef()->deepCopy(); + for(std::size_t i=0;i0) + _pd=(*_pd)+(*(fw[i].getPartDef())); + } +} + +void LocInfo::checkUniqueLoc(const std::string& loc) const +{ + if(std::find(_locs.begin(),_locs.end(),loc)!=_locs.end()) + { + std::ostringstream oss; oss << "LocInfo::checkUniqueLoc : loc \"" << loc << "\" already exists !"; + throw INTERP_KERNEL::Exception(oss.str()); + } +} + +MCAuto LocInfo::BuildMeshCommon(INTERP_KERNEL::NormalizedCellType gt,const std::string& pfl, const MEDFileFieldLoc& loc, const MEDFileEltStruct4Mesh *zeStr, const MEDFileUMesh *mesh, const MEDFileUMesh *section, const MEDFileFieldGlobsReal *globs, MCAuto& ptsForLoc) +{ + MCAuto conn(zeStr->getConn()); + conn=conn->deepCopy(); conn->rearrange(1); + MCAuto geoMesh; + { + MCAuto umesh(MEDCoupling1SGTUMesh::New("",gt)); + umesh->setCoords(mesh->getCoords()); + umesh->setNodalConnectivity(conn); + geoMesh=umesh->buildUnstructured(); + } + // + MCAuto fakeF(MEDCouplingFieldDouble::New(ON_GAUSS_PT)); + fakeF->setMesh(geoMesh); + fakeF->setGaussLocalizationOnType(gt,loc.getRefCoords(),loc.getGaussCoords(),loc.getGaussWeights()); + ptsForLoc=fakeF->getLocalizationOfDiscr(); + // + return geoMesh; +} + +MCAuto LocInfo::BuildMeshFromAngleVrille(INTERP_KERNEL::NormalizedCellType gt, const DataArrayDouble *angleDeVrille, const std::string& pfl, const MEDFileFieldLoc& loc, const MEDFileEltStruct4Mesh *zeStr, const MEDFileUMesh *mesh, const MEDFileUMesh *section, const MEDFileFieldGlobsReal *globs) +{ + MCAuto ptsForLoc; + MCAuto geoMesh(BuildMeshCommon(gt,pfl,loc,zeStr,mesh,section,globs,ptsForLoc)); + // + MCConstAuto angleVrille; + if(!pfl.empty()) + { + const DataArrayInt *pflArr(globs->getProfile(pfl)); + geoMesh=geoMesh->buildPartOfMySelf(pflArr->begin(),pflArr->end(),true); + angleVrille=angleDeVrille->selectByTupleIdSafe(pflArr->begin(),pflArr->end()); + } + else + angleVrille.takeRef(angleDeVrille); + // + int nbCompo(ptsForLoc->getNumberOfComponents()); + MCAuto secPts(section->getCoords()->changeNbOfComponents(nbCompo,0.)); + int nbSecPts(secPts->getNumberOfTuples()),nbCells(geoMesh->getNumberOfCells()),nbg(loc.getGaussWeights().size()); + { + const int TAB[3]={2,0,1}; + std::vector v(TAB,TAB+3); + secPts=secPts->keepSelectedComponents(v); + } + MCAuto dir(geoMesh->buildDirectionVectorField()); + MCAuto rot(dir->getArray()->fromCartToSpher()); + // + const double CENTER[3]={0.,0.,0.},AX0[3]={0.,0.,1.}; + double AX1[3]; AX1[2]=0.; + std::vector< MCAuto > arrs(nbCells*nbg); + for(int j=0;j p(secPts->deepCopy()); + double ang0(rot->getIJ(j,2)); + DataArrayDouble::Rotate3DAlg(CENTER,AX0,ang0,nbSecPts,p->begin(),p->getPointer()); + AX1[0]=-sin(ang0); AX1[1]=cos(ang0);// rot Oy around OZ + double ang1(M_PI/2.-rot->getIJ(j,1)); + DataArrayDouble::Rotate3DAlg(CENTER,AX1,-ang1,nbSecPts,p->begin(),p->getPointer()); + DataArrayDouble::Rotate3DAlg(CENTER,dir->getArray()->begin()+j*3,angleVrille->getIJ(j,0),nbSecPts,p->begin(),p->getPointer()); + for(int l=0;l p2(p->deepCopy()); + for(int k=0;kapplyLin(1.,ptsForLoc->getIJ(j*nbg+l,k),k); + arrs[j*nbg+l]=p2; + } + } + std::vector arrs2(VecAutoToVecOfCstPt(arrs)); + MCAuto resu(DataArrayDouble::Aggregate(arrs2)); + return resu; +} + +MCAuto LocInfo::BuildMeshFromEpaisseur(INTERP_KERNEL::NormalizedCellType gt, const DataArrayDouble *thikness, const std::string& pfl, const MEDFileFieldLoc& loc, const MEDFileEltStruct4Mesh *zeStr, const MEDFileUMesh *mesh, const MEDFileUMesh *section, const MEDFileFieldGlobsReal *globs) +{ + MCAuto ptsForLoc; + MCAuto geoMesh(BuildMeshCommon(gt,pfl,loc,zeStr,mesh,section,globs,ptsForLoc)); + int nbSecPts(section->getNumberOfNodes()),nbCells(geoMesh->getNumberOfCells()),nbg(loc.getGaussWeights().size()); + MCConstAuto zeThikness; + if(!pfl.empty()) + { + const DataArrayInt *pflArr(globs->getProfile(pfl)); + geoMesh=geoMesh->buildPartOfMySelf(pflArr->begin(),pflArr->end(),true); + zeThikness=thikness->selectByTupleIdSafe(pflArr->begin(),pflArr->end()); + } + else + zeThikness.takeRef(thikness); + MCAuto orthoArr; + { + MCAuto ortho(geoMesh->buildOrthogonalField()); + orthoArr.takeRef(ortho->getArray()); + } + int nbCompo(orthoArr->getNumberOfComponents()); + MCAuto secPts(section->getCoords()->duplicateEachTupleNTimes(nbCompo)); + secPts->rearrange(nbCompo); + std::vector< MCAuto > arrs(nbCells*nbg); + for(int j=0;jgetIJ(j,0)); + MCAuto fact(DataArrayDouble::New()); fact->alloc(1,nbCompo); + std::copy(orthoArr->begin()+j*nbCompo,orthoArr->begin()+(j+1)*nbCompo,fact->getPointer()); + std::transform(fact->begin(),fact->end(),fact->getPointer(),std::bind2nd(std::multiplies(),thck/2.)); + MCAuto p(DataArrayDouble::Multiply(secPts,fact)); + for(int l=0;l p2(p->deepCopy()); + for(int k=0;kapplyLin(1.,ptsForLoc->getIJ(j*nbg+l,k),k); + arrs[j*nbg+l]=p2; + } + } + std::vector arrs2(VecAutoToVecOfCstPt(arrs)); + MCAuto resu(DataArrayDouble::Aggregate(arrs2)); + return resu; +} + +MCAuto LocInfo::BuildMeshFromStructure(INTERP_KERNEL::NormalizedCellType gt, const std::string& pfl, const MEDFileFieldLoc& loc, const MEDFileEltStruct4Mesh *zeStr, const MEDFileUMesh *mesh, const MEDFileUMesh *section, const MEDFileFieldGlobsReal *globs) +{ + static const char MSG1[]="BuildMeshFromStructure : not recognized pattern ! Send mail to anthony.geay@edf.fr with corresponding MED file !"; + const std::vector< MCAuto >& vars(zeStr->getVars()); + if(vars.size()!=1) + throw INTERP_KERNEL::Exception(MSG1); + MCAuto zeArr(vars[0]); + if(zeArr.isNull()) + throw INTERP_KERNEL::Exception(MSG1); + MCAuto zeArr2(DynamicCast(zeArr)); + if(zeArr2.isNull()) + throw INTERP_KERNEL::Exception(MSG1); + if(zeArr2->getName()==ANGLE_DE_VRILLE) + return BuildMeshFromAngleVrille(gt,zeArr2,pfl,loc,zeStr,mesh,section,globs); + if(zeArr2->getName()==EPAISSEUR) + return BuildMeshFromEpaisseur(gt,zeArr2,pfl,loc,zeStr,mesh,section,globs); + throw INTERP_KERNEL::Exception(MSG1); +} + +MCAuto LocInfo::generateNonClassicalData(int zePos, const MEDFileUMesh *mesh, const MEDFileFieldGlobsReal *globs) const +{ + static const char MSG1[]="LocInfo::generateNonClassicalData : no spec for GAUSS on StructureElement with more than one cell !"; + std::size_t sz(_locs.size()); + std::vector< MCAuto > arrs(sz); + for(std::size_t i=0;igetLocalization(_locs[i])); + const MEDFileGTKeeper *gtk(loc.getUndergroundGTKeeper()); + const MEDFileGTKeeperDyn *gtk2(dynamic_cast(gtk)); + if(!gtk2) + throw INTERP_KERNEL::Exception("LocInfo::generateNonClassicalData : internal error !"); + const MEDFileUMesh *meshLoc(gtk2->getMesh()),*section(gtk2->getSection()); + const MEDFileStructureElement *se(gtk2->getSE()); + INTERP_KERNEL::NormalizedCellType gt; + { + std::vector nel(meshLoc->getNonEmptyLevels()); + if(nel.size()!=1) + throw INTERP_KERNEL::Exception(MSG1); + if(nel[0]!=0) + throw INTERP_KERNEL::Exception(MSG1); + MCAuto um(meshLoc->getMeshAtLevel(0)); + if(um->getNumberOfCells()!=1) + throw INTERP_KERNEL::Exception(MSG1); + gt=um->getTypeOfCell(0); + std::vector v; + um->getNodeIdsOfCell(0,v); + std::size_t sz2(v.size()); + for(std::size_t j=0;j >& strs(mesh->getAccessOfUndergroundEltStrs()); + MCAuto zeStr; + for(std::vector< MCAuto >::const_iterator it=strs.begin();it!=strs.end();it++) + { + if((*it)->getGeoTypeName()==se->getName()) + { + zeStr=*it; + break; + } + } + if(zeStr.isNull()) + { + std::ostringstream oss; oss << "LocInfo::generateNonClassicalData : : no geo type with name " << se->getName() << " in " << mesh->getName() << " !"; + throw INTERP_KERNEL::Exception(oss.str()); + } + arrs[i]=BuildMeshFromStructure(gt,_pfl[i],loc,zeStr,mesh,section,globs); + } + std::vector arrs2(VecAutoToVecOfCstPt(arrs)); + MCAuto resu(DataArrayDouble::Aggregate(arrs2)); + MCAuto ret(MEDFileUMesh::New()); + ret->setCoords(resu); + std::ostringstream meshName; meshName << mesh->getName() << "_on_" << sz << "_sections" << "_" << zePos; + ret->setName(meshName.str()); + return ret; +} + +FieldWalker2::FieldWalker2(const MEDFileFieldPerMeshPerTypePerDisc *pmptpd) +{ + _loc=pmptpd->getLocalization(); + _pfl=pmptpd->getProfile(); + _is_classic=pmptpd->getType()!=ON_GAUSS_PT; + _pd=SlicePartDefinition::New(pmptpd->getStart(),pmptpd->getEnd(),1); +} + +bool FieldWalker2::operator!=(const FieldWalker2& other) const +{ + return !((*this)==other); +} + +bool FieldWalker2::operator==(const FieldWalker2& other) const +{ + bool ret2(false); + { + std::string tmp; + ret2=_pd->isEqual(other._pd,tmp); + } + bool ret(_loc==other._loc && _pfl==other._pfl && _is_classic==other._is_classic && ret2); + return ret; +} + +class FieldWalker1 +{ +public: + FieldWalker1(const MEDFileAnyTypeField1TSWithoutSDA *ts):_ts(ts),_pm_pt(0),_nb_mesh(0) { } + void newMeshEntry(const MEDFileFieldPerMesh *fpm); + void endMeshEntry(const MEDFileFieldPerMesh *fpm) { } + void newPerMeshPerTypeEntry(const MEDFileFieldPerMeshPerTypeCommon *pmpt); + void endPerMeshPerTypeEntry(const MEDFileFieldPerMeshPerTypeCommon *pmpt); + void newPerMeshPerTypePerDisc(const MEDFileFieldPerMeshPerTypePerDisc *pmptpd); + void checkOK(const FieldWalker1& other) const; + bool isClassical() const; + std::vector getNonClassicalData() const { return _fw; } +private: + const MEDFileAnyTypeField1TSWithoutSDA *_ts; + const MEDFileFieldPerMeshPerTypeDyn *_pm_pt; + std::vector _fw; + int _nb_mesh; +}; + +void FieldWalker1::newMeshEntry(const MEDFileFieldPerMesh *fpm) +{ + if(_nb_mesh++==1) + throw INTERP_KERNEL::Exception("FieldWalker1::newMeshEntry : multi mesh not supported !"); +} + +void FieldWalker1::newPerMeshPerTypeEntry(const MEDFileFieldPerMeshPerTypeCommon *pmpt) +{ + if(_pm_pt) + throw INTERP_KERNEL::Exception("FieldWalker1::newPerMeshPerTypeEntry : multi SE loc not managed yet !"); + const MEDFileFieldPerMeshPerTypeDyn *pmpt2(dynamic_cast(pmpt)); + if(!pmpt2) + throw INTERP_KERNEL::Exception("newPerMeshPerTypeEntry : internal error !"); + _pm_pt=pmpt2; +} + +void FieldWalker1::endPerMeshPerTypeEntry(const MEDFileFieldPerMeshPerTypeCommon *) +{ + isClassical(); +} + +void FieldWalker1::newPerMeshPerTypePerDisc(const MEDFileFieldPerMeshPerTypePerDisc *pmptpd) +{ + _fw.push_back(FieldWalker2(pmptpd)); +} + +void FieldWalker1::checkOK(const FieldWalker1& other) const +{ + std::size_t sz(_fw.size()); + if(other._fw.size()!=sz) + throw INTERP_KERNEL::Exception("checkOK : not OK because size are not the same !"); + for(std::size_t i=0;i::const_iterator it=_fw.begin();it!=_fw.end();it++) + { + if((*it).isClassic()) + ic++; + else + inc++; + } + if(ic!=0 && inc!=0) + throw INTERP_KERNEL::Exception("FieldWalker1::endPerMeshPerTypeEntry : mix is not allowed yet !"); + return inc==0; +} + +class FieldWalker +{ +public: + FieldWalker(const MEDFileAnyTypeFieldMultiTSWithoutSDA *f):_f(f) { } + void newTimeStepEntry(const MEDFileAnyTypeField1TSWithoutSDA *ts); + void endTimeStepEntry(const MEDFileAnyTypeField1TSWithoutSDA *ts); + void newMeshEntry(const MEDFileFieldPerMesh *fpm); + void endMeshEntry(const MEDFileFieldPerMesh *fpm); + void newPerMeshPerTypeEntry(const MEDFileFieldPerMeshPerTypeCommon *pmpt); + void endPerMeshPerTypeEntry(const MEDFileFieldPerMeshPerTypeCommon *pmpt); + void newPerMeshPerTypePerDisc(const MEDFileFieldPerMeshPerTypePerDisc *pmptpd); +public: + bool isEmpty() const; + bool isClassical() const; + const MEDFileAnyTypeFieldMultiTSWithoutSDA *field() const { return _f; } + std::vector getNonClassicalData() const { return _fw_prev->getNonClassicalData(); } +private: + const MEDFileAnyTypeFieldMultiTSWithoutSDA *_f; + mutable INTERP_KERNEL::AutoCppPtr _fw; + mutable INTERP_KERNEL::AutoCppPtr _fw_prev; +}; + +bool FieldWalker::isEmpty() const +{ + return _fw_prev.isNull(); +} + +bool FieldWalker::isClassical() const +{ + return _fw_prev->isClassical(); +} + +void FieldWalker::newTimeStepEntry(const MEDFileAnyTypeField1TSWithoutSDA *ts) +{ + _fw=new FieldWalker1(ts); +} + +void FieldWalker::endTimeStepEntry(const MEDFileAnyTypeField1TSWithoutSDA *ts) +{ + if(_fw_prev.isNull()) + _fw_prev=new FieldWalker1(*_fw); + else + _fw_prev->checkOK(*_fw); + _fw=0; +} + +void FieldWalker::newMeshEntry(const MEDFileFieldPerMesh *fpm) +{ + _fw->newMeshEntry(fpm); +} + +void FieldWalker::endMeshEntry(const MEDFileFieldPerMesh *fpm) +{ + _fw->endMeshEntry(fpm); +} + +void FieldWalker::newPerMeshPerTypeEntry(const MEDFileFieldPerMeshPerTypeCommon *pmpt) +{ + _fw->newPerMeshPerTypeEntry(pmpt); +} + +void FieldWalker::endPerMeshPerTypeEntry(const MEDFileFieldPerMeshPerTypeCommon *pmpt) +{ + _fw->endPerMeshPerTypeEntry(pmpt); +} + +void FieldWalker::newPerMeshPerTypePerDisc(const MEDFileFieldPerMeshPerTypePerDisc *pmptpd) +{ + _fw->newPerMeshPerTypePerDisc(pmptpd); +} + +// this class splits fields into same +class LocSpliter : public MEDFileFieldVisitor +{ +public: + LocSpliter(const MEDFileFieldGlobsReal *globs):_globs(globs),_fw(0) { } + MCAuto getClassical() const { return _classical; } + void generateNonClassicalData(const MEDFileUMesh *mesh, std::vector< MCAuto >& outFields, std::vector< MCAuto >& outMeshes) const; +private: + void newFieldEntry(const MEDFileAnyTypeFieldMultiTSWithoutSDA *field); + void endFieldEntry(const MEDFileAnyTypeFieldMultiTSWithoutSDA *field); + // + void newTimeStepEntry(const MEDFileAnyTypeField1TSWithoutSDA *ts); + void endTimeStepEntry(const MEDFileAnyTypeField1TSWithoutSDA *ts); + // + void newMeshEntry(const MEDFileFieldPerMesh *fpm); + void endMeshEntry(const MEDFileFieldPerMesh *fpm); + // + void newPerMeshPerTypeEntry(const MEDFileFieldPerMeshPerTypeCommon *pmpt); + void endPerMeshPerTypeEntry(const MEDFileFieldPerMeshPerTypeCommon *pmpt); + // + void newPerMeshPerTypePerDisc(const MEDFileFieldPerMeshPerTypePerDisc *pmptpd); +private: + const MEDFileFieldGlobsReal *_globs; + std::vector< LocInfo > _locs; + std::vector< MCAuto > _fields_on_locs;//size of _locs== size of _fields_on_locs + MCAuto _classical; +private: + mutable INTERP_KERNEL::AutoCppPtr _fw; +}; + +void LocSpliter::newFieldEntry(const MEDFileAnyTypeFieldMultiTSWithoutSDA *field) +{ + _fw=new FieldWalker(field); +} + +void LocSpliter::endFieldEntry(const MEDFileAnyTypeFieldMultiTSWithoutSDA *field) +{ + if(_fw->isEmpty()) + return ; + MCAuto f(MEDFileAnyTypeFieldMultiTS::BuildNewInstanceFromContent(const_cast(field))); + if(_fw->isClassical()) + { + if(_classical.isNull()) + { + _classical=MEDFileFields::New(); + _classical->shallowCpyGlobs(*_globs); + } + _classical->pushField(f); + } + else + { + std::vector fw2(_fw->getNonClassicalData()); + LocInfo elt(fw2); + std::vector< LocInfo >::iterator it(std::find(_locs.begin(),_locs.end(),elt)); + if(it==_locs.end()) + { + _locs.push_back(elt); + MCAuto zeF(MEDFileFields::New()); + zeF->shallowCpyGlobs(*_globs); + zeF->pushField(f); + _fields_on_locs.push_back(zeF); + } + else + { + MCAuto zeF(_fields_on_locs[std::distance(_locs.begin(),it)]); + zeF->pushField(f); + } + } +} + +void LocSpliter::generateNonClassicalData(const MEDFileUMesh *mesh, std::vector< MCAuto >& outFields, std::vector< MCAuto >& outMeshes) const +{ + int i(0); + for(std::vector::const_iterator it=_locs.begin();it!=_locs.end();it++,i++) + { + MCAuto m((*it).generateNonClassicalData(i,mesh,_globs)); + outMeshes.push_back(m); + MCAuto mcm(MEDCouplingUMesh::Build0DMeshFromCoords(m->getCoords())); + mcm->setName(m->getName()); + MCAuto fs(_fields_on_locs[i]); + MCAuto outFs(MEDFileFields::New()); + for(int j=0;jgetNumberOfFields();j++) + { + MCAuto fmtsNC(fs->getFieldAtPos(j)); + MCAuto fmts(DynamicCastSafe(fmtsNC)); + MCAuto outFmts(MEDFileFieldMultiTS::New()); + for(int k=0;kgetNumberOfTS();k++) + { + MCAuto outF1t(MEDFileField1TS::New()); + MCAuto f1ts(fmts->getTimeStepAtPos(k)); + int t2,t3; + double t1(f1ts->getTime(t2,t3)); + MCAuto mcf(MEDCouplingFieldDouble::New(ON_NODES)); + MCAuto arr,arr2; + arr.takeRef(f1ts->getUndergroundDataArray()); + arr2=arr->selectPartDef((*it).getPartDef()); + mcf->setArray(arr2); + mcf->setTime(t1,t2,t3); + mcf->setName(f1ts->getName()); + mcf->setMesh(mcm); + outF1t->setFieldNoProfileSBT(mcf); + outFmts->pushBackTimeStep(outF1t); + } + outFs->pushField(outFmts); + } + outFields.push_back(outFs); + } +} + +void LocSpliter::newTimeStepEntry(const MEDFileAnyTypeField1TSWithoutSDA *ts) +{ + _fw->newTimeStepEntry(ts); +} + +void LocSpliter::endTimeStepEntry(const MEDFileAnyTypeField1TSWithoutSDA *ts) +{ + _fw->endTimeStepEntry(ts); +} + +void LocSpliter::newMeshEntry(const MEDFileFieldPerMesh *fpm) +{ + _fw->newMeshEntry(fpm); +} + +void LocSpliter::endMeshEntry(const MEDFileFieldPerMesh *fpm) +{ + _fw->endMeshEntry(fpm); +} + +void LocSpliter::newPerMeshPerTypeEntry(const MEDFileFieldPerMeshPerTypeCommon *pmpt) +{ + _fw->newPerMeshPerTypeEntry(pmpt); +} + +void LocSpliter::endPerMeshPerTypeEntry(const MEDFileFieldPerMeshPerTypeCommon *pmpt) +{ + _fw->endPerMeshPerTypeEntry(pmpt); +} + +void LocSpliter::newPerMeshPerTypePerDisc(const MEDFileFieldPerMeshPerTypePerDisc *pmptpd) +{ + _fw->newPerMeshPerTypePerDisc(pmptpd); +} + +void MEDFileBlowStrEltUp::DealWithConflictNames(MEDFileAnyTypeFieldMultiTS *fmtsToAdd, const MEDFileFields *fs) +{ + std::vector fnames(fs->getFieldsNames()); + for(int i=0;i<1000;i++) + { + std::ostringstream oss; oss << fmtsToAdd->getName(); + if(i>=1) + oss << "_" << i-1; + if(std::find(fnames.begin(),fnames.end(),oss.str())==fnames.end()) + { + fmtsToAdd->setName(oss.str()); + return ; + } + } + throw INTERP_KERNEL::Exception("DealWithConflictNames : Eh eh interesting !"); +} + +MCAuto MEDFileBlowStrEltUp::splitFieldsPerLoc(const MEDFileFields *fields, const MEDFileUMesh *mesh, MEDFileMeshes *msOut, MEDFileFields *allZeOutFields) +{ + LocSpliter ls(fields); + fields->accept(ls); + std::vector< MCAuto > outFields; + std::vector< MCAuto > outMeshes; + ls.generateNonClassicalData(mesh,outFields,outMeshes); + for(std::vector< MCAuto >::iterator it=outFields.begin();it!=outFields.end();it++) + { + for(int j=0;j<(*it)->getNumberOfFields();j++) + { + MCAuto fmts((*it)->getFieldAtPos(j)); + //DealWithConflictNames(fmts,allZeOutFields);// uncomment to have a writable data structure + allZeOutFields->pushField(fmts); + } + } + for(std::vector< MCAuto >::iterator it=outMeshes.begin();it!=outMeshes.end();it++) + msOut->pushMesh(*it); + return ls.getClassical(); }