1 // Copyright (C) 2007-2017 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 "MEDFileBlowStrEltUp.hxx"
22 #include "MEDCouplingFieldDouble.hxx"
23 #include "MEDFileFieldVisitor.hxx"
26 using namespace MEDCoupling;
28 const char MEDFileBlowStrEltUp::MED_BALL_STR[]="MED_BALL";
30 MEDFileBlowStrEltUp::MEDFileBlowStrEltUp(const MEDFileFields *fsOnlyOnSE, const MEDFileMeshes *ms, const MEDFileStructureElements *ses)
32 if(!fsOnlyOnSE || !ms || !ses)
33 throw INTERP_KERNEL::Exception("MEDFileBlowStrEltUp constructor : NULL input pointer !");
34 _ms.takeRef(ms); _ses.takeRef(ses);
35 std::vector< std::pair<std::string,std::string> > ps;
36 fsOnlyOnSE->getMeshSENames(ps);
37 std::size_t sz(ps.size());
39 for(std::size_t i=0;i<sz;i++)
41 const std::pair<std::string,std::string>& p(ps[i]);
42 MCAuto<MEDFileFields> f(fsOnlyOnSE->partOfThisLyingOnSpecifiedMeshSEName(p.first,p.second));
45 for(std::size_t i=0;i<sz;i++)
47 const std::pair<std::string,std::string>& p(ps[i]);
48 MEDFileMesh *mesh(_ms->getMeshWithName(p.first));
50 throw INTERP_KERNEL::Exception("MEDFileBlowStrEltUp : NULL mesh !");
51 MEDFileUMesh *umesh(dynamic_cast<MEDFileUMesh *>(mesh));
53 throw INTERP_KERNEL::Exception("MEDFileBlowStrEltUp : Blow up of Stru Elt not managed yet for unstructured meshes !");
58 * \param [in] mesh - The mesh containing structure element called \a seName. After the call of this method the Structure elements parts will be removed.
59 * \param [out] mOut - the physical mesh of the structure element \a seName in mesh \a mesh
60 * \param [out] fsOut - the list of var attribute of structure element \a seName - \b WARNING no time steps here
62 MCAuto<MEDFileEltStruct4Mesh> MEDFileBlowStrEltUp::dealWithSEInMesh(const std::string& seName, MEDFileUMesh *mesh, MCAuto<MEDFileUMesh>& mOut, MCAuto<MEDFileFields>& fsOut) const
65 throw INTERP_KERNEL::Exception("MEDFileBlowStrEltUp::dealWithSEInMesh : null pointer !");
66 if(seName==MED_BALL_STR)
68 MCAuto<MEDFileEltStruct4Mesh> ret(dealWithMEDBALLInMesh(mesh,mOut,fsOut));
69 mesh->killStructureElements();
72 throw INTERP_KERNEL::Exception("MEDFileBlowStrEltUp::dealWithSEInMesh : only MED_BALL is managed for the moment, but if you are interested please send spec to anthony.geay@edf.fr !");
75 MCAuto<MEDFileEltStruct4Mesh> MEDFileBlowStrEltUp::dealWithMEDBALLInMesh(const MEDFileUMesh *mesh, MCAuto<MEDFileUMesh>& mOut, MCAuto<MEDFileFields>& fsOut) const
77 mOut=MEDFileUMesh::New(); fsOut=MEDFileFields::New();
78 const std::vector< MCAuto<MEDFileEltStruct4Mesh> >& strs(mesh->getAccessOfUndergroundEltStrs());
79 MCAuto<MEDFileEltStruct4Mesh> zeStr;
80 for(std::vector< MCAuto<MEDFileEltStruct4Mesh> >::const_iterator it=strs.begin();it!=strs.end();it++)
82 if((*it)->getGeoTypeName()==MED_BALL_STR)
90 std::ostringstream oss; oss << "MEDFileBlowStrEltUp::dealWithMEDBALLInMesh : no geo type with name " << MED_BALL_STR << " in " << mesh->getName() << " !";
91 throw INTERP_KERNEL::Exception(oss.str());
93 const DataArrayDouble *coo(mesh->getCoords());
95 throw INTERP_KERNEL::Exception("MEDFileBlowStrEltUp::dealWithMEDBALLInMesh : null coords !");
96 MCAuto<DataArrayInt> conn(zeStr->getConn());
98 throw INTERP_KERNEL::Exception("MEDFileBlowStrEltUp::dealWithMEDBALLInMesh : null connectivity !");
99 conn->checkAllocated();
100 if(conn->getNumberOfComponents()!=1)
101 throw INTERP_KERNEL::Exception("MEDFileBlowStrEltUp::dealWithMEDBALLInMesh : excepted to be single compo !");
102 int nbCells(conn->getNumberOfTuples());
103 MCAuto<DataArrayDouble> connOut(coo->selectByTupleIdSafe(conn->begin(),conn->end()));
104 MCAuto<MEDCouplingUMesh> mcOut(MEDCouplingUMesh::Build0DMeshFromCoords(connOut));
105 mcOut->setName(BuildNewMeshName(mesh->getName(),MED_BALL_STR));
106 mOut->setMeshAtLevel(0,mcOut);
107 const DataArrayInt *ff1(mesh->getFamilyFieldAtLevel(1));
110 MCAuto<DataArrayInt> ff1o(ff1->selectByTupleIdSafe(conn->begin(),conn->end()));
111 mOut->setFamilyFieldArr(1,ff1o);
113 const DataArrayInt *nf1(mesh->getNumberFieldAtLevel(1));
116 MCAuto<DataArrayInt> nf1o(nf1->selectByTupleIdSafe(conn->begin(),conn->end()));
117 mOut->setRenumFieldArr(1,nf1o);
119 MCAuto<MEDFileUMeshPerTypeCommon> md(zeStr->getMeshDef());
120 const DataArrayInt *ff0(md->getFam());
122 mOut->setFamilyFieldArr(0,const_cast<DataArrayInt *>(ff0));
123 const DataArrayInt *nf0(md->getNum());
125 mOut->setRenumFieldArr(0,const_cast<DataArrayInt *>(nf0));
126 mOut->copyFamGrpMapsFrom(*mesh);
127 const std::vector< MCAuto<DataArray> >& vars(zeStr->getVars());
128 for(std::vector< MCAuto<DataArray> >::const_iterator it=vars.begin();it!=vars.end();it++)
130 const DataArray *elt(*it);
134 const DataArrayDouble *eltC(dynamic_cast<const DataArrayDouble *>(elt));
137 MCAuto<MEDFileFieldMultiTS> fmts(MEDFileFieldMultiTS::New());
138 MCAuto<MEDFileField1TS> f1ts(MEDFileField1TS::New());
139 MCAuto<MEDCouplingFieldDouble> f(MEDCouplingFieldDouble::New(ON_NODES));
141 f->setArray(const_cast<DataArrayDouble *>(eltC));
142 f->setName(eltC->getName());
143 f1ts->setFieldNoProfileSBT(f);
144 fmts->pushBackTimeStep(f1ts);
145 fsOut->pushField(fmts);
153 * \param [in] fs - fields lying all on same mesh and on same structure element
154 * \param [in] zeStr - ze structure of current structure element
155 * \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
156 * \param [out] zeOutputs - ze fields that are the concatenation of fields in \a fs transformed and those in \a varAtt normalized in time space
158 void MEDFileBlowStrEltUp::dealWithSEInFields(const std::string& seName, const MEDFileFields *fs, const MEDFileEltStruct4Mesh *zeStr, const MEDFileFields *varAtt, MEDFileFields *zeOutputs) const
161 throw INTERP_KERNEL::Exception("MEDFileBlowStrEltUp::dealWithSEInFields : null pointer !");
162 if(seName==MED_BALL_STR)
164 dealWithMEDBALLSInFields(fs,zeStr,varAtt,zeOutputs);
167 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 !");
170 void MEDFileBlowStrEltUp::dealWithMEDBALLSInFields(const MEDFileFields *fs, const MEDFileEltStruct4Mesh *zeStr, const MEDFileFields *varAtt, MEDFileFields *zeOutputs) const
172 int nbf(fs->getNumberOfFields());
173 std::vector< MCAuto<MEDFileAnyTypeFieldMultiTS> > elts0;
174 std::vector< MEDFileAnyTypeFieldMultiTS * > elts1;
175 std::string zeMeshName;
176 for(int i=0;i<nbf;i++)
178 MCAuto<MEDFileAnyTypeFieldMultiTS> elt(fs->getFieldAtPos(i));
179 MCAuto<MEDFileAnyTypeFieldMultiTS> eltOut(elt->buildNewEmpty());
180 int nbTS(elt->getNumberOfTS());
181 for(int j=0;j<nbTS;j++)
183 MCAuto<MEDFileAnyTypeField1TS> eltt(elt->getTimeStepAtPos(j));
184 MCAuto<MEDFileAnyTypeField1TS> elttOut(eltt->deepCopy());
185 std::string meshName(eltt->getMeshName());
186 zeMeshName=BuildNewMeshName(meshName,MED_BALL_STR);
187 elttOut->setMeshName(zeMeshName);
188 elttOut->convertMedBallIntoClassic();
189 eltOut->pushBackTimeStep(elttOut);
191 elts0.push_back(eltOut); elts1.push_back(eltOut);
194 const MEDFileMesh *zeCurrentMesh(_ms->getMeshWithName(zeMeshName));
197 std::vector< std::vector<MEDFileAnyTypeFieldMultiTS *> > sp(MEDFileAnyTypeFieldMultiTS::SplitIntoCommonTimeSeries(elts1));
198 for(std::vector< std::vector<MEDFileAnyTypeFieldMultiTS *> >::const_iterator it0=sp.begin();it0!=sp.end();it0++,ii++)
200 std::vector< MCAuto<MEDFileFastCellSupportComparator> > fsc;
201 std::vector< std::vector<MEDFileAnyTypeFieldMultiTS *> > sp2(MEDFileAnyTypeFieldMultiTS::SplitPerCommonSupport(*it0,zeCurrentMesh,fsc));
203 for(std::vector< std::vector<MEDFileAnyTypeFieldMultiTS *> >::const_iterator it1=sp2.begin();it1!=sp2.end();it1++,jj++)
205 for(std::vector<MEDFileAnyTypeFieldMultiTS *>::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
206 zeOutputs->pushField(*it2);
207 // The most exciting part. Users that put profiles on struct elements part of fields. Reduce var att.
209 throw INTERP_KERNEL::Exception("MEDFileBlowStrEltUp::dealWithMEDBALLSInFields : take a deep breath !");
210 MCAuto<MEDFileAnyTypeField1TS> zeGuideForPfl;// This var is the reference for pfl management.
213 throw INTERP_KERNEL::Exception("MEDFileBlowStrEltUp::dealWithMEDBALLSInFields : take a deep breath 2 !");
214 int pdm((*it1)[0]->getNumberOfTS());
216 throw INTERP_KERNEL::Exception("MEDFileBlowStrEltUp::dealWithMEDBALLSInFields : take a deep breath 3 !");
217 zeGuideForPfl=(*it1)[0]->getTimeStepAtPos(0);
219 if(zeGuideForPfl.isNull())
220 throw INTERP_KERNEL::Exception("MEDFileBlowStrEltUp::dealWithMEDBALLSInFields : take a deep breath 4 !");
221 std::vector<std::string> pfls(zeGuideForPfl->getPflsReallyUsed());
223 throw INTERP_KERNEL::Exception("MEDFileBlowStrEltUp::dealWithMEDBALLSInFields : drink less coffee");
224 MCAuto<DataArrayInt> pflMyLove;
226 pflMyLove.takeRef(zeGuideForPfl->getProfile(pfls[0]));
228 std::vector<double> t2s;
229 std::vector< std::pair<int,int> > t1s((*it1)[0]->getTimeSteps(t2s));
230 std::size_t nbTS3(t2s.size());
231 int nbf2(varAtt->getNumberOfFields());
232 for(int i=0;i<nbf2;i++)
234 MCAuto<MEDFileAnyTypeFieldMultiTS> elt(varAtt->getFieldAtPos(i));
235 int nbTS2(elt->getNumberOfTS());
237 throw INTERP_KERNEL::Exception("MEDFileBlowStrEltUp::dealWithMEDBALLSInFields : internal error ! The dealWithMEDBALLInMesh is expected to return a single TS !");
238 MCAuto<MEDFileAnyTypeField1TS> elt2(elt->getTimeStepAtPos(0));
239 MCAuto<MEDFileAnyTypeFieldMultiTS> elt4(elt->buildNewEmpty());
240 for(std::size_t j=0;j<nbTS3;j++)
242 MCAuto<MEDFileAnyTypeField1TS> elt3(elt2->deepCopy());
243 elt3->setTime(t1s[j].first,t1s[j].second,t2s[j]);
244 elt3->setName(BuildVarAttName(ii,sp.size(),jj,sp2.size(),elt3->getName()));
245 if(pflMyLove.isNotNull())
246 elt3->makeReduction(INTERP_KERNEL::NORM_ERROR,ON_NODES,pflMyLove);
247 elt4->pushBackTimeStep(elt3);
249 zeOutputs->pushField(elt4);
255 void MEDFileBlowStrEltUp::generate(MEDFileMeshes *msOut, MEDFileFields *allZeOutFields)
257 for(std::vector< MCAuto<MEDFileFields> >::iterator elt=_elts.begin();elt!=_elts.end();elt++)
259 std::vector< std::pair<std::string,std::string> > ps;
260 (*elt)->getMeshSENames(ps);
262 throw INTERP_KERNEL::Exception("MEDFileBlowStrEltUp::generateMeshes : internal error !");
263 MEDFileMesh *mesh(_ms->getMeshWithName(ps[0].first));
265 throw INTERP_KERNEL::Exception("MEDFileBlowStrEltUp::generateMeshes : NULL mesh !");
266 MEDFileUMesh *umesh(dynamic_cast<MEDFileUMesh *>(mesh));
268 throw INTERP_KERNEL::Exception("MEDFileBlowStrEltUp::generateMeshes : Blow up of Stru Elt not managed yet for unstructured meshes !");
270 MCAuto<MEDFileFields> classicalSEFields(splitFieldsPerLoc(*elt,umesh,msOut,allZeOutFields));
271 if(classicalSEFields.isNotNull())
273 MCAuto<MEDFileUMesh> mOut;
274 MCAuto<MEDFileFields> fsOut1;
275 MCAuto<MEDFileEltStruct4Mesh> zeStr(dealWithSEInMesh(ps[0].second,umesh,mOut,fsOut1));
276 msOut->pushMesh(mOut);
277 dealWithSEInFields(ps[0].second,classicalSEFields,zeStr,fsOut1,allZeOutFields);
282 std::string MEDFileBlowStrEltUp::BuildNewMeshName(const std::string& meshName, const std::string& seName)
284 std::ostringstream mNameOut;
285 mNameOut << meshName << "_" << seName;
286 return mNameOut.str();
289 std::string MEDFileBlowStrEltUp::BuildVarAttName(std::size_t iPart, std::size_t totINbParts, std::size_t jPart, std::size_t totJNbParts, const std::string& name)
291 if(totINbParts==1 && totJNbParts==1)
293 std::ostringstream oss;
294 oss << name << "@" << iPart << "@" << jPart;
298 void MEDFileBlowStrEltUp::DealWithSE(MEDFileFields *fs, MEDFileMeshes *ms, const MEDFileStructureElements *ses)
300 MCAuto<MEDFileFields> fsSEOnly(fs->partOfThisOnStructureElements());
301 fs->killStructureElements();
302 MEDFileBlowStrEltUp bu(fsSEOnly,ms,ses);
304 fs->killStructureElementsInGlobs();
312 FieldWalker2(const MEDFileFieldPerMeshPerTypePerDisc *pmptpd);
313 std::string getLoc() const { return _loc; }
314 std::string getPfl() const { return _pfl; }
315 bool isClassic() const { return _is_classic; }
316 bool operator!=(const FieldWalker2& other) const;
317 bool operator==(const FieldWalker2& other) const;
328 LocInfo(const std::vector<FieldWalker2>& fw);
329 bool operator==(const LocInfo& other) const { return _locs==other._locs && _pfl==other._pfl; }
330 void push(const std::string& loc, const std::string& pfl) { checkUniqueLoc(loc); _locs.push_back(loc); _pfl.push_back(pfl); }
331 MCAuto<MEDFileUMesh> generateNonClassicalData(int zePos, const MEDFileUMesh *mesh, const MEDFileFieldGlobsReal *globs) const;
333 void checkUniqueLoc(const std::string& loc) const;
334 static MCAuto<DataArrayDouble> 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);
335 static MCAuto<DataArrayDouble> BuildMeshFromStructure(INTERP_KERNEL::NormalizedCellType gt, const std::string& pfl, const MEDFileFieldLoc& loc, const MEDFileEltStruct4Mesh *zeStr, const MEDFileUMesh *mesh, const MEDFileUMesh *section, const MEDFileFieldGlobsReal *globs);
337 static const char ANGLE_DE_VRILLE[];
339 std::vector<std::string> _locs;
340 std::vector<std::string> _pfl;
343 const char LocInfo::ANGLE_DE_VRILLE[]="ANGLE DE VRILLE";
345 LocInfo::LocInfo(const std::vector<FieldWalker2>& fw)
347 std::size_t sz(fw.size());
348 _locs.resize(sz); _pfl.resize(sz);
349 for(std::size_t i=0;i<sz;i++)
351 _locs[i]=fw[i].getLoc();
352 _pfl[i]=fw[i].getPfl();
356 void LocInfo::checkUniqueLoc(const std::string& loc) const
358 if(std::find(_locs.begin(),_locs.end(),loc)!=_locs.end())
360 std::ostringstream oss; oss << "LocInfo::checkUniqueLoc : loc \"" << loc << "\" already exists !";
361 throw INTERP_KERNEL::Exception(oss.str());
365 MCAuto<DataArrayDouble> 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)
367 MCAuto<DataArrayInt> conn(zeStr->getConn());
368 conn=conn->deepCopy(); conn->rearrange(1);
369 MCAuto<MEDCouplingUMesh> geoMesh;
371 MCAuto<MEDCoupling1SGTUMesh> umesh(MEDCoupling1SGTUMesh::New("",gt));
372 umesh->setCoords(mesh->getCoords());
373 umesh->setNodalConnectivity(conn);
374 geoMesh=umesh->buildUnstructured();
377 MCConstAuto<DataArrayDouble> angleVrille;
380 const DataArrayInt *pflArr(globs->getProfile(pfl));
381 geoMesh=geoMesh->buildPartOfMySelf(pflArr->begin(),pflArr->end(),true);
382 angleVrille=angleDeVrille->selectByTupleIdSafe(pflArr->begin(),pflArr->end());
385 angleVrille.takeRef(angleDeVrille);
387 MCAuto<MEDCouplingFieldDouble> fakeF(MEDCouplingFieldDouble::New(ON_GAUSS_PT));
388 fakeF->setMesh(geoMesh);
389 int nbg(loc.getGaussWeights().size());
390 fakeF->setGaussLocalizationOnType(gt,loc.getRefCoords(),loc.getGaussCoords(),loc.getGaussWeights());
391 MCAuto<DataArrayDouble> ptsForLoc(fakeF->getLocalizationOfDiscr());
393 MCAuto<MEDCouplingFieldDouble> dir(geoMesh->buildDirectionVectorField());
394 MCAuto<DataArrayDouble> rot(dir->getArray()->fromCartToSpher());
395 int nbCells(geoMesh->getNumberOfCells()),nbCompo(ptsForLoc->getNumberOfComponents());
396 MCAuto<DataArrayDouble> secPts(section->getCoords()->changeNbOfComponents(nbCompo,0.));
397 int nbSecPts(secPts->getNumberOfTuples());
399 const int TAB[3]={2,0,1};
400 std::vector<int> v(TAB,TAB+3);
401 secPts=secPts->keepSelectedComponents(v);
403 const double CENTER[3]={0.,0.,0.},AX0[3]={0.,0.,1.};
404 double AX1[3]; AX1[2]=0.;
405 std::vector< MCAuto<DataArrayDouble> > arrs(nbCells*nbg);
406 for(int j=0;j<nbCells;j++)
408 MCAuto<DataArrayDouble> p(secPts->deepCopy());
409 double ang0(rot->getIJ(j,2));
410 DataArrayDouble::Rotate3DAlg(CENTER,AX0,ang0,nbSecPts,p->begin(),p->getPointer());
411 AX1[0]=-sin(ang0); AX1[1]=cos(ang0);// rot Oy around OZ
412 double ang1(M_PI/2.-rot->getIJ(j,1));
413 DataArrayDouble::Rotate3DAlg(CENTER,AX1,-ang1,nbSecPts,p->begin(),p->getPointer());
414 DataArrayDouble::Rotate3DAlg(CENTER,dir->getArray()->begin()+j*3,angleVrille->getIJ(j,0),nbSecPts,p->begin(),p->getPointer());
415 for(int l=0;l<nbg;l++)
417 MCAuto<DataArrayDouble> p2(p->deepCopy());
418 for(int k=0;k<nbCompo;k++)
419 p2->applyLin(1.,ptsForLoc->getIJ(j*nbg+l,k),k);
423 std::vector<const DataArrayDouble *> arrs2(VecAutoToVecOfCstPt(arrs));
424 MCAuto<DataArrayDouble> resu(DataArrayDouble::Aggregate(arrs2));
428 MCAuto<DataArrayDouble> 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)
430 static const char MSG1[]="BuildMeshFromStructure : not recognized pattern ! Send mail to anthony.geay@edf.fr with corresponding MED file !";
431 const std::vector< MCAuto<DataArray> >& vars(zeStr->getVars());
433 throw INTERP_KERNEL::Exception(MSG1);
434 MCAuto<DataArray> zeArr(vars[0]);
436 throw INTERP_KERNEL::Exception(MSG1);
437 MCAuto<DataArrayDouble> zeArr2(DynamicCast<DataArray,DataArrayDouble>(zeArr));
439 throw INTERP_KERNEL::Exception(MSG1);
440 if(zeArr2->getName()!=ANGLE_DE_VRILLE)
441 throw INTERP_KERNEL::Exception(MSG1);
442 return BuildMeshFromAngleVrille(gt,zeArr2,pfl,loc,zeStr,mesh,section,globs);
445 MCAuto<MEDFileUMesh> LocInfo::generateNonClassicalData(int zePos, const MEDFileUMesh *mesh, const MEDFileFieldGlobsReal *globs) const
447 static const char MSG1[]="LocInfo::generateNonClassicalData : no spec for GAUSS on StructureElement with more than one cell !";
448 std::size_t sz(_locs.size());
449 std::vector< MCAuto<DataArrayDouble> > arrs(sz);
450 for(std::size_t i=0;i<sz;i++)
452 const MEDFileFieldLoc& loc(globs->getLocalization(_locs[i]));
453 const MEDFileGTKeeper *gtk(loc.getUndergroundGTKeeper());
454 const MEDFileGTKeeperDyn *gtk2(dynamic_cast<const MEDFileGTKeeperDyn *>(gtk));
456 throw INTERP_KERNEL::Exception("LocInfo::generateNonClassicalData : internal error !");
457 const MEDFileUMesh *meshLoc(gtk2->getMesh()),*section(gtk2->getSection());
458 const MEDFileStructureElement *se(gtk2->getSE());
459 INTERP_KERNEL::NormalizedCellType gt;
461 std::vector<int> nel(meshLoc->getNonEmptyLevels());
463 throw INTERP_KERNEL::Exception(MSG1);
465 throw INTERP_KERNEL::Exception(MSG1);
466 MCAuto<MEDCouplingUMesh> um(meshLoc->getMeshAtLevel(0));
467 if(um->getNumberOfCells()!=1)
468 throw INTERP_KERNEL::Exception(MSG1);
469 gt=um->getTypeOfCell(0);
471 um->getNodeIdsOfCell(0,v);
472 std::size_t sz2(v.size());
473 for(std::size_t j=0;j<sz2;j++)
475 throw INTERP_KERNEL::Exception(MSG1);
477 const std::vector< MCAuto<MEDFileEltStruct4Mesh> >& strs(mesh->getAccessOfUndergroundEltStrs());
478 MCAuto<MEDFileEltStruct4Mesh> zeStr;
479 for(std::vector< MCAuto<MEDFileEltStruct4Mesh> >::const_iterator it=strs.begin();it!=strs.end();it++)
481 if((*it)->getGeoTypeName()==se->getName())
489 std::ostringstream oss; oss << "LocInfo::generateNonClassicalData : : no geo type with name " << se->getName() << " in " << mesh->getName() << " !";
490 throw INTERP_KERNEL::Exception(oss.str());
492 arrs[i]=BuildMeshFromStructure(gt,_pfl[i],loc,zeStr,mesh,section,globs);
494 std::vector<const DataArrayDouble *> arrs2(VecAutoToVecOfCstPt(arrs));
495 MCAuto<DataArrayDouble> resu(DataArrayDouble::Aggregate(arrs2));
496 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
497 ret->setCoords(resu);
498 std::ostringstream meshName; meshName << mesh->getName() << "_on_" << sz << "_sections" << "_" << zePos;
499 ret->setName(meshName.str());
503 FieldWalker2::FieldWalker2(const MEDFileFieldPerMeshPerTypePerDisc *pmptpd)
505 _loc=pmptpd->getLocalization();
506 _pfl=pmptpd->getProfile();
507 _is_classic=pmptpd->getType()!=ON_GAUSS_PT;
510 bool FieldWalker2::operator!=(const FieldWalker2& other) const
512 bool ret(_loc==other._loc && _pfl==other._pfl && _is_classic==other._is_classic);
516 bool FieldWalker2::operator==(const FieldWalker2& other) const
518 bool ret(_loc==other._loc && _pfl==other._pfl && _is_classic==other._is_classic);
525 FieldWalker1(const MEDFileAnyTypeField1TSWithoutSDA *ts):_ts(ts),_pm_pt(0),_nb_mesh(0) { }
526 void newMeshEntry(const MEDFileFieldPerMesh *fpm);
527 void endMeshEntry(const MEDFileFieldPerMesh *fpm) { }
528 void newPerMeshPerTypeEntry(const MEDFileFieldPerMeshPerTypeCommon *pmpt);
529 void endPerMeshPerTypeEntry(const MEDFileFieldPerMeshPerTypeCommon *pmpt);
530 void newPerMeshPerTypePerDisc(const MEDFileFieldPerMeshPerTypePerDisc *pmptpd);
531 void checkOK(const FieldWalker1& other) const;
532 bool isClassical() const;
533 std::vector<FieldWalker2> getNonClassicalData() const { return _fw; }
535 const MEDFileAnyTypeField1TSWithoutSDA *_ts;
536 const MEDFileFieldPerMeshPerTypeDyn *_pm_pt;
537 std::vector<FieldWalker2> _fw;
541 void FieldWalker1::newMeshEntry(const MEDFileFieldPerMesh *fpm)
544 throw INTERP_KERNEL::Exception("FieldWalker1::newMeshEntry : multi mesh not supported !");
547 void FieldWalker1::newPerMeshPerTypeEntry(const MEDFileFieldPerMeshPerTypeCommon *pmpt)
550 throw INTERP_KERNEL::Exception("FieldWalker1::newPerMeshPerTypeEntry : multi SE loc not managed yet !");
551 const MEDFileFieldPerMeshPerTypeDyn *pmpt2(dynamic_cast<const MEDFileFieldPerMeshPerTypeDyn *>(pmpt));
553 throw INTERP_KERNEL::Exception("newPerMeshPerTypeEntry : internal error !");
557 void FieldWalker1::endPerMeshPerTypeEntry(const MEDFileFieldPerMeshPerTypeCommon *)
562 void FieldWalker1::newPerMeshPerTypePerDisc(const MEDFileFieldPerMeshPerTypePerDisc *pmptpd)
564 _fw.push_back(FieldWalker2(pmptpd));
567 void FieldWalker1::checkOK(const FieldWalker1& other) const
569 std::size_t sz(_fw.size());
570 if(other._fw.size()!=sz)
571 throw INTERP_KERNEL::Exception("checkOK : not OK because size are not the same !");
572 for(std::size_t i=0;i<sz;i++)
573 if(_fw[i]!=other._fw[i])
574 throw INTERP_KERNEL::Exception("checkOK : not OK because an element mismatches !");
577 bool FieldWalker1::isClassical() const
580 throw INTERP_KERNEL::Exception("FieldWalker1::endPerMeshPerTypeEntry : internal error !");
581 std::size_t ic(0),inc(0);
582 for(std::vector<FieldWalker2>::const_iterator it=_fw.begin();it!=_fw.end();it++)
584 if((*it).isClassic())
590 throw INTERP_KERNEL::Exception("FieldWalker1::endPerMeshPerTypeEntry : mix is not allowed yet !");
597 FieldWalker(const MEDFileAnyTypeFieldMultiTSWithoutSDA *f):_f(f) { }
598 void newTimeStepEntry(const MEDFileAnyTypeField1TSWithoutSDA *ts);
599 void endTimeStepEntry(const MEDFileAnyTypeField1TSWithoutSDA *ts);
600 void newMeshEntry(const MEDFileFieldPerMesh *fpm);
601 void endMeshEntry(const MEDFileFieldPerMesh *fpm);
602 void newPerMeshPerTypeEntry(const MEDFileFieldPerMeshPerTypeCommon *pmpt);
603 void endPerMeshPerTypeEntry(const MEDFileFieldPerMeshPerTypeCommon *pmpt);
604 void newPerMeshPerTypePerDisc(const MEDFileFieldPerMeshPerTypePerDisc *pmptpd);
606 bool isEmpty() const;
607 bool isClassical() const;
608 const MEDFileAnyTypeFieldMultiTSWithoutSDA *field() const { return _f; }
609 std::vector<FieldWalker2> getNonClassicalData() const { return _fw_prev->getNonClassicalData(); }
611 const MEDFileAnyTypeFieldMultiTSWithoutSDA *_f;
612 mutable INTERP_KERNEL::AutoCppPtr<FieldWalker1> _fw;
613 mutable INTERP_KERNEL::AutoCppPtr<FieldWalker1> _fw_prev;
616 bool FieldWalker::isEmpty() const
618 return _fw_prev.isNull();
621 bool FieldWalker::isClassical() const
623 return _fw_prev->isClassical();
626 void FieldWalker::newTimeStepEntry(const MEDFileAnyTypeField1TSWithoutSDA *ts)
628 _fw=new FieldWalker1(ts);
631 void FieldWalker::endTimeStepEntry(const MEDFileAnyTypeField1TSWithoutSDA *ts)
633 if(_fw_prev.isNull())
634 _fw_prev=new FieldWalker1(*_fw);
636 _fw_prev->checkOK(*_fw);
640 void FieldWalker::newMeshEntry(const MEDFileFieldPerMesh *fpm)
642 _fw->newMeshEntry(fpm);
645 void FieldWalker::endMeshEntry(const MEDFileFieldPerMesh *fpm)
647 _fw->endMeshEntry(fpm);
650 void FieldWalker::newPerMeshPerTypeEntry(const MEDFileFieldPerMeshPerTypeCommon *pmpt)
652 _fw->newPerMeshPerTypeEntry(pmpt);
655 void FieldWalker::endPerMeshPerTypeEntry(const MEDFileFieldPerMeshPerTypeCommon *pmpt)
657 _fw->endPerMeshPerTypeEntry(pmpt);
660 void FieldWalker::newPerMeshPerTypePerDisc(const MEDFileFieldPerMeshPerTypePerDisc *pmptpd)
662 _fw->newPerMeshPerTypePerDisc(pmptpd);
665 // this class splits fields into same
666 class LocSpliter : public MEDFileFieldVisitor
669 LocSpliter(const MEDFileFieldGlobsReal *globs):_globs(globs),_fw(0) { }
670 MCAuto<MEDFileFields> getClassical() const { return _classical; }
671 void generateNonClassicalData(const MEDFileUMesh *mesh, std::vector< MCAuto<MEDFileFields> >& outFields, std::vector< MCAuto<MEDFileUMesh> >& outMeshes) const;
673 void newFieldEntry(const MEDFileAnyTypeFieldMultiTSWithoutSDA *field);
674 void endFieldEntry(const MEDFileAnyTypeFieldMultiTSWithoutSDA *field);
676 void newTimeStepEntry(const MEDFileAnyTypeField1TSWithoutSDA *ts);
677 void endTimeStepEntry(const MEDFileAnyTypeField1TSWithoutSDA *ts);
679 void newMeshEntry(const MEDFileFieldPerMesh *fpm);
680 void endMeshEntry(const MEDFileFieldPerMesh *fpm);
682 void newPerMeshPerTypeEntry(const MEDFileFieldPerMeshPerTypeCommon *pmpt);
683 void endPerMeshPerTypeEntry(const MEDFileFieldPerMeshPerTypeCommon *pmpt);
685 void newPerMeshPerTypePerDisc(const MEDFileFieldPerMeshPerTypePerDisc *pmptpd);
687 const MEDFileFieldGlobsReal *_globs;
688 std::vector< LocInfo > _locs;
689 std::vector< MCAuto<MEDFileFields> > _fields_on_locs;//size of _locs== size of _fields_on_locs
690 MCAuto<MEDFileFields> _classical;
692 mutable INTERP_KERNEL::AutoCppPtr<FieldWalker> _fw;
695 void LocSpliter::newFieldEntry(const MEDFileAnyTypeFieldMultiTSWithoutSDA *field)
697 _fw=new FieldWalker(field);
700 void LocSpliter::endFieldEntry(const MEDFileAnyTypeFieldMultiTSWithoutSDA *field)
704 MCAuto<MEDFileAnyTypeFieldMultiTS> f(MEDFileAnyTypeFieldMultiTS::BuildNewInstanceFromContent(const_cast<MEDFileAnyTypeFieldMultiTSWithoutSDA *>(field)));
705 if(_fw->isClassical())
707 if(_classical.isNull())
709 _classical=MEDFileFields::New();
710 _classical->shallowCpyGlobs(*_globs);
712 _classical->pushField(f);
716 std::vector<FieldWalker2> fw2(_fw->getNonClassicalData());
718 std::vector< LocInfo >::iterator it(std::find(_locs.begin(),_locs.end(),elt));
721 _locs.push_back(elt);
722 MCAuto<MEDFileFields> zeF(MEDFileFields::New());
723 zeF->shallowCpyGlobs(*_globs);
725 _fields_on_locs.push_back(zeF);
729 MCAuto<MEDFileFields> zeF(_fields_on_locs[std::distance(_locs.begin(),it)]);
735 void LocSpliter::generateNonClassicalData(const MEDFileUMesh *mesh, std::vector< MCAuto<MEDFileFields> >& outFields, std::vector< MCAuto<MEDFileUMesh> >& outMeshes) const
738 for(std::vector<LocInfo>::const_iterator it=_locs.begin();it!=_locs.end();it++,i++)
740 MCAuto<MEDFileUMesh> m((*it).generateNonClassicalData(i,mesh,_globs));
741 outMeshes.push_back(m);
742 MCAuto<MEDCouplingUMesh> mcm(MEDCouplingUMesh::Build0DMeshFromCoords(m->getCoords()));
743 mcm->setName(m->getName());
744 MCAuto<MEDFileFields> fs(_fields_on_locs[i]);
745 MCAuto<MEDFileFields> outFs(MEDFileFields::New());
746 for(int j=0;j<fs->getNumberOfFields();j++)
748 MCAuto<MEDFileAnyTypeFieldMultiTS> fmtsNC(fs->getFieldAtPos(j));
749 MCAuto<MEDFileFieldMultiTS> fmts(DynamicCastSafe<MEDFileAnyTypeFieldMultiTS,MEDFileFieldMultiTS>(fmtsNC));
750 MCAuto<MEDFileFieldMultiTS> outFmts(MEDFileFieldMultiTS::New());
751 for(int k=0;k<fmts->getNumberOfTS();k++)
753 MCAuto<MEDFileField1TS> outF1t(MEDFileField1TS::New());
754 MCAuto<MEDFileField1TS> f1ts(fmts->getTimeStepAtPos(k));
756 double t1(f1ts->getTime(t2,t3));
757 MCAuto<MEDCouplingFieldDouble> mcf(MEDCouplingFieldDouble::New(ON_NODES));
758 mcf->setArray(f1ts->getUndergroundDataArray());
759 mcf->setTime(t1,t2,t3);
760 mcf->setName(f1ts->getName());
762 outF1t->setFieldNoProfileSBT(mcf);
763 outFmts->pushBackTimeStep(outF1t);
765 outFs->pushField(outFmts);
767 outFields.push_back(outFs);
771 void LocSpliter::newTimeStepEntry(const MEDFileAnyTypeField1TSWithoutSDA *ts)
773 _fw->newTimeStepEntry(ts);
776 void LocSpliter::endTimeStepEntry(const MEDFileAnyTypeField1TSWithoutSDA *ts)
778 _fw->endTimeStepEntry(ts);
781 void LocSpliter::newMeshEntry(const MEDFileFieldPerMesh *fpm)
783 _fw->newMeshEntry(fpm);
786 void LocSpliter::endMeshEntry(const MEDFileFieldPerMesh *fpm)
788 _fw->endMeshEntry(fpm);
791 void LocSpliter::newPerMeshPerTypeEntry(const MEDFileFieldPerMeshPerTypeCommon *pmpt)
793 _fw->newPerMeshPerTypeEntry(pmpt);
796 void LocSpliter::endPerMeshPerTypeEntry(const MEDFileFieldPerMeshPerTypeCommon *pmpt)
798 _fw->endPerMeshPerTypeEntry(pmpt);
801 void LocSpliter::newPerMeshPerTypePerDisc(const MEDFileFieldPerMeshPerTypePerDisc *pmptpd)
803 _fw->newPerMeshPerTypePerDisc(pmptpd);
806 MCAuto<MEDFileFields> MEDFileBlowStrEltUp::splitFieldsPerLoc(const MEDFileFields *fields, const MEDFileUMesh *mesh, MEDFileMeshes *msOut, MEDFileFields *allZeOutFields)
808 LocSpliter ls(fields);
810 std::vector< MCAuto<MEDFileFields> > outFields;
811 std::vector< MCAuto<MEDFileUMesh> > outMeshes;
812 ls.generateNonClassicalData(mesh,outFields,outMeshes);
813 for(std::vector< MCAuto<MEDFileFields> >::iterator it=outFields.begin();it!=outFields.end();it++)
815 for(int j=0;j<(*it)->getNumberOfFields();j++)
817 MCAuto<MEDFileAnyTypeFieldMultiTS> fmts((*it)->getFieldAtPos(j));
818 allZeOutFields->pushField(fmts);
821 for(std::vector< MCAuto<MEDFileUMesh> >::iterator it=outMeshes.begin();it!=outMeshes.end();it++)
822 msOut->pushMesh(*it);
823 return ls.getClassical();