]> SALOME platform Git repositories - tools/medcoupling.git/blob - src/MEDLoader/MEDFileFieldOverView.cxx
Salome HOME
On the road of last imps for MEDReader
[tools/medcoupling.git] / src / MEDLoader / MEDFileFieldOverView.cxx
1 // Copyright (C) 2007-2013  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.
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 (CEA/DEN)
20
21 #include "MEDFileFieldOverView.hxx"
22 #include "MEDFileField.hxx"
23 #include "MEDFileMesh.hxx"
24
25 #include "CellModel.hxx"
26
27 using namespace ParaMEDMEM;
28
29 MEDFileMeshStruct *MEDFileMeshStruct::New(const MEDFileMesh *mesh)
30 {
31   return new MEDFileMeshStruct(mesh);
32 }
33
34 std::size_t MEDFileMeshStruct::getHeapMemorySize() const
35 {
36   return 0;
37 }
38
39 MEDFileMeshStruct::MEDFileMeshStruct(const MEDFileMesh *mesh):_mesh(mesh)
40 {
41   std::vector<int> levs=mesh->getNonEmptyLevels();
42   _name=mesh->getName();
43   _nb_nodes=mesh->getNumberOfNodes();
44   _geo_types_distrib.resize(levs.size());
45   for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
46     {
47       MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> mLev=mesh->getGenMeshAtLevel(*lev);
48       _geo_types_distrib[-(*lev)]=mLev->getDistributionOfTypes();
49     }
50 }
51
52 int MEDFileMeshStruct::getLevelOfGeoType(INTERP_KERNEL::NormalizedCellType t) const throw(INTERP_KERNEL::Exception)
53 {
54   int j=0;
55   for(std::vector< std::vector<int> >::const_iterator it1=_geo_types_distrib.begin();it1!=_geo_types_distrib.end();it1++,j--)
56     {
57       std::size_t sz=(*it1).size();
58       if(sz%3!=0)
59         throw INTERP_KERNEL::Exception("MEDFileMeshStruct::getLevelOfGeoType : internal error in code !");
60       std::size_t nbGeo=sz/3;
61       for(std::size_t i=0;i<nbGeo;i++)
62         if((*it1)[3*i]==(int)t)
63           return j;
64     }
65   throw INTERP_KERNEL::Exception("MEDFileMeshStruct::getLevelOfGeoType : The specified geometric type is not present in the mesh structure !");
66 }
67
68 int MEDFileMeshStruct::getNumberOfElemsOfGeoType(INTERP_KERNEL::NormalizedCellType t) const throw(INTERP_KERNEL::Exception)
69 {
70   for(std::vector< std::vector<int> >::const_iterator it1=_geo_types_distrib.begin();it1!=_geo_types_distrib.end();it1++)
71     {
72       std::size_t sz=(*it1).size();
73       if(sz%3!=0)
74         throw INTERP_KERNEL::Exception("MEDFileMeshStruct::getNumberOfElemsOfGeoType : internal error in code !");
75       std::size_t nbGeo=sz/3;
76       for(std::size_t i=0;i<nbGeo;i++)
77         if((*it1)[3*i]==(int)t)
78           return (*it1)[3*i+1];
79     }
80   throw INTERP_KERNEL::Exception("The specified geometric type is not present in the mesh structure !");
81 }
82
83 int MEDFileMeshStruct::getNumberOfLevs() const
84 {
85   return (int)_geo_types_distrib.size();
86 }
87
88 int MEDFileMeshStruct::getNumberOfGeoTypesInLev(int relativeLev) const throw(INTERP_KERNEL::Exception)
89 {
90   int pos(-relativeLev);
91   if(pos<0 || pos>=_geo_types_distrib.size())
92     throw INTERP_KERNEL::Exception("MEDFileMeshStruct::getNumberOfGeoTypesInLev : invalid level specified !");
93   std::size_t sz=_geo_types_distrib[pos].size();
94   if(sz%3!=0)
95     throw INTERP_KERNEL::Exception("MEDFileMeshStruct::getNumberOfGeoTypesInLev : internal error in code !");
96   return (int)(sz/3);
97 }
98
99 //=
100
101 MEDFileField1TSStructItem2::MEDFileField1TSStructItem2()
102 {
103 }
104
105 MEDFileField1TSStructItem2::MEDFileField1TSStructItem2(INTERP_KERNEL::NormalizedCellType a, const std::pair<int,int>& b, const std::string& c, const std::string& d):_geo_type(a),_start_end(b),_pfl(DataArrayInt::New()),_loc(d),_nb_of_entity(-1)
106 {
107   _pfl->setName(c.c_str());
108 }
109
110 void MEDFileField1TSStructItem2::checkWithMeshStructForCells(const MEDFileMeshStruct *mst, const MEDFileFieldGlobs *globs) throw(INTERP_KERNEL::Exception)
111 {
112   int nbOfEnt=mst->getNumberOfElemsOfGeoType(_geo_type);
113   checkInRange(nbOfEnt,1,globs);
114 }
115
116 void MEDFileField1TSStructItem2::checkWithMeshStructForGaussNE(const MEDFileMeshStruct *mst, const MEDFileFieldGlobs *globs) throw(INTERP_KERNEL::Exception)
117 {
118   int nbOfEnt=mst->getNumberOfElemsOfGeoType(_geo_type);
119   const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_geo_type);
120   checkInRange(nbOfEnt,(int)cm.getNumberOfNodes(),globs);
121 }
122
123 void MEDFileField1TSStructItem2::checkWithMeshStructForGaussPT(const MEDFileMeshStruct *mst, const MEDFileFieldGlobs *globs) throw(INTERP_KERNEL::Exception)
124 {
125   if(!globs)
126     throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::checkWithMeshStructForGaussPT : no globals specified !");
127   if(_loc.empty())
128     throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::checkWithMeshStructForGaussPT : no localization specified !");
129   const MEDFileFieldLoc& loc=globs->getLocalization(_loc.c_str());
130   int nbOfEnt=mst->getNumberOfElemsOfGeoType(_geo_type);
131   checkInRange(nbOfEnt,loc.getNumberOfGaussPoints(),globs);
132 }
133
134 std::string MEDFileField1TSStructItem2::getPflName() const
135 {
136   return _pfl->getName();
137 }
138
139 /*!
140  * \param [in] nbOfEntity - number of entity that can be either cells or nodes. Not other possiblity.
141  * \param [in] nip - number of integration points. 1 for ON_CELLS and NO_NODES
142  */
143 void MEDFileField1TSStructItem2::checkInRange(int nbOfEntity, int nip, const MEDFileFieldGlobs *globs) throw(INTERP_KERNEL::Exception)
144 {
145   _nb_of_entity=nbOfEntity;
146   if(_pfl->getName().empty())
147     {
148       if(nbOfEntity!=(_start_end.second-_start_end.first)/nip)
149         throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::checkInRange : Mismatch between number of entities and size of node field !");
150       return ;
151     }
152   else
153     {
154       if(!globs)
155         throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::checkInRange : Presence of a profile on field whereas no globals found in file !");
156       const DataArrayInt *pfl=globs->getProfile(_pfl->getName().c_str());
157       if(!pfl)
158         throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::checkInRange : Presence of a profile on field whereas no such profile found in file !");
159       pfl->checkAllIdsInRange(0,nbOfEntity);
160     }
161 }
162
163 bool MEDFileField1TSStructItem2::operator==(const MEDFileField1TSStructItem2& other) const throw(INTERP_KERNEL::Exception)
164 {
165   //_nb_of_entity is not taken into account here. It is not a bug, because no mesh consideration needed here to perform fast compare.
166   //idem for _loc. It is not an effective attribute for support comparison.
167   return _geo_type==other._geo_type && _start_end==other._start_end && _pfl->getName()==other._pfl->getName();
168 }
169
170 bool MEDFileField1TSStructItem2::isCellSupportEqual(const MEDFileField1TSStructItem2& other) const throw(INTERP_KERNEL::Exception)
171 {
172   if(_geo_type!=other._geo_type)
173     return false;
174   if(_nb_of_entity!=other._nb_of_entity)
175     return false;
176   if((_pfl->getName().empty() && !other._pfl->getName().empty()) || (!_pfl->getName().empty() && other._pfl->getName().empty()))
177     return false;
178   if(_pfl->getName().empty() && other._pfl->getName().empty())
179     return true;
180   return _pfl->isEqualWithoutConsideringStr(*other._pfl);
181 }
182
183 /*!
184  * \a objs must be non empty. \a objs should contain items having same geometric type.
185  */
186 MEDFileField1TSStructItem2 MEDFileField1TSStructItem2::BuildAggregationOf(const std::vector<const MEDFileField1TSStructItem2 *>& objs, const MEDFileFieldGlobs *globs) throw(INTERP_KERNEL::Exception)
187 {
188   if(objs.empty())
189     throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::BuildAggregationOf : empty input !");
190   if(objs.size()==1)
191     return MEDFileField1TSStructItem2(*objs[0]);
192   INTERP_KERNEL::NormalizedCellType gt(objs[0]->_geo_type);
193   int nbEntityRef(objs[0]->_nb_of_entity);
194   std::size_t sz(objs.size());
195   std::vector<const DataArrayInt *> arrs(sz);
196   for(std::size_t i=0;i<sz;i++)
197     {
198       const MEDFileField1TSStructItem2 *obj(objs[i]);
199       if(gt!=obj->_geo_type)
200         throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::BuildAggregationOf : invalid situation ! All input must have the same geo type !");
201       if(nbEntityRef!=obj->_nb_of_entity)
202         throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::BuildAggregationOf : invalid situation ! All input must have the global nb of entity !");
203       if(obj->_pfl->getName().empty())
204         throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::BuildAggregationOf : invalid situation ! Several same geo type chunk must all lie on profiles !");
205       arrs[i]=globs->getProfile(obj->_pfl->getName().c_str());
206     }
207   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr(DataArrayInt::Aggregate(arrs));
208   arr->sort();
209   int oldNbTuples(arr->getNumberOfTuples());
210   arr=arr->buildUnique();
211   if(oldNbTuples!=arr->getNumberOfTuples())
212     throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::BuildAggregationOf : some entities are present several times !");
213   if(arr->isIdentity() && oldNbTuples==nbEntityRef)
214     {
215       std::pair<int,int> p(0,nbEntityRef);
216       std::string a,b;
217       MEDFileField1TSStructItem2 ret(gt,p,a,b);
218       ret._nb_of_entity=nbEntityRef;
219       return ret;
220     }
221   else
222     {
223       arr->setName("???");
224       std::pair<int,int> p(0,oldNbTuples);
225       std::string a,b;
226       MEDFileField1TSStructItem2 ret(gt,p,a,b);
227       ret._nb_of_entity=nbEntityRef;
228       ret._pfl=arr;
229       return ret;
230     }
231 }
232
233 //=
234
235 MEDFileField1TSStructItem::MEDFileField1TSStructItem(TypeOfField a, const std::vector< MEDFileField1TSStructItem2 >& b):_computed(false),_type(a),_items(b)
236 {
237 }
238
239 void MEDFileField1TSStructItem::checkWithMeshStruct(const MEDFileMeshStruct *mst, const MEDFileFieldGlobs *globs) throw(INTERP_KERNEL::Exception)
240 {
241   switch(_type)
242     {
243     case ON_NODES:
244       {
245         int nbOfEnt=mst->getNumberOfNodes();
246         if(_items.size()!=1)
247           throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::checkWithMeshStruct : for nodes field only one subdivision supported !");
248         _items[0].checkInRange(nbOfEnt,1,globs);
249         break ;
250       }
251     case ON_CELLS:
252       {
253         for(std::vector< MEDFileField1TSStructItem2 >::iterator it=_items.begin();it!=_items.end();it++)
254           (*it).checkWithMeshStructForCells(mst,globs);
255         break;
256       }
257     case ON_GAUSS_NE:
258       {
259         for(std::vector< MEDFileField1TSStructItem2 >::iterator it=_items.begin();it!=_items.end();it++)
260           (*it).checkWithMeshStructForGaussNE(mst,globs);
261         break;
262       }
263     case ON_GAUSS_PT:
264       {
265         for(std::vector< MEDFileField1TSStructItem2 >::iterator it=_items.begin();it!=_items.end();it++)
266           (*it).checkWithMeshStructForGaussPT(mst,globs);
267         break;
268       }
269     default:
270       throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::checkWithMeshStruct : not managed field type !");
271     }
272 }
273
274 bool MEDFileField1TSStructItem::operator==(const MEDFileField1TSStructItem& other) const throw(INTERP_KERNEL::Exception)
275 {
276   if(_type!=other._type)
277     return false;
278   if(_items.size()!=other._items.size())
279     return false;
280   for(std::size_t i=0;i<_items.size();i++)
281     if(!(_items[i]==other._items[i]))
282       return false;
283   return true;
284 }
285
286 bool MEDFileField1TSStructItem::isCellSupportEqual(const MEDFileField1TSStructItem& other) const throw(INTERP_KERNEL::Exception)
287 {
288   if(_type!=other._type)
289     return false;
290   if(_items.size()!=other._items.size())
291     return false;
292   for(std::size_t i=0;i<_items.size();i++)
293     if(!(_items[i].isCellSupportEqual(other._items[i])))
294       return false;
295   return true;
296 }
297
298 bool MEDFileField1TSStructItem::isEntityCell() const
299 {
300   if(_type==ON_NODES)
301     return false;
302   else
303     return true;
304 }
305
306 class CmpGeo
307 {
308 public:
309   CmpGeo(INTERP_KERNEL::NormalizedCellType geoTyp):_geo_type(geoTyp) { }
310   bool operator()(const std::pair< INTERP_KERNEL::NormalizedCellType, std::vector<std::size_t> > & v) const { return _geo_type==v.first; }
311 private:
312   INTERP_KERNEL::NormalizedCellType _geo_type;
313 };
314
315 MEDFileField1TSStructItem MEDFileField1TSStructItem::simplifyMeOnCellEntity(const MEDFileFieldGlobs *globs) const throw(INTERP_KERNEL::Exception)
316 {
317   if(!isEntityCell())
318     throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::simplifyMeOnCellEntity : must be on ON_CELLS, ON_GAUSS_NE or ON_GAUSS_PT !");
319   std::vector< std::pair< INTERP_KERNEL::NormalizedCellType, std::vector<std::size_t> > > m;
320   std::size_t i=0;
321   for(std::vector< MEDFileField1TSStructItem2 >::const_iterator it=_items.begin();it!=_items.end();it++,i++)
322     {
323       std::vector< std::pair< INTERP_KERNEL::NormalizedCellType, std::vector<std::size_t> > >::iterator it0(std::find_if(m.begin(),m.end(),CmpGeo((*it).getGeo())));
324       if(it0==m.end())
325         m.push_back(std::pair< INTERP_KERNEL::NormalizedCellType, std::vector<std::size_t> >((*it).getGeo(),std::vector<std::size_t>(1,i)));
326       else
327         (*it0).second.push_back(i);
328     }
329   if(m.size()==_items.size())
330     {
331       MEDFileField1TSStructItem ret(*this);
332       ret._type=ON_CELLS;
333       return ret;
334     }
335   std::size_t sz(m.size());
336   std::vector< MEDFileField1TSStructItem2 > items(sz);
337   for(i=0;i<sz;i++)
338     {
339       const std::vector<std::size_t>& ids=m[i].second;
340       std::vector<const MEDFileField1TSStructItem2 *>objs(ids.size());
341       for(std::size_t j=0;j<ids.size();j++)
342         objs[j]=&_items[ids[j]];
343       items[i]=MEDFileField1TSStructItem2::BuildAggregationOf(objs,globs);
344     }
345   MEDFileField1TSStructItem ret(ON_CELLS,items);
346   ret._computed=true;
347   return ret;
348 }
349
350 /*!
351  * \a this is expected to be ON_CELLS and simplified.
352  */
353 bool MEDFileField1TSStructItem::isCompatibleWithNodesDiscr(const MEDFileField1TSStructItem& other, const MEDFileMeshStruct *meshSt, const MEDFileFieldGlobs *globs) const throw(INTERP_KERNEL::Exception)
354 {
355   if(other._type!=ON_NODES)
356     throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::isCompatibleWithNodesDiscr : other must be on nodes !");
357   if(other._items.size()!=1)
358     throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::isCompatibleWithNodesDiscr : other is on nodes but number of subparts !");
359   int theFirstLevFull;
360   bool ret0=isFullyOnOneLev(meshSt,theFirstLevFull);
361   const MEDFileField1TSStructItem2& otherNodeIt(other._items[0]);
362   if(otherNodeIt.getPflName().empty())
363     {//on all nodes
364       if(!ret0)
365         return false;
366       return theFirstLevFull==0;
367     }
368   else
369     {
370       const DataArrayInt *pfl=globs->getProfile(otherNodeIt.getPflName().c_str());
371       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cpyPfl(pfl->deepCpy());
372       cpyPfl->sort();
373       int nbOfNodes(meshSt->getNumberOfNodes());
374       if(cpyPfl->isIdentity() && cpyPfl->getNumberOfTuples()==nbOfNodes)
375         {//on all nodes also !
376           if(!ret0)
377             return false;
378           return theFirstLevFull==0;
379         }
380       std::vector<bool> nodesFetched(nbOfNodes,false);
381       meshSt->getTheMesh()->whichAreNodesFetched(*this,globs,nodesFetched);
382       return cpyPfl->isFittingWith(nodesFetched);
383     }
384 }
385
386 bool MEDFileField1TSStructItem::isFullyOnOneLev(const MEDFileMeshStruct *meshSt, int& theFirstLevFull) const throw(INTERP_KERNEL::Exception)
387 {
388   if(_type!=ON_CELLS)
389     throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::isFullyOnOneLev : works only for ON_CELLS discretization !");
390   if(_items.empty())
391     throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::isFullyOnOneLev : items vector is empty !");
392   int nbOfLevs(meshSt->getNumberOfLevs());
393   if(nbOfLevs==0)
394     throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::isFullyOnOneLev : no levels in input mesh structure !");
395   std::vector<int> levs(nbOfLevs);
396   theFirstLevFull=1;
397   int nbOfGT=0;
398   std::set<INTERP_KERNEL::NormalizedCellType> gts;
399   for(std::vector< MEDFileField1TSStructItem2 >::const_iterator it=_items.begin();it!=_items.end();it++)
400     {
401       if(!(*it).getPflName().empty())
402         return false;
403       INTERP_KERNEL::NormalizedCellType gt((*it).getGeo());
404       if(gts.find(gt)!=gts.end())
405         throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::isFullyOnOneLev : internal error !");
406       gts.insert(gt);
407       int pos(meshSt->getLevelOfGeoType((*it).getGeo()));
408       levs[-pos]++;
409     }
410   for(int i=0;i<nbOfLevs;i++)
411     if(meshSt->getNumberOfGeoTypesInLev(-i)==levs[i])
412       { theFirstLevFull=-i; return true; }
413   return false;
414 }
415
416 const MEDFileField1TSStructItem2& MEDFileField1TSStructItem::operator[](std::size_t i) const throw(INTERP_KERNEL::Exception)
417 {
418   if(i<0 || i>=_items.size())
419     throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::operator[] : input is not in valid range !");
420   return _items[i];
421 }
422
423 //=
424
425 MEDFileField1TSStruct *MEDFileField1TSStruct::New(const MEDFileAnyTypeField1TS *ref, MEDFileMeshStruct *mst) throw(INTERP_KERNEL::Exception)
426 {
427   return new MEDFileField1TSStruct(ref,mst);
428 }
429
430 MEDFileField1TSStruct::MEDFileField1TSStruct(const MEDFileAnyTypeField1TS *ref, MEDFileMeshStruct *mst)
431 {
432   _already_checked.push_back(BuildItemFrom(ref,mst));
433 }
434
435 void MEDFileField1TSStruct::checkWithMeshStruct(MEDFileMeshStruct *mst, const MEDFileFieldGlobs *globs) throw(INTERP_KERNEL::Exception)
436 {
437   if(_already_checked.empty())
438     throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::checkWithMeshStruct : not correctly initialized !");
439   _already_checked.back().checkWithMeshStruct(mst,globs);
440 }
441
442 bool MEDFileField1TSStruct::isEqualConsideringThePast(const MEDFileAnyTypeField1TS *other, const MEDFileMeshStruct *mst) const throw(INTERP_KERNEL::Exception)
443 {
444   MEDFileField1TSStructItem b(BuildItemFrom(other,mst));
445   for(std::vector<MEDFileField1TSStructItem>::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++)
446     {
447       if((*it)==b)
448         return true;
449     }
450   return false;
451 }
452
453 /*!
454  * Not const because \a other structure will be added to the \c _already_checked attribute in case of success.
455  */
456 bool MEDFileField1TSStruct::isSupportSameAs(const MEDFileAnyTypeField1TS *other, const MEDFileMeshStruct *meshSt) throw(INTERP_KERNEL::Exception)
457 {
458   if(_already_checked.empty())
459     throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::isSupportSameAs : no ref !");
460   MEDFileField1TSStructItem b(BuildItemFrom(other,meshSt));
461   if(!_already_checked[0].isEntityCell() || !b.isEntityCell())
462     throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::isSupportSameAs : only available on cell entities !");
463   MEDFileField1TSStructItem other1(b.simplifyMeOnCellEntity(other->contentNotNull()));
464   int found=-1,i=0;
465   for(std::vector<MEDFileField1TSStructItem>::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++,i++)
466     if((*it).isComputed())
467       { found=i; break; }
468   bool ret(false);
469   if(found==-1)
470     {
471       MEDFileField1TSStructItem this1(_already_checked[0].simplifyMeOnCellEntity(other->contentNotNull()));
472       ret=this1.isCellSupportEqual(other1);
473       if(ret)
474         _already_checked.push_back(this1);
475     }
476   else
477     ret=_already_checked[found].isCellSupportEqual(other1);
478   if(ret)
479     _already_checked.push_back(b);
480   return ret;
481 }
482
483 bool MEDFileField1TSStruct::isCompatibleWithNodesDiscr(const MEDFileAnyTypeField1TS *other, const MEDFileMeshStruct *meshSt) throw(INTERP_KERNEL::Exception)
484 {
485   if(_already_checked.empty())
486     throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::isCompatibleWithNodesDiscr : no ref !");
487   if(!_already_checked[0].isEntityCell())
488     throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::isCompatibleWithNodesDiscr : only available on cell entities !");
489   MEDFileField1TSStructItem other1(BuildItemFrom(other,meshSt));
490   //
491   int found=-1,i=0;
492   for(std::vector<MEDFileField1TSStructItem>::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++,i++)
493     if((*it).isComputed())
494       { found=i; break; }
495   bool ret(false);
496   if(found==-1)
497     {
498       MEDFileField1TSStructItem this1(_already_checked[0].simplifyMeOnCellEntity(other->contentNotNull()));
499       ret=this1.isCompatibleWithNodesDiscr(other1,meshSt,other->contentNotNull());
500       if(ret)
501         _already_checked.push_back(this1);
502     }
503   else
504     ret=_already_checked[found].isCompatibleWithNodesDiscr(other1,meshSt,other->contentNotNull());
505   if(ret)
506     _already_checked.push_back(other1);
507   return ret;
508 }
509
510 std::size_t MEDFileField1TSStruct::getHeapMemorySize() const
511 {
512   return 0;
513 }
514
515 MEDFileField1TSStructItem MEDFileField1TSStruct::BuildItemFrom(const MEDFileAnyTypeField1TS *ref, const MEDFileMeshStruct *meshSt)
516 {
517   TypeOfField atype;
518   std::vector< MEDFileField1TSStructItem2 > anItems;
519   //
520   std::vector< std::vector<std::string> > pfls,locs;
521   std::vector< std::vector<TypeOfField> > typesF;
522   std::vector<INTERP_KERNEL::NormalizedCellType> geoTypes;
523   std::vector< std::vector<std::pair<int,int> > > strtEnds=ref->getFieldSplitedByType(0,geoTypes,typesF,pfls,locs);
524   std::size_t nbOfGeoTypes(geoTypes.size());
525   if(nbOfGeoTypes==0)
526     throw INTERP_KERNEL::Exception("MEDFileField1TSStruct : not null by empty ref  !");
527   bool isFirst=true;
528   for(std::size_t i=0;i<nbOfGeoTypes;i++)
529     {
530       std::size_t sz=typesF[i].size();
531       if(strtEnds[i].size()<1 || sz<1 || pfls[i].size()<1)
532         throw INTERP_KERNEL::Exception("MEDFileField1TSStruct : internal error #1 !");
533       //
534       if(isFirst)
535         atype=typesF[i][0];
536       isFirst=false;
537       //
538       for(std::size_t j=0;j<sz;j++)
539         {
540           if(atype==typesF[i][j])
541             anItems.push_back(MEDFileField1TSStructItem2(geoTypes[i],strtEnds[i][j],pfls[i][j],locs[i][j]));
542           else
543             throw INTERP_KERNEL::Exception("MEDFileField1TSStruct : can be applied only on single spatial discretization fields ! Call SplitPerDiscretization method !");
544         }
545     }
546   MEDFileField1TSStructItem ret(atype,anItems);
547   ret.checkWithMeshStruct(meshSt,ref->contentNotNull());
548   return ret;
549 }
550
551 //=
552
553 MEDFileFastCellSupportComparator *MEDFileFastCellSupportComparator::New(const MEDFileMesh *m, const MEDFileAnyTypeFieldMultiTS *ref) throw(INTERP_KERNEL::Exception)
554 {
555   return new MEDFileFastCellSupportComparator(m,ref);
556 }
557
558 MEDFileFastCellSupportComparator::MEDFileFastCellSupportComparator(const MEDFileMesh *m, const MEDFileAnyTypeFieldMultiTS *ref)
559 {
560   _mesh_comp=MEDFileMeshStruct::New(m);
561   int nbPts=ref->getNumberOfTS();
562   _f1ts_cmps.resize(nbPts);
563   for(int i=0;i<nbPts;i++)
564     {
565       MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TS> elt=ref->getTimeStepAtPos(i);
566       _f1ts_cmps[i]=MEDFileField1TSStruct::New(elt,_mesh_comp);
567       _f1ts_cmps[i]->checkWithMeshStruct(_mesh_comp,elt->contentNotNull());
568     }
569 }
570
571 std::size_t MEDFileFastCellSupportComparator::getHeapMemorySize() const
572 {
573   /*std::size_t part1=sizeof(MEDFileFastCellSupportComparator)+_mesh_name.capacity()+_already_passed_code1.capacity()*sizeof(std::vector<int>)+_already_passed_code2.capacity()*sizeof(void*)+_m_geo_types_distrib.capacity()*sizeof(std::vector<int>);
574   std::size_t part2=0;
575   for(std::vector< std::vector<int> >::const_iterator it=_already_passed_code1.begin();it!=_already_passed_code1.end();it++)
576     part2+=(*it).capacity()*(sizeof(int)+sizeof(const DataArrayInt *));
577   for(std::vector< std::vector<int> >::const_iterator it2=_m_geo_types_distrib.begin();it2!=_m_geo_types_distrib.end();it2++)
578     part2+=(*it2).capacity()*sizeof(int);
579     return part1+part2;*/
580   return 0;
581 }
582
583 bool MEDFileFastCellSupportComparator::isEqual(const MEDFileAnyTypeFieldMultiTS *other) throw(INTERP_KERNEL::Exception)
584 {
585   int nbPts=other->getNumberOfTS();
586   if(nbPts!=(int)_f1ts_cmps.size())
587     {
588       std::ostringstream oss; oss << "MEDFileFastCellSupportComparator::isEqual : unexpected nb of time steps in  input ! Should be " << _f1ts_cmps.size() << " it is in reality " << nbPts << " !";
589       throw INTERP_KERNEL::Exception(oss.str().c_str());
590     }
591   for(int i=0;i<nbPts;i++)
592     {
593       MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TS> elt=other->getTimeStepAtPos(i);
594       if(!_f1ts_cmps[i]->isEqualConsideringThePast(elt,_mesh_comp))
595         if(!_f1ts_cmps[i]->isSupportSameAs(elt,_mesh_comp))
596           return false;
597     }
598   return true;
599 }
600
601 bool MEDFileFastCellSupportComparator::isCompatibleWithNodesDiscr(const MEDFileAnyTypeFieldMultiTS *other) throw(INTERP_KERNEL::Exception)
602 {
603   int nbPts=other->getNumberOfTS();
604   if(nbPts!=(int)_f1ts_cmps.size())
605     {
606       std::ostringstream oss; oss << "MEDFileFastCellSupportComparator::isCompatibleWithNodesDiscr : unexpected nb of time steps in  input ! Should be " << _f1ts_cmps.size() << " it is in reality " << nbPts << " !";
607       throw INTERP_KERNEL::Exception(oss.str().c_str());
608     }
609   for(int i=0;i<nbPts;i++)
610     {
611       MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TS> elt=other->getTimeStepAtPos(i);
612       if(!_f1ts_cmps[i]->isCompatibleWithNodesDiscr(elt,_mesh_comp))
613         return false;
614     }
615   return true;
616 }