Salome HOME
[EDF23738] : multi geometric type in a single mesh having structure elements on each...
[tools/medcoupling.git] / src / MEDLoader / MEDFileStructureElement.cxx
1 // Copyright (C) 2007-2021  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 "MEDFileStructureElement.hxx"
22 #include "MEDFileMeshSupport.hxx"
23 #include "MEDLoaderBase.hxx"
24 #include "MEDFileMeshLL.hxx"
25 #include "MEDFileSafeCaller.txx"
26
27 #include "InterpKernelAutoPtr.hxx"
28
29 using namespace MEDCoupling;
30
31
32 std::string MEDFileSEHolder::getModelName() const
33 {
34   return _father->getName();
35 }
36
37 std::string MEDFileSEHolder::getName() const
38 {
39   return _name;
40 }
41
42 void MEDFileSEHolder::setName(const std::string& name)
43 {
44   _name=name;
45 }
46
47 std::size_t MEDFileSEHolder::getHeapMemorySizeLoc() const
48 {
49   return _name.capacity();
50 }
51
52 ////////////////////
53
54 MEDFileSEConstAtt *MEDFileSEConstAtt::New(med_idt fid, MEDFileStructureElement *father, int idCstAtt, const MEDFileUMesh *mesh)
55 {
56   return new MEDFileSEConstAtt(fid,father,idCstAtt,mesh);
57 }
58
59 MEDFileSEConstAtt::MEDFileSEConstAtt(med_idt fid, MEDFileStructureElement *father, int idCstAtt, const MEDFileUMesh *mesh):MEDFileSEHolder(father)
60 {
61   std::string modelName(getModelName());
62   INTERP_KERNEL::AutoPtr<char> constattname(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE)),profilename(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE));
63   med_attribute_type constatttype;
64   med_int nbCompo;
65   med_entity_type met;
66   med_int miPflSz;
67   MEDFILESAFECALLERRD0(MEDstructElementConstAttInfo,(fid,modelName.c_str(),idCstAtt+1,constattname,&constatttype,&nbCompo,&met,profilename,&miPflSz));
68   std::string name(MEDLoaderBase::buildStringFromFortran(constattname,MED_NAME_SIZE));
69   setName(name);
70   setProfile(MEDLoaderBase::buildStringFromFortran(profilename,MED_NAME_SIZE));
71   _tof=MEDFileMesh::ConvertFromMEDFileEntity(met);
72   //
73   _val=MEDFileStructureElement::BuildFrom(constatttype);
74   nbCompo=MEDFileStructureElement::EffectiveNbCompo(constatttype,FromMedInt<int>(nbCompo));
75   mcIdType pflSz = miPflSz;
76   if(pflSz==0 && getProfile().empty())
77     {
78       switch(met)
79         {
80         case MED_CELL:
81           {
82             std::vector<INTERP_KERNEL::NormalizedCellType> gt(mesh->getAllGeoTypes());
83             if(gt.size()!=1)
84               throw INTERP_KERNEL::Exception("MEDFileSEConstAtt constr : only one cell type expected !");
85             pflSz=mesh->getNumberOfCellsWithType(gt[0]);
86             break;
87           }
88         case MED_NODE:
89           {
90             pflSz=mesh->getNumberOfNodes();
91             break;
92           }
93         default:
94           throw INTERP_KERNEL::Exception("MEDFileSEConstAtt cstr : not recognized entity type !");
95         }
96     }
97   if(constatttype==MED_ATT_NAME)
98     pflSz++;
99   _val->alloc(pflSz,nbCompo);
100   MEDFILESAFECALLERRD0(MEDstructElementConstAttRd,(fid,modelName.c_str(),name.c_str(),_val->getVoidStarPointer()));
101   if(constatttype==MED_ATT_NAME)
102     { pflSz--; _val->reAlloc(pflSz); }
103 }
104
105 std::vector<const BigMemoryObject *> MEDFileSEConstAtt::getDirectChildrenWithNull() const
106 {
107   std::vector<const BigMemoryObject *> ret;
108   ret.push_back(_val);
109   return ret;
110 }
111
112 std::size_t MEDFileSEConstAtt::getHeapMemorySizeWithoutChildren() const
113 {
114   return getHeapMemorySizeLoc()+_pfl.capacity();
115 }
116
117 void MEDFileSEConstAtt::writeLL(med_idt fid) const
118 {
119 }
120
121 void MEDFileSEConstAtt::setProfile(const std::string& name)
122 {
123   _pfl=name;
124 }
125
126 std::string MEDFileSEConstAtt::getProfile() const
127 {
128   return _pfl;
129 }
130
131 ////////////////////
132
133 MEDFileSEVarAtt *MEDFileSEVarAtt::New(med_idt fid, MEDFileStructureElement *father, int idVarAtt)
134 {
135   return new MEDFileSEVarAtt(fid,father,idVarAtt);
136 }
137
138 MEDFileSEVarAtt::MEDFileSEVarAtt(med_idt fid, MEDFileStructureElement *father, int idVarAtt):MEDFileSEHolder(father)
139 {
140   std::string modelName(getModelName());
141   INTERP_KERNEL::AutoPtr<char> varattname(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE)),profilename(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE));
142   med_attribute_type varatttype;
143   {
144     //int pflSz;
145     med_int nbComp;
146     MEDFILESAFECALLERRD0(MEDstructElementVarAttInfo,(fid,modelName.c_str(),idVarAtt+1,varattname,&varatttype,&nbComp));
147     _nb_compo=FromMedInt<int>(nbComp);
148   }
149   setName(MEDLoaderBase::buildStringFromFortran(varattname,MED_NAME_SIZE));
150   _gen=MEDFileStructureElement::BuildFrom(varatttype);
151   _gen->alloc(0,1);
152 }
153
154 std::vector<const BigMemoryObject *> MEDFileSEVarAtt::getDirectChildrenWithNull() const
155 {
156   return std::vector<const BigMemoryObject *>();
157 }
158
159 std::size_t MEDFileSEVarAtt::getHeapMemorySizeWithoutChildren() const
160 {
161   return getHeapMemorySizeLoc();
162 }
163
164 void MEDFileSEVarAtt::writeLL(med_idt fid) const
165 {
166 }
167
168 ////////////////////
169
170 MEDFileStructureElement *MEDFileStructureElement::New(med_idt fid, int idSE, const MEDFileMeshSupports *ms)
171 {
172   return new MEDFileStructureElement(fid,idSE,ms);
173 }
174
175 MEDFileStructureElement::MEDFileStructureElement(med_idt fid, int idSE, const MEDFileMeshSupports *ms)
176 {
177   INTERP_KERNEL::AutoPtr<char> modelName(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE)),supportMeshName(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE));
178   med_geometry_type sgeoType;
179   med_entity_type entiyType;
180   med_int nConsAttr(0),nVarAttr(0);
181   {
182     med_bool anyPfl;
183     med_int nnode(0),ncell(0),dim(0);
184     med_geometry_type idType;
185     MEDFILESAFECALLERRD0(MEDstructElementInfo,(fid,idSE+1,modelName,&idType,&dim,supportMeshName,&entiyType,&nnode,&ncell,&sgeoType,&nConsAttr,&anyPfl,&nVarAttr));
186     _id_type=(int)idType;
187     _dim=FromMedInt<int>(dim);
188   }
189   _name=MEDLoaderBase::buildStringFromFortran(modelName,MED_NAME_SIZE);
190   _sup_mesh_name=MEDLoaderBase::buildStringFromFortran(supportMeshName,MED_NAME_SIZE);
191   _geo_type=MEDFileMesh::ConvertFromMEDFileGeoType(sgeoType);
192   _tof=MEDFileMesh::ConvertFromMEDFileEntity(entiyType);
193   _cst_att.resize(nConsAttr);
194   for(int i=0;i<nConsAttr;i++)
195     _cst_att[i]=MEDFileSEConstAtt::New(fid,this,i,ms->getSupMeshWithName(_sup_mesh_name));
196   _var_att.resize(nVarAttr);
197   for(int i=0;i<nVarAttr;i++)
198     _var_att[i]=MEDFileSEVarAtt::New(fid,this,i);
199 }
200
201 std::vector<const BigMemoryObject *> MEDFileStructureElement::getDirectChildrenWithNull() const
202 {
203   std::vector<const BigMemoryObject *> ret;
204   for(std::vector< MCAuto<MEDFileSEConstAtt> >::const_iterator it=_cst_att.begin();it!=_cst_att.end();it++)
205     ret.push_back(*it);
206   for(std::vector< MCAuto<MEDFileSEVarAtt> >::const_iterator it=_var_att.begin();it!=_var_att.end();it++)
207     ret.push_back(*it);
208   return ret;
209 }
210
211 std::size_t MEDFileStructureElement::getHeapMemorySizeWithoutChildren() const
212 {
213   return _name.capacity()+_cst_att.capacity()*sizeof(MCAuto<MEDFileSEConstAtt>)+_var_att.capacity()*sizeof(MCAuto<MEDFileSEVarAtt>);
214 }
215
216 void MEDFileStructureElement::writeLL(med_idt fid) const
217 {
218 }
219
220 std::string MEDFileStructureElement::getName() const
221 {
222   return _name;
223 }
224
225 MCAuto<DataArray> MEDFileStructureElement::BuildFrom(med_attribute_type mat)
226 {
227   MCAuto<DataArray> ret;
228   switch(mat)
229     {
230     case MED_ATT_INT:
231       {
232         ret=DataArrayInt::New();
233         break;
234       }
235     case MED_ATT_FLOAT64:
236       {
237         ret=DataArrayDouble::New();
238         break;
239       }
240     case MED_ATT_NAME:
241       {
242         ret=DataArrayAsciiChar::New();
243         break;
244       }
245     default:
246       throw INTERP_KERNEL::Exception("MEDFileStructureElement::BuildFrom : not recognized type ! Only INT and FLOAT64 !");
247     }
248   return ret;
249 }
250
251 int MEDFileStructureElement::EffectiveNbCompo(med_attribute_type mat, int nbCompo)
252 {
253   switch(mat)
254     {
255     case MED_ATT_INT:
256     case MED_ATT_FLOAT64:
257       return nbCompo;
258     case MED_ATT_NAME:
259       return nbCompo*MED_NAME_SIZE;
260     default:
261       throw INTERP_KERNEL::Exception("MEDFileStructureElement::BuildFrom : not recognized type ! Only INT and FLOAT64 !");
262     }
263 }
264
265 int MEDFileStructureElement::getDynGT() const
266 {
267   return _id_type;
268 }
269
270 TypeOfField MEDFileStructureElement::getEntity() const
271 {
272   return _tof;
273 }
274
275 std::string MEDFileStructureElement::getMeshName() const
276 {
277   return _sup_mesh_name;
278 }
279
280 std::vector<std::string> MEDFileStructureElement::getVarAtts() const
281 {
282   std::vector<std::string> ret;
283   for(std::vector< MCAuto<MEDFileSEVarAtt> >::const_iterator it=_var_att.begin();it!=_var_att.end();it++)
284     if((*it).isNotNull())
285       ret.push_back((*it)->getName());
286   return ret;
287 }
288
289 const MEDFileSEVarAtt *MEDFileStructureElement::getVarAtt(const std::string& varName) const
290 {
291   for(std::vector< MCAuto<MEDFileSEVarAtt> >::const_iterator it=_var_att.begin();it!=_var_att.end();it++)
292     if((*it).isNotNull())
293       if((*it)->getName()==varName)
294         return *it;
295   std::ostringstream oss; oss << "MEDFileStructureElement::getVarAtt : no var att with name \"" << varName << "\" !";
296   throw INTERP_KERNEL::Exception(oss.str());
297 }
298
299 ////////////////////
300
301 MEDFileStructureElements *MEDFileStructureElements::New(const std::string& fileName, const MEDFileMeshSupports *ms)
302 {
303   MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
304   return New(fid,ms);
305 }
306
307 MEDFileStructureElements *MEDFileStructureElements::New(med_idt fid, const MEDFileMeshSupports *ms)
308 {
309   return new MEDFileStructureElements(fid,ms);
310 }
311
312 MEDFileStructureElements *MEDFileStructureElements::New()
313 {
314   return new MEDFileStructureElements;
315 }
316
317 std::vector<const BigMemoryObject *> MEDFileStructureElements::getDirectChildrenWithNull() const
318 {
319   std::vector<const BigMemoryObject *> ret;
320   for(std::vector< MCAuto<MEDFileStructureElement> >::const_iterator it=_elems.begin();it!=_elems.end();it++)
321     ret.push_back(*it);
322   return ret;
323 }
324
325 std::size_t MEDFileStructureElements::getHeapMemorySizeWithoutChildren() const
326 {
327   return _elems.capacity()*sizeof(MEDFileStructureElement);
328 }
329
330 void MEDFileStructureElements::writeLL(med_idt fid) const
331 {
332 }
333
334 MEDFileStructureElements::MEDFileStructureElements(med_idt fid, const MEDFileMeshSupports *ms)
335 {
336   med_int nbSE(MEDnStructElement(fid));
337   _elems.resize(nbSE);
338   for(int i=0;i<nbSE;i++)
339     _elems[i]=MEDFileStructureElement::New(fid,i,ms);
340   _sup.takeRef(ms);
341 }
342
343 MEDFileStructureElements::MEDFileStructureElements()
344 {
345 }
346
347 MEDFileStructureElements::~MEDFileStructureElements()
348 {
349 }
350
351 int MEDFileStructureElements::getNumberOf() const
352 {
353   return (int)_elems.size();
354 }
355
356 std::vector<int> MEDFileStructureElements::getDynGTAvail() const
357 {
358   std::vector<int> ret;
359   for(std::vector< MCAuto<MEDFileStructureElement> >::const_iterator it=_elems.begin();it!=_elems.end();it++)
360     {
361       const MEDFileStructureElement *elt(*it);
362       if(elt)
363         ret.push_back(elt->getDynGT());
364     }
365   return ret;
366 }
367
368 const MEDFileStructureElement *MEDFileStructureElements::getWithGT(int idGT) const
369 {
370   for(std::vector< MCAuto<MEDFileStructureElement> >::const_iterator it=_elems.begin();it!=_elems.end();it++)
371     if((*it).isNotNull())
372       {
373         if((*it)->getDynGT()==idGT)
374           return *it;
375       }
376   std::ostringstream oss; oss << "MEDFileStructureElements::getWithGT : no such geo type " << idGT << " !";
377   throw INTERP_KERNEL::Exception(oss.str());
378 }
379
380 mcIdType MEDFileStructureElements::getNumberOfNodesPerSE(const std::string& seName) const
381 {
382   if(seName=="MED_PARTICLE")
383     return 1;
384   const MEDFileStructureElement *se(getSEWithName(seName));
385   std::string meshName(se->getMeshName());
386   return _sup->getNumberOfNodesInConnOf(se->getEntity(),se->getGeoType(),meshName);
387 }
388
389 const MEDFileStructureElement *MEDFileStructureElements::getSEWithName(const std::string& seName) const
390 {
391   for(std::vector< MCAuto<MEDFileStructureElement> >::const_iterator it=_elems.begin();it!=_elems.end();it++)
392     {
393       if((*it).isNotNull())
394         if((*it)->getName()==seName)
395           return *it;
396     }
397   std::ostringstream oss; oss << "MEDFileStructureElements::getSEWithName : no such structure element with name " << seName << " !";
398   throw INTERP_KERNEL::Exception(oss.str());
399 }
400
401 std::vector<std::string> MEDFileStructureElements::getVarAttsOf(const std::string& seName) const
402 {
403   const MEDFileStructureElement *se(getSEWithName(seName));
404   return se->getVarAtts();
405 }
406
407 const MEDFileSEVarAtt *MEDFileStructureElements::getVarAttOf(const std::string &seName, const std::string& varName) const
408 {
409   const MEDFileStructureElement *se(getSEWithName(seName));
410   return se->getVarAtt(varName);
411 }
412
413 const MEDFileUMesh *MEDFileStructureElements::getSupMeshWithName(const std::string& name) const
414 {
415   return _sup->getSupMeshWithName(name);
416 }