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"
24 using namespace MEDCoupling;
26 const char MEDFileBlowStrEltUp::MED_BALL_STR[]="MED_BALL";
28 MEDFileBlowStrEltUp::MEDFileBlowStrEltUp(const MEDFileFields *fsOnlyOnSE, const MEDFileMeshes *ms, const MEDFileStructureElements *ses)
30 if(!fsOnlyOnSE || !ms || !ses)
31 throw INTERP_KERNEL::Exception("MEDFileBlowStrEltUp constructor : NULL input pointer !");
32 _ms.takeRef(ms); _ses.takeRef(ses);
33 std::vector< std::pair<std::string,std::string> > ps;
34 fsOnlyOnSE->getMeshSENames(ps);
35 std::size_t sz(ps.size());
37 for(std::size_t i=0;i<sz;i++)
39 const std::pair<std::string,std::string>& p(ps[i]);
40 MCAuto<MEDFileFields> f(fsOnlyOnSE->partOfThisLyingOnSpecifiedMeshSEName(p.first,p.second));
43 for(std::size_t i=0;i<sz;i++)
45 const std::pair<std::string,std::string>& p(ps[i]);
46 MEDFileMesh *mesh(_ms->getMeshWithName(p.first));
48 throw INTERP_KERNEL::Exception("MEDFileBlowStrEltUp : NULL mesh !");
49 MEDFileUMesh *umesh(dynamic_cast<MEDFileUMesh *>(mesh));
51 throw INTERP_KERNEL::Exception("MEDFileBlowStrEltUp : Blow up of Stru Elt not managed yet for unstructured meshes !");
56 * \param [in] mesh - The mesh containing structure element called \a seName. After the call of this method the Structure elements parts will be removed.
57 * \param [out] mOut - the physical mesh of the structure element \a seName in mesh \a mesh
58 * \param [out] fsOut - the list of var attribute of structure element \a seName - \b WARNING no time steps here
60 MCAuto<MEDFileEltStruct4Mesh> MEDFileBlowStrEltUp::dealWithSEInMesh(const std::string& seName, MEDFileUMesh *mesh, MCAuto<MEDFileUMesh>& mOut, MCAuto<MEDFileFields>& fsOut) const
63 throw INTERP_KERNEL::Exception("MEDFileBlowStrEltUp::dealWithSEInMesh : null pointer !");
64 if(seName==MED_BALL_STR)
66 MCAuto<MEDFileEltStruct4Mesh> ret(dealWithMEDBALLInMesh(mesh,mOut,fsOut));
67 mesh->killStructureElements();
70 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 !");
73 MCAuto<MEDFileEltStruct4Mesh> MEDFileBlowStrEltUp::dealWithMEDBALLInMesh(const MEDFileUMesh *mesh, MCAuto<MEDFileUMesh>& mOut, MCAuto<MEDFileFields>& fsOut) const
75 mOut=MEDFileUMesh::New(); fsOut=MEDFileFields::New();
76 const std::vector< MCAuto<MEDFileEltStruct4Mesh> >& strs(mesh->getAccessOfUndergroundEltStrs());
77 MCAuto<MEDFileEltStruct4Mesh> zeStr;
78 for(std::vector< MCAuto<MEDFileEltStruct4Mesh> >::const_iterator it=strs.begin();it!=strs.end();it++)
80 if((*it)->getGeoTypeName()==MED_BALL_STR)
88 std::ostringstream oss; oss << "MEDFileBlowStrEltUp::dealWithMEDBALLInMesh : no geo type with name " << MED_BALL_STR << " in " << mesh->getName() << " !";
89 throw INTERP_KERNEL::Exception(oss.str());
91 const DataArrayDouble *coo(mesh->getCoords());
93 throw INTERP_KERNEL::Exception("MEDFileBlowStrEltUp::dealWithMEDBALLInMesh : null coords !");
94 MCAuto<DataArrayInt> conn(zeStr->getConn());
96 throw INTERP_KERNEL::Exception("MEDFileBlowStrEltUp::dealWithMEDBALLInMesh : null connectivity !");
97 conn->checkAllocated();
98 if(conn->getNumberOfComponents()!=1)
99 throw INTERP_KERNEL::Exception("MEDFileBlowStrEltUp::dealWithMEDBALLInMesh : excepted to be single compo !");
100 int nbCells(conn->getNumberOfTuples());
101 MCAuto<DataArrayDouble> connOut(coo->selectByTupleIdSafe(conn->begin(),conn->end()));
102 MCAuto<MEDCouplingUMesh> mcOut(MEDCouplingUMesh::Build0DMeshFromCoords(connOut));
103 mcOut->setName(BuildNewMeshName(mesh->getName(),MED_BALL_STR));
104 mOut->setMeshAtLevel(0,mcOut);
105 const DataArrayInt *ff1(mesh->getFamilyFieldAtLevel(1));
108 MCAuto<DataArrayInt> ff1o(ff1->selectByTupleIdSafe(conn->begin(),conn->end()));
109 mOut->setFamilyFieldArr(1,ff1o);
111 const DataArrayInt *nf1(mesh->getNumberFieldAtLevel(1));
114 MCAuto<DataArrayInt> nf1o(nf1->selectByTupleIdSafe(conn->begin(),conn->end()));
115 mOut->setRenumFieldArr(1,nf1o);
117 MCAuto<MEDFileUMeshPerTypeCommon> md(zeStr->getMeshDef());
118 const DataArrayInt *ff0(md->getFam());
120 mOut->setFamilyFieldArr(0,const_cast<DataArrayInt *>(ff0));
121 const DataArrayInt *nf0(md->getNum());
123 mOut->setRenumFieldArr(0,const_cast<DataArrayInt *>(nf0));
124 mOut->copyFamGrpMapsFrom(*mesh);
125 const std::vector< MCAuto<DataArray> >& vars(zeStr->getVars());
126 for(std::vector< MCAuto<DataArray> >::const_iterator it=vars.begin();it!=vars.end();it++)
128 const DataArray *elt(*it);
132 const DataArrayDouble *eltC(dynamic_cast<const DataArrayDouble *>(elt));
135 MCAuto<MEDFileFieldMultiTS> fmts(MEDFileFieldMultiTS::New());
136 MCAuto<MEDFileField1TS> f1ts(MEDFileField1TS::New());
137 MCAuto<MEDCouplingFieldDouble> f(MEDCouplingFieldDouble::New(ON_NODES));
139 f->setArray(const_cast<DataArrayDouble *>(eltC));
140 f->setName(eltC->getName());
141 f1ts->setFieldNoProfileSBT(f);
142 fmts->pushBackTimeStep(f1ts);
143 fsOut->pushField(fmts);
151 * \param [in] fs - fields lying all on same mesh and on same structure element
152 * \param [in] zeStr - ze structure of current structure element
153 * \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
154 * \param [out] zeOutputs - ze fields that are the concatenation of fields in \a fs transformed and those in \a varAtt normalized in time space
156 void MEDFileBlowStrEltUp::dealWithSEInFields(const std::string& seName, const MEDFileFields *fs, const MEDFileEltStruct4Mesh *zeStr, const MEDFileFields *varAtt, MEDFileFields *zeOutputs) const
159 throw INTERP_KERNEL::Exception("MEDFileBlowStrEltUp::dealWithSEInFields : null pointer !");
160 if(seName==MED_BALL_STR)
162 dealWithMEDBALLSInFields(fs,zeStr,varAtt,zeOutputs);
165 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 !");
168 void MEDFileBlowStrEltUp::dealWithMEDBALLSInFields(const MEDFileFields *fs, const MEDFileEltStruct4Mesh *zeStr, const MEDFileFields *varAtt, MEDFileFields *zeOutputs) const
170 int nbf(fs->getNumberOfFields());
171 std::vector< MCAuto<MEDFileAnyTypeFieldMultiTS> > elts0;
172 std::vector< MEDFileAnyTypeFieldMultiTS * > elts1;
173 std::string zeMeshName;
174 for(int i=0;i<nbf;i++)
176 MCAuto<MEDFileAnyTypeFieldMultiTS> elt(fs->getFieldAtPos(i));
177 MCAuto<MEDFileAnyTypeFieldMultiTS> eltOut(elt->buildNewEmpty());
178 int nbTS(elt->getNumberOfTS());
179 for(int j=0;j<nbTS;j++)
181 MCAuto<MEDFileAnyTypeField1TS> eltt(elt->getTimeStepAtPos(j));
182 MCAuto<MEDFileAnyTypeField1TS> elttOut(eltt->deepCopy());
183 std::string meshName(eltt->getMeshName());
184 zeMeshName=BuildNewMeshName(meshName,MED_BALL_STR);
185 elttOut->setMeshName(zeMeshName);
186 elttOut->convertMedBallIntoClassic();
187 eltOut->pushBackTimeStep(elttOut);
189 elts0.push_back(eltOut); elts1.push_back(eltOut);
192 const MEDFileMesh *zeCurrentMesh(_ms->getMeshWithName(zeMeshName));
195 std::vector< std::vector<MEDFileAnyTypeFieldMultiTS *> > sp(MEDFileAnyTypeFieldMultiTS::SplitIntoCommonTimeSeries(elts1));
196 for(std::vector< std::vector<MEDFileAnyTypeFieldMultiTS *> >::const_iterator it0=sp.begin();it0!=sp.end();it0++,ii++)
198 std::vector< MCAuto<MEDFileFastCellSupportComparator> > fsc;
199 std::vector< std::vector<MEDFileAnyTypeFieldMultiTS *> > sp2(MEDFileAnyTypeFieldMultiTS::SplitPerCommonSupport(*it0,zeCurrentMesh,fsc));
201 for(std::vector< std::vector<MEDFileAnyTypeFieldMultiTS *> >::const_iterator it1=sp2.begin();it1!=sp2.end();it1++,jj++)
203 for(std::vector<MEDFileAnyTypeFieldMultiTS *>::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
204 zeOutputs->pushField(*it2);
205 // The most exciting part. Users that put profiles on struct elements part of fields. Reduce var att.
207 throw INTERP_KERNEL::Exception("MEDFileBlowStrEltUp::dealWithMEDBALLSInFields : take a deep breath !");
208 MCAuto<MEDFileAnyTypeField1TS> zeGuideForPfl;// This var is the reference for pfl management.
211 throw INTERP_KERNEL::Exception("MEDFileBlowStrEltUp::dealWithMEDBALLSInFields : take a deep breath 2 !");
212 int pdm((*it1)[0]->getNumberOfTS());
214 throw INTERP_KERNEL::Exception("MEDFileBlowStrEltUp::dealWithMEDBALLSInFields : take a deep breath 3 !");
215 zeGuideForPfl=(*it1)[0]->getTimeStepAtPos(0);
217 if(zeGuideForPfl.isNull())
218 throw INTERP_KERNEL::Exception("MEDFileBlowStrEltUp::dealWithMEDBALLSInFields : take a deep breath 4 !");
219 std::vector<std::string> pfls(zeGuideForPfl->getPflsReallyUsed());
221 throw INTERP_KERNEL::Exception("MEDFileBlowStrEltUp::dealWithMEDBALLSInFields : drink less coffee");
222 MCAuto<DataArrayInt> pflMyLove;
224 pflMyLove.takeRef(zeGuideForPfl->getProfile(pfls[0]));
226 std::vector<double> t2s;
227 std::vector< std::pair<int,int> > t1s((*it1)[0]->getTimeSteps(t2s));
228 std::size_t nbTS3(t2s.size());
229 int nbf2(varAtt->getNumberOfFields());
230 for(int i=0;i<nbf2;i++)
232 MCAuto<MEDFileAnyTypeFieldMultiTS> elt(varAtt->getFieldAtPos(i));
233 int nbTS2(elt->getNumberOfTS());
235 throw INTERP_KERNEL::Exception("MEDFileBlowStrEltUp::dealWithMEDBALLSInFields : internal error ! The dealWithMEDBALLInMesh is expected to return a single TS !");
236 MCAuto<MEDFileAnyTypeField1TS> elt2(elt->getTimeStepAtPos(0));
237 MCAuto<MEDFileAnyTypeFieldMultiTS> elt4(elt->buildNewEmpty());
238 for(std::size_t j=0;j<nbTS3;j++)
240 MCAuto<MEDFileAnyTypeField1TS> elt3(elt2->deepCopy());
241 elt3->setTime(t1s[j].first,t1s[j].second,t2s[j]);
242 elt3->setName(BuildVarAttName(ii,sp.size(),jj,sp2.size(),elt3->getName()));
243 if(pflMyLove.isNotNull())
244 elt3->makeReduction(INTERP_KERNEL::NORM_ERROR,ON_NODES,pflMyLove);
245 elt4->pushBackTimeStep(elt3);
247 zeOutputs->pushField(elt4);
253 void MEDFileBlowStrEltUp::generate(MEDFileMeshes *msOut, MEDFileFields *allZeOutFields)
255 for(std::vector< MCAuto<MEDFileFields> >::iterator elt=_elts.begin();elt!=_elts.end();elt++)
257 std::vector< std::pair<std::string,std::string> > ps;
258 (*elt)->getMeshSENames(ps);
260 throw INTERP_KERNEL::Exception("MEDFileBlowStrEltUp::generateMeshes : internal error !");
261 MEDFileMesh *mesh(_ms->getMeshWithName(ps[0].first));
263 throw INTERP_KERNEL::Exception("MEDFileBlowStrEltUp::generateMeshes : NULL mesh !");
264 MEDFileUMesh *umesh(dynamic_cast<MEDFileUMesh *>(mesh));
266 throw INTERP_KERNEL::Exception("MEDFileBlowStrEltUp::generateMeshes : Blow up of Stru Elt not managed yet for unstructured meshes !");
267 MCAuto<MEDFileUMesh> mOut;
268 MCAuto<MEDFileFields> fsOut1;
269 MCAuto<MEDFileEltStruct4Mesh> zeStr(dealWithSEInMesh(ps[0].second,umesh,mOut,fsOut1));
270 msOut->pushMesh(mOut);
271 dealWithSEInFields(ps[0].second,*elt,zeStr,fsOut1,allZeOutFields);
275 std::string MEDFileBlowStrEltUp::BuildNewMeshName(const std::string& meshName, const std::string& seName)
277 std::ostringstream mNameOut;
278 mNameOut << meshName << "_" << seName;
279 return mNameOut.str();
282 std::string MEDFileBlowStrEltUp::BuildVarAttName(std::size_t iPart, std::size_t totINbParts, std::size_t jPart, std::size_t totJNbParts, const std::string& name)
284 if(totINbParts==1 && totJNbParts==1)
286 std::ostringstream oss;
287 oss << name << "@" << iPart << "@" << jPart;
291 void MEDFileBlowStrEltUp::DealWithSE(MEDFileFields *fs, MEDFileMeshes *ms, const MEDFileStructureElements *ses)
293 MCAuto<MEDFileFields> fsSEOnly(fs->partOfThisOnStructureElements());
294 fs->killStructureElements();
295 MEDFileBlowStrEltUp bu(fsSEOnly,ms,ses);