Salome HOME
0ee8ec16fea0b050a398a7294fce0696acbec836
[tools/medcoupling.git] / src / MEDLoader / MEDFileBlowStrEltUp.cxx
1 // Copyright (C) 2007-2017  CEA/DEN, EDF R&D
2 //
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.
7 //
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.
12 //
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
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 // Author : Anthony Geay (EDF R&D)
20
21 #include "MEDFileBlowStrEltUp.hxx"
22 #include "MEDCouplingFieldDouble.hxx"
23
24 using namespace MEDCoupling;
25
26 const char MEDFileBlowStrEltUp::MED_BALL_STR[]="MED_BALL";
27
28 MEDFileBlowStrEltUp::MEDFileBlowStrEltUp(const MEDFileFields *fsOnlyOnSE, const MEDFileMeshes *ms, const MEDFileStructureElements *ses)
29 {
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());
36   _elts.resize(sz);
37   for(std::size_t i=0;i<sz;i++)
38     {
39       const std::pair<std::string,std::string>& p(ps[i]);
40       MCAuto<MEDFileFields> f(fsOnlyOnSE->partOfThisLyingOnSpecifiedMeshSEName(p.first,p.second));
41       _elts[i]=f;
42     }
43   for(std::size_t i=0;i<sz;i++)
44     {
45       const std::pair<std::string,std::string>& p(ps[i]);
46       MEDFileMesh *mesh(_ms->getMeshWithName(p.first));
47       if(!mesh)
48         throw INTERP_KERNEL::Exception("MEDFileBlowStrEltUp : NULL mesh !");
49       MEDFileUMesh *umesh(dynamic_cast<MEDFileUMesh *>(mesh));
50       if(!umesh)
51         throw INTERP_KERNEL::Exception("MEDFileBlowStrEltUp : Blow up of Stru Elt not managed yet for unstructured meshes !");
52     }
53 }
54
55 /*!
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
59  */
60 MCAuto<MEDFileEltStruct4Mesh> MEDFileBlowStrEltUp::dealWithSEInMesh(const std::string& seName, MEDFileUMesh *mesh, MCAuto<MEDFileUMesh>& mOut, MCAuto<MEDFileFields>& fsOut) const
61 {
62   if(!mesh)
63     throw INTERP_KERNEL::Exception("MEDFileBlowStrEltUp::dealWithSEInMesh : null pointer !");
64   if(seName==MED_BALL_STR)
65     {
66       MCAuto<MEDFileEltStruct4Mesh> ret(dealWithMEDBALLInMesh(mesh,mOut,fsOut));
67       mesh->killStructureElements();
68       return ret;
69     }
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 !");
71 }
72
73 MCAuto<MEDFileEltStruct4Mesh> MEDFileBlowStrEltUp::dealWithMEDBALLInMesh(const MEDFileUMesh *mesh, MCAuto<MEDFileUMesh>& mOut, MCAuto<MEDFileFields>& fsOut) const
74 {
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++)
79     {
80       if((*it)->getGeoTypeName()==MED_BALL_STR)
81         {
82           zeStr=*it;
83           break;
84         }
85     }
86   if(zeStr.isNull())
87     {
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());
90     }
91   const DataArrayDouble *coo(mesh->getCoords());
92   if(!coo)
93     throw INTERP_KERNEL::Exception("MEDFileBlowStrEltUp::dealWithMEDBALLInMesh : null coords !");
94   MCAuto<DataArrayInt> conn(zeStr->getConn());
95   if(conn.isNull())
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));
106   if(ff1)
107     {
108       MCAuto<DataArrayInt> ff1o(ff1->selectByTupleIdSafe(conn->begin(),conn->end()));
109       mOut->setFamilyFieldArr(1,ff1o);
110     }
111   const DataArrayInt *nf1(mesh->getNumberFieldAtLevel(1));
112   if(nf1)
113     {
114       MCAuto<DataArrayInt> nf1o(nf1->selectByTupleIdSafe(conn->begin(),conn->end()));
115       mOut->setRenumFieldArr(1,nf1o);
116     }
117   MCAuto<MEDFileUMeshPerTypeCommon> md(zeStr->getMeshDef());
118   const DataArrayInt *ff0(md->getFam());
119   if(ff0)
120     {
121       MCAuto<DataArrayInt> ff0o(ff0->duplicateEachTupleNTimes(nbCells));
122       mOut->setFamilyFieldArr(0,ff0o);
123     }
124   const DataArrayInt *nf0(md->getNum());
125   if(nf0)
126     {
127       MCAuto<DataArrayInt> nf0o(ff0->duplicateEachTupleNTimes(nbCells));
128       mOut->setRenumFieldArr(0,nf0o);
129     }
130   mOut->copyFamGrpMapsFrom(*mesh);
131   const std::vector< MCAuto<DataArray> >& vars(zeStr->getVars());
132   for(std::vector< MCAuto<DataArray> >::const_iterator it=vars.begin();it!=vars.end();it++)
133     {
134       const DataArray *elt(*it);
135       if(!elt)
136         continue;
137       {
138         const DataArrayDouble *eltC(dynamic_cast<const DataArrayDouble *>(elt));
139         if(eltC)
140           {
141             MCAuto<MEDFileFieldMultiTS> fmts(MEDFileFieldMultiTS::New());
142             MCAuto<MEDFileField1TS> f1ts(MEDFileField1TS::New());
143             MCAuto<MEDCouplingFieldDouble> f(MEDCouplingFieldDouble::New(ON_NODES));
144             f->setMesh(mcOut);
145             f->setArray(const_cast<DataArrayDouble *>(eltC));
146             f->setName(eltC->getName());
147             f1ts->setFieldNoProfileSBT(f);
148             fmts->pushBackTimeStep(f1ts);
149             fsOut->pushField(fmts);
150           }
151       }
152     }
153   return zeStr;
154 }
155
156 /*!
157  * \param [in] fs - fields lying all on same mesh and on same structure element
158  * \param [in] zeStr - ze structure of current structure element
159  * \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
160  * \param [out] zeOutputs - ze fields that are the concatenation of fields in \a fs transformed and those in \a varAtt normalized in time space
161  */
162 void MEDFileBlowStrEltUp::dealWithSEInFields(const std::string& seName, const MEDFileFields *fs, const MEDFileEltStruct4Mesh *zeStr, const MEDFileFields *varAtt, MCAuto<MEDFileFields>& zeOutputs) const
163 {
164   if(!fs)
165     throw INTERP_KERNEL::Exception("MEDFileBlowStrEltUp::dealWithSEInFields : null pointer !");
166   if(seName==MED_BALL_STR)
167     {
168       dealWithMEDBALLSInFields(fs,zeStr,varAtt,zeOutputs);
169       return ;
170     }
171   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 !");
172 }
173
174 void MEDFileBlowStrEltUp::dealWithMEDBALLSInFields(const MEDFileFields *fs, const MEDFileEltStruct4Mesh *zeStr, const MEDFileFields *varAtt, MCAuto<MEDFileFields>& zeOutputs) const
175 {
176   
177 }
178
179 void MEDFileBlowStrEltUp::generate(MCAuto<MEDFileMeshes>& msOut, MCAuto<MEDFileFields>& allZeOutFields)
180 {
181   msOut=MEDFileMeshes::New();
182   allZeOutFields=MEDFileFields::New();
183   for(std::vector< MCAuto<MEDFileFields> >::iterator elt=_elts.begin();elt!=_elts.end();elt++)
184     {
185       std::vector< std::pair<std::string,std::string> > ps;
186       (*elt)->getMeshSENames(ps);
187       if(ps.size()!=1)
188         throw INTERP_KERNEL::Exception("MEDFileBlowStrEltUp::generateMeshes : internal error !");
189       MEDFileMesh *mesh(_ms->getMeshWithName(ps[0].first));
190       if(!mesh)
191         throw INTERP_KERNEL::Exception("MEDFileBlowStrEltUp::generateMeshes : NULL mesh !");
192       MEDFileUMesh *umesh(dynamic_cast<MEDFileUMesh *>(mesh));
193       if(!umesh)
194         throw INTERP_KERNEL::Exception("MEDFileBlowStrEltUp::generateMeshes : Blow up of Stru Elt not managed yet for unstructured meshes !");
195       MCAuto<MEDFileUMesh> mOut;
196       MCAuto<MEDFileFields> fsOut1;
197       MCAuto<MEDFileEltStruct4Mesh> zeStr(dealWithSEInMesh(ps[0].second,umesh,mOut,fsOut1));
198       msOut->pushMesh(umesh);
199       MCAuto<MEDFileFields> fsOut2;
200       dealWithSEInFields(ps[0].second,*elt,zeStr,fsOut1,fsOut2);
201       allZeOutFields->aggregate(*fsOut2);
202     }
203 }
204
205 std::string MEDFileBlowStrEltUp::BuildNewMeshName(const std::string& meshName, const std::string& seName)
206 {
207   std::ostringstream mNameOut;
208   mNameOut << meshName << "_" << seName;
209   return mNameOut.str();
210 }
211
212 void MEDFileBlowStrEltUp::DealWithSE(MEDFileFields *fs, const MEDFileMeshes *ms, const MEDFileStructureElements *ses, MCAuto<MEDFileFields>& fsOut, MCAuto<MEDFileMeshes>& msOut)
213 {
214   MCAuto<MEDFileFields> fsSEOnly(fs->partOfThisOnStructureElements());
215   fs->killStructureElements();
216   MEDFileBlowStrEltUp bu(fsSEOnly,ms,ses);
217   MCAuto<MEDFileMeshes> msOut1;
218   MCAuto<MEDFileFields> allZeOutFields1;
219   bu.generate(msOut1,allZeOutFields1);
220   
221 }