X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FMEDLoader%2FMEDFileBlowStrEltUp.cxx;h=3e87d2004316afe073cdede78fabca647ded5538;hb=3ccbd6672d4cab9ddd873774deb1276b43ccb621;hp=fcd9e51fab2c05f75c67c7aeb68cb0733125279e;hpb=869fc0294f52a1a5bd79cf1cca53aca1d361ad44;p=tools%2Fmedcoupling.git diff --git a/src/MEDLoader/MEDFileBlowStrEltUp.cxx b/src/MEDLoader/MEDFileBlowStrEltUp.cxx index fcd9e51fa..3e87d2004 100644 --- a/src/MEDLoader/MEDFileBlowStrEltUp.cxx +++ b/src/MEDLoader/MEDFileBlowStrEltUp.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2017 CEA/DEN, EDF R&D +// Copyright (C) 2007-2024 CEA, EDF // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -20,6 +20,10 @@ #include "MEDFileBlowStrEltUp.hxx" #include "MEDCouplingFieldDouble.hxx" +#include "MEDFileFieldVisitor.hxx" +#include "MEDCouplingPartDefinition.hxx" +#include "MCAuto.txx" +#include using namespace MEDCoupling; @@ -91,36 +95,35 @@ MCAuto MEDFileBlowStrEltUp::dealWithMEDBALLInMesh(const M const DataArrayDouble *coo(mesh->getCoords()); if(!coo) throw INTERP_KERNEL::Exception("MEDFileBlowStrEltUp::dealWithMEDBALLInMesh : null coords !"); - MCAuto conn(zeStr->getConn()); + MCAuto conn(zeStr->getConn()); if(conn.isNull()) throw INTERP_KERNEL::Exception("MEDFileBlowStrEltUp::dealWithMEDBALLInMesh : null connectivity !"); conn->checkAllocated(); if(conn->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception("MEDFileBlowStrEltUp::dealWithMEDBALLInMesh : excepted to be single compo !"); - int nbCells(conn->getNumberOfTuples()); MCAuto connOut(coo->selectByTupleIdSafe(conn->begin(),conn->end())); MCAuto mcOut(MEDCouplingUMesh::Build0DMeshFromCoords(connOut)); mcOut->setName(BuildNewMeshName(mesh->getName(),MED_BALL_STR)); mOut->setMeshAtLevel(0,mcOut); - const DataArrayInt *ff1(mesh->getFamilyFieldAtLevel(1)); + const DataArrayIdType *ff1(mesh->getFamilyFieldAtLevel(1)); if(ff1) { - MCAuto ff1o(ff1->selectByTupleIdSafe(conn->begin(),conn->end())); + MCAuto ff1o(ff1->selectByTupleIdSafe(conn->begin(),conn->end())); mOut->setFamilyFieldArr(1,ff1o); } - const DataArrayInt *nf1(mesh->getNumberFieldAtLevel(1)); + const DataArrayIdType *nf1(mesh->getNumberFieldAtLevel(1)); if(nf1) { - MCAuto nf1o(nf1->selectByTupleIdSafe(conn->begin(),conn->end())); + MCAuto nf1o(nf1->selectByTupleIdSafe(conn->begin(),conn->end())); mOut->setRenumFieldArr(1,nf1o); } MCAuto md(zeStr->getMeshDef()); - const DataArrayInt *ff0(md->getFam()); + const DataArrayIdType *ff0(md->getFam()); if(ff0) - mOut->setFamilyFieldArr(0,const_cast(ff0)); - const DataArrayInt *nf0(md->getNum()); + mOut->setFamilyFieldArr(0,const_cast(ff0)); + const DataArrayIdType *nf0(md->getNum()); if(nf0) - mOut->setRenumFieldArr(0,const_cast(nf0)); + 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++) @@ -219,7 +222,7 @@ void MEDFileBlowStrEltUp::dealWithMEDBALLSInFields(const MEDFileFields *fs, cons std::vector pfls(zeGuideForPfl->getPflsReallyUsed()); if(pfls.size()>=2) throw INTERP_KERNEL::Exception("MEDFileBlowStrEltUp::dealWithMEDBALLSInFields : drink less coffee"); - MCAuto pflMyLove; + MCAuto pflMyLove; if(pfls.size()==1) pflMyLove.takeRef(zeGuideForPfl->getProfile(pfls[0])); // Yeah we have pfls @@ -264,11 +267,16 @@ void MEDFileBlowStrEltUp::generate(MEDFileMeshes *msOut, MEDFileFields *allZeOut MEDFileUMesh *umesh(dynamic_cast(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(mOut); - dealWithSEInFields(ps[0].second,*elt,zeStr,fsOut1,allZeOutFields); + // + 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); + } } } @@ -294,4 +302,814 @@ void MEDFileBlowStrEltUp::DealWithSE(MEDFileFields *fs, MEDFileMeshes *ms, const fs->killStructureElements(); MEDFileBlowStrEltUp bu(fsSEOnly,ms,ses); 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; } + INTERP_KERNEL::NormalizedCellType getGeoType() const { return _ct; } + 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; + INTERP_KERNEL::NormalizedCellType _ct; + 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 *thickness, const std::string& pfl, const MEDFileFieldLoc& loc, const MEDFileEltStruct4Mesh *zeStr, const MEDFileUMesh *mesh, const MEDFileUMesh *section, const MEDFileFieldGlobsReal *globs); + static MCAuto BuildMeshPipeSEG3(const DataArrayDouble *angle, const DataArrayDouble *scale, const std::string& pfl, const MEDFileFieldLoc& loc, const MEDFileEltStruct4Mesh *zeStr, const MEDFileUMesh *mesh, const MEDFileUMesh *section, const MEDFileFieldGlobsReal *globs); + static MCAuto BuildMeshPipeSEG4(const DataArrayDouble *angle, const DataArrayDouble *scale, 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 ANGLE[]; + static const char SCALE[]; + static const char EPAISSEUR[]; +private: + std::vector _locs; + std::vector _pfl; + std::vector _cts; + MCAuto _pd; +}; + +const char LocInfo::ANGLE_DE_VRILLE[]="ANGLE DE VRILLE"; + +const char LocInfo::ANGLE[]="ANGLE"; + +const char LocInfo::SCALE[]="SCALE"; + +const char LocInfo::EPAISSEUR[]="EPAISSEUR"; + +LocInfo::LocInfo(const std::vector& fw) +{ + std::size_t sz(fw.size()); + _locs.resize(sz); _pfl.resize(sz); _cts.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(); + } + // + if(!pfl.empty()) + { + const DataArrayIdType *pflArr(globs->getProfile(pfl)); + geoMesh=geoMesh->buildPartOfMySelf(pflArr->begin(),pflArr->end(),true); + } + // + 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 DataArrayIdType *pflArr(globs->getProfile(pfl)); + angleVrille=angleDeVrille->selectByTupleIdSafe(pflArr->begin(),pflArr->end()); + } + else + angleVrille.takeRef(angleDeVrille); + // + MCAuto dir(geoMesh->buildDirectionVectorField()); + MCAuto rot(dir->getArray()->fromCartToSpher()); + std::size_t nbCompo(ptsForLoc->getNumberOfComponents()); + MCAuto secPts(section->getCoords()->changeNbOfComponents(nbCompo,0.)); + mcIdType nbSecPts(secPts->getNumberOfTuples()),nbCells(geoMesh->getNumberOfCells()),nbg(ToIdType(loc.getGaussWeights().size())); + { + const int TAB[3]={2,0,1}; + std::vector v(TAB,TAB+3); + secPts=secPts->keepSelectedComponents(v); + } + 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(std::size_t 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 *thickness, 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)); + mcIdType nbCells(geoMesh->getNumberOfCells()),nbg(ToIdType(loc.getGaussWeights().size())); + MCConstAuto zeThickness; + if(!pfl.empty()) + { + const DataArrayIdType *pflArr(globs->getProfile(pfl)); + zeThickness=thickness->selectByTupleIdSafe(pflArr->begin(),pflArr->end()); + } + else + zeThickness.takeRef(thickness); + MCAuto orthoArr; + { + MCAuto ortho(geoMesh->buildOrthogonalField()); + orthoArr.takeRef(ortho->getArray()); + } + mcIdType nbCompo(ToIdType(orthoArr->getNumberOfComponents())); + MCAuto secPts(section->getCoords()->duplicateEachTupleNTimes(nbCompo)); + secPts->rearrange(nbCompo); + std::vector< MCAuto > arrs(nbCells*nbg); + for(mcIdType j=0;jgetIJ(j,0)),eccentricity(zeThickness->getIJ(j,1)); + MCAuto fact(DataArrayDouble::New()),fact2(DataArrayDouble::New()); fact->alloc(1,nbCompo); fact2->alloc(1,nbCompo); + std::copy(orthoArr->begin()+j*nbCompo,orthoArr->begin()+(j+1)*nbCompo,fact->getPointer()); + std::copy(orthoArr->begin()+j*nbCompo,orthoArr->begin()+(j+1)*nbCompo,fact2->getPointer()); + std::for_each(fact2->rwBegin(),fact2->rwEnd(),[eccentricity](double& val){ val*=eccentricity; }); + std::transform(fact->begin(),fact->end(),fact->getPointer(),[thck](const double& val){ return val*thck/2.; }); + MCAuto p(DataArrayDouble::Multiply(secPts,fact)); + p=DataArrayDouble::Add(p,fact2); + 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::BuildMeshPipeSEG3(const DataArrayDouble *angle, const DataArrayDouble *scale, const std::string& pfl, const MEDFileFieldLoc& loc, const MEDFileEltStruct4Mesh *zeStr, const MEDFileUMesh *mesh, const MEDFileUMesh *section, const MEDFileFieldGlobsReal *globs) +{ + static const char MSG1[]="BuildMeshPipeSEG3 : not recognized pattern ! Send mail to anthony.geay@edf.fr with corresponding MED file !"; + MCAuto ptsForLoc; + MCAuto geoMesh(BuildMeshCommon(INTERP_KERNEL::NORM_SEG3,pfl,loc,zeStr,mesh,section,globs,ptsForLoc)); + mcIdType nbSecPts(section->getNumberOfNodes()),nbCells(geoMesh->getNumberOfCells()),nbg(ToIdType(loc.getGaussWeights().size())); + MCConstAuto zeAngle,zeScale; + if(!pfl.empty()) + { + const DataArrayIdType *pflArr(globs->getProfile(pfl)); + zeAngle=angle->selectByTupleIdSafe(pflArr->begin(),pflArr->end()); + zeScale=scale->selectByTupleIdSafe(pflArr->begin(),pflArr->end()); + } + else + { + zeAngle.takeRef(angle); + zeScale.takeRef(scale); + } + if(zeAngle->getNumberOfComponents()!=3 || zeScale->getNumberOfComponents()!=2 || nbg!=3) + throw INTERP_KERNEL::Exception(MSG1); + MCAuto dir; + { + MCAuto geoMesh2(geoMesh->deepCopy()); + geoMesh2->convertQuadraticCellsToLinear(); + dir=geoMesh2->buildDirectionVectorField(); + } + MCAuto rot(dir->getArray()->fromCartToSpher()); + std::size_t nbCompo(ptsForLoc->getNumberOfComponents()); + MCAuto secPts(section->getCoords()->changeNbOfComponents(nbCompo,0.)); + { + const int TAB[3]={2,0,1}; + std::vector v(TAB,TAB+3); + secPts=secPts->keepSelectedComponents(v); + } + 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(mcIdType j=0;j p(secPts->deepCopy()); + double ang0(rot->getIJ(j,2)); + double rmin(zeScale->getIJ(j,0)),rmax(zeScale->getIJ(j,1)); + { + auto pt(p->rwBegin()); + for(int i=0;ibegin(),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()); + for(int l=0;l<3;l++) + { + MCAuto p3(p->deepCopy()); + DataArrayDouble::Rotate3DAlg(CENTER,dir->getArray()->begin()+j*3,zeAngle->getIJ(j,l),nbSecPts,p3->begin(),p3->getPointer()); + MCAuto p2(p3->deepCopy()); + for(std::size_t 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::BuildMeshPipeSEG4(const DataArrayDouble *angle, const DataArrayDouble *scale, const std::string& pfl, const MEDFileFieldLoc& loc, const MEDFileEltStruct4Mesh *zeStr, const MEDFileUMesh *mesh, const MEDFileUMesh *section, const MEDFileFieldGlobsReal *globs) +{ + static const char MSG1[]="BuildMeshPipeSEG4 : not recognized pattern ! Send mail to anthony.geay@edf.fr with corresponding MED file !"; + MCAuto ptsForLoc; + MCAuto geoMesh(BuildMeshCommon(INTERP_KERNEL::NORM_SEG4,pfl,loc,zeStr,mesh,section,globs,ptsForLoc)); + mcIdType nbSecPts(section->getNumberOfNodes()),nbCells(geoMesh->getNumberOfCells()),nbg(ToIdType(loc.getGaussWeights().size())); + MCConstAuto zeAngle,zeScale; + if(!pfl.empty()) + { + const DataArrayIdType *pflArr(globs->getProfile(pfl)); + zeAngle=angle->selectByTupleIdSafe(pflArr->begin(),pflArr->end()); + zeScale=scale->selectByTupleIdSafe(pflArr->begin(),pflArr->end()); + } + else + { + zeAngle.takeRef(angle); + zeScale.takeRef(scale); + } + if(zeAngle->getNumberOfComponents()!=4 || zeScale->getNumberOfComponents()!=2 || nbg!=3) + throw INTERP_KERNEL::Exception(MSG1); + MCAuto dir; + { + MCAuto geoMesh2(geoMesh->deepCopy()); + geoMesh2->convertQuadraticCellsToLinear(); + dir=geoMesh2->buildDirectionVectorField(); + } + MCAuto rot(dir->getArray()->fromCartToSpher()); + std::size_t nbCompo(ptsForLoc->getNumberOfComponents()); + MCAuto secPts(section->getCoords()->changeNbOfComponents(nbCompo,0.)); + { + const int TAB[3]={2,0,1}; + std::vector v(TAB,TAB+3); + secPts=secPts->keepSelectedComponents(v); + } + 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(mcIdType j=0;j p(secPts->deepCopy()); + double ang0(rot->getIJ(j,2)); + double rmin(zeScale->getIJ(j,0)),rmax(zeScale->getIJ(j,1)); + { + auto pt(p->rwBegin()); + for(int i=0;ibegin(),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()); + for(int l=0;l<3;l++) + { + MCAuto p3(p->deepCopy()); + DataArrayDouble::Rotate3DAlg(CENTER,dir->getArray()->begin()+j*3,zeAngle->getIJ(j,l),nbSecPts,p3->begin(),p3->getPointer()); + MCAuto p2(p3->deepCopy()); + for(std::size_t 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) + { + 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 || zeArr2->getName()==ANGLE) + return BuildMeshFromAngleVrille(gt,zeArr2,pfl,loc,zeStr,mesh,section,globs); + if(zeArr2->getName()==EPAISSEUR || zeArr2->getName()==SCALE) + return BuildMeshFromEpaisseur(gt,zeArr2,pfl,loc,zeStr,mesh,section,globs); + } + if(vars.size()==2) + { + MCAuto zeArr0(vars[0]),zeArr1(vars[1]); + if(zeArr0.isNull() || zeArr1.isNull()) + throw INTERP_KERNEL::Exception(MSG1); + MCAuto zeArr00(DynamicCastSafe(zeArr0)),zeArr11(DynamicCastSafe(zeArr1)); + MCAuto angle,scale; + if(zeArr00->getName()==ANGLE) + angle=zeArr00; + if(zeArr00->getName()==SCALE) + scale=zeArr00; + if(zeArr11->getName()==ANGLE) + angle=zeArr11; + if(zeArr11->getName()==SCALE) + scale=zeArr11; + if(angle.isNull() || scale.isNull()) + throw INTERP_KERNEL::Exception(MSG1); + switch(gt) + { + case INTERP_KERNEL::NORM_SEG3: + { + return BuildMeshPipeSEG3(angle,scale,pfl,loc,zeStr,mesh,section,globs); + } + case INTERP_KERNEL::NORM_SEG4: + { + return BuildMeshPipeSEG4(angle,scale,pfl,loc,zeStr,mesh,section,globs); + } + default: + throw INTERP_KERNEL::Exception(MSG1); + } + } + 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()); + MCAuto um(meshLoc->getMeshAtLevel(0)); + INTERP_KERNEL::NormalizedCellType gt(_cts[i]); + { + std::vector nel(meshLoc->getNonEmptyLevels()); + if(nel.size()!=1) + throw INTERP_KERNEL::Exception(MSG1); + if(nel[0]!=0) + throw INTERP_KERNEL::Exception(MSG1); + mcIdType zePos(-1); + for(mcIdType icell = 0 ; icell < um->getNumberOfCells() ; ++icell) + if( gt == um->getTypeOfCell(icell) ) + zePos = icell; + if(zePos == -1) + throw INTERP_KERNEL::Exception(MSG1); + std::vector v; + um->getNodeIdsOfCell(zePos,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(); + _ct=pmptpd->getGeoTypeStatic(); + _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(); }