Salome HOME
d77b36f1387352ae4a93857b0c6c640b498a1dd1
[modules/med.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(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(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(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       if(!pfl->checkAllIdsInRange(0,nbOfEntity))
160         throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::checkInRange : The profile specified is invalid !");
161     }
162 }
163
164 bool MEDFileField1TSStructItem2::operator==(const MEDFileField1TSStructItem2& other) const throw(INTERP_KERNEL::Exception)
165 {
166   return _geo_type==other._geo_type && _start_end==other._start_end && _pfl->getName()==other._pfl->getName();
167 }
168
169 bool MEDFileField1TSStructItem2::isCellSupportEqual(const MEDFileField1TSStructItem2& other) const throw(INTERP_KERNEL::Exception)
170 {
171   if(_geo_type!=other._geo_type)
172     return false;
173   if(_nb_of_entity!=other._nb_of_entity)
174     return false;
175   if((_pfl->getName().empty() && !other._pfl->getName().empty()) || (!_pfl->getName().empty() && other._pfl->getName().empty()))
176     return false;
177   if(_pfl->getName().empty() && other._pfl->getName().empty())
178     return true;
179   return _pfl->isEqualWithoutConsideringStr(*other._pfl);
180 }
181
182 /*!
183  * \a objs must be non empty. \a objs should contain items having same geometric type.
184  */
185 MEDFileField1TSStructItem2 MEDFileField1TSStructItem2::BuildAggregationOf(const std::vector<const MEDFileField1TSStructItem2 *>& objs, const MEDFileFieldGlobs *globs) throw(INTERP_KERNEL::Exception)
186 {
187   if(objs.empty())
188     throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::BuildAggregationOf : empty input !");
189   if(objs.size()==1)
190     return MEDFileField1TSStructItem2(*objs[0]);
191   INTERP_KERNEL::NormalizedCellType gt(objs[0]->_geo_type);
192   int nbEntityRef(objs[0]->_nb_of_entity);
193   std::size_t sz(objs.size());
194   std::vector<const DataArrayInt *> arrs(sz);
195   for(std::size_t i=0;i<sz;i++)
196     {
197       const MEDFileField1TSStructItem2 *obj(objs[i]);
198       if(gt!=obj->_geo_type)
199         throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::BuildAggregationOf : invalid situation ! All input must have the same geo type !");
200       if(nbEntityRef!=obj->_nb_of_entity)
201         throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::BuildAggregationOf : invalid situation ! All input must have the global nb of entity !");
202       if(obj->_pfl->getName().empty())
203         throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::BuildAggregationOf : invalid situation ! Several same geo type chunk must all lie on profiles !");
204       arrs[i]=globs->getProfile(obj->_pfl->getName().c_str());
205       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr(DataArrayInt::Aggregate(arrs));
206       arr->sort();
207       int oldNbTuples(arr->getNumberOfTuples());
208       arr=arr->buildUnique();
209       if(oldNbTuples!=arr->getNumberOfTuples())
210         throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::BuildAggregationOf : some entities are present several times !");
211       if(arr->isIdentity() && oldNbTuples==nbEntityRef)
212         {
213           std::pair<int,int> p(0,nbEntityRef);
214           std::string a,b;
215           MEDFileField1TSStructItem2 ret(gt,p,a,b);
216           ret._nb_of_entity=nbEntityRef;
217           return ret;
218         }
219       else
220         {
221           arr->setName("???");
222           std::pair<int,int> p(0,oldNbTuples);
223           std::string a,b;
224           MEDFileField1TSStructItem2 ret(gt,p,a,b);
225           ret._nb_of_entity=nbEntityRef;
226           ret._pfl=arr;
227           return ret;
228         }
229     }
230 }
231
232 //=
233
234 MEDFileField1TSStructItem::MEDFileField1TSStructItem(TypeOfField a, const std::vector< MEDFileField1TSStructItem2 >& b):_computed(false),_type(a),_items(b)
235 {
236 }
237
238 void MEDFileField1TSStructItem::checkWithMeshStruct(MEDFileMeshStruct *mst, const MEDFileFieldGlobs *globs) throw(INTERP_KERNEL::Exception)
239 {
240   switch(_type)
241     {
242     case ON_NODES:
243       {
244         int nbOfEnt=mst->getNumberOfNodes();
245         if(_items.size()!=1)
246           throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::checkWithMeshStruct : for nodes field only one subdivision supported !");
247         _items[0].checkInRange(nbOfEnt,1,globs);
248         break ;
249       }
250     case ON_CELLS:
251       {
252         for(std::vector< MEDFileField1TSStructItem2 >::iterator it=_items.begin();it!=_items.end();it++)
253           (*it).checkWithMeshStructForCells(mst,globs);
254         break;
255       }
256     case ON_GAUSS_NE:
257       {
258         for(std::vector< MEDFileField1TSStructItem2 >::iterator it=_items.begin();it!=_items.end();it++)
259           (*it).checkWithMeshStructForGaussNE(mst,globs);
260         break;
261       }
262     case ON_GAUSS_PT:
263       {
264         for(std::vector< MEDFileField1TSStructItem2 >::iterator it=_items.begin();it!=_items.end();it++)
265           (*it).checkWithMeshStructForGaussPT(mst,globs);
266         break;
267       }
268     default:
269       throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::checkWithMeshStruct : not managed field type !");
270     }
271 }
272
273 bool MEDFileField1TSStructItem::operator==(const MEDFileField1TSStructItem& other) const throw(INTERP_KERNEL::Exception)
274 {
275   if(_type!=other._type)
276     return false;
277   if(_items.size()!=other._items.size())
278     return false;
279   for(std::size_t i=0;i<_items.size();i++)
280     if(!(_items[i]==other._items[i]))
281       return false;
282   return true;
283 }
284
285 bool MEDFileField1TSStructItem::isCellSupportEqual(const MEDFileField1TSStructItem& other) const throw(INTERP_KERNEL::Exception)
286 {
287   if(_type!=other._type)
288     return false;
289   if(_items.size()!=other._items.size())
290     return false;
291   for(std::size_t i=0;i<_items.size();i++)
292     if(!(_items[i].isCellSupportEqual(other._items[i])))
293       return false;
294   return true;
295 }
296
297 bool MEDFileField1TSStructItem::isEntityCell() const
298 {
299   if(_type==ON_NODES)
300     return false;
301   else
302     return true;
303 }
304
305 class CmpGeo
306 {
307 public:
308   CmpGeo(INTERP_KERNEL::NormalizedCellType geoTyp):_geo_type(geoTyp) { }
309   bool operator()(const std::pair< INTERP_KERNEL::NormalizedCellType, std::vector<std::size_t> > & v) const { return _geo_type==v.first; }
310 private:
311   INTERP_KERNEL::NormalizedCellType _geo_type;
312 };
313
314 MEDFileField1TSStructItem MEDFileField1TSStructItem::simplifyMeOnCellEntity(const MEDFileFieldGlobs *globs) const throw(INTERP_KERNEL::Exception)
315 {
316   if(!isEntityCell())
317     throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::simplifyMeOnCellEntity : must be on ON_CELLS, ON_GAUSS_NE or ON_GAUSS_PT !");
318   std::vector< std::pair< INTERP_KERNEL::NormalizedCellType, std::vector<std::size_t> > > m;
319   std::size_t i=0;
320   for(std::vector< MEDFileField1TSStructItem2 >::const_iterator it=_items.begin();it!=_items.end();it++,i++)
321     {
322       std::vector< std::pair< INTERP_KERNEL::NormalizedCellType, std::vector<std::size_t> > >::iterator it0(std::find_if(m.begin(),m.end(),CmpGeo((*it).getGeo())));
323       if(it0==m.end())
324         m.push_back(std::pair< INTERP_KERNEL::NormalizedCellType, std::vector<std::size_t> >((*it).getGeo(),std::vector<std::size_t>(1,i)));
325       else
326         (*it0).second.push_back(i);
327     }
328   if(m.size()==_items.size())
329     {
330       MEDFileField1TSStructItem ret(*this);
331       ret._type=ON_CELLS;
332       return ret;
333     }
334   std::size_t sz(m.size());
335   std::vector< MEDFileField1TSStructItem2 > items(sz);
336   for(i=0;i<sz;i++)
337     {
338       const std::vector<std::size_t>& ids=m[i].second;
339       std::vector<const MEDFileField1TSStructItem2 *>objs(ids.size());
340       for(std::size_t j=0;j<ids.size();j++)
341         objs[j]=&_items[j];
342       items[i]=MEDFileField1TSStructItem2::BuildAggregationOf(objs,globs);
343     }
344   MEDFileField1TSStructItem ret(ON_CELLS,items);
345   ret._computed=true;
346   return ret;
347 }
348
349 /*!
350  * \a this is expected to be ON_CELLS and simplified.
351  */
352 bool MEDFileField1TSStructItem::isCompatibleWithNodesDiscr(const MEDFileField1TSStructItem& other, const MEDFileMeshStruct *meshSt, const MEDFileFieldGlobs *globs) const throw(INTERP_KERNEL::Exception)
353 {
354   if(other._type!=ON_NODES)
355     throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::isCompatibleWithNodesDiscr : other must be on nodes !");
356   if(other._items.size()!=1)
357     throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::isCompatibleWithNodesDiscr : other is on nodes but number of subparts !");
358   int theFirstLevFull;
359   bool ret0=isFullyOnExactlyOneLev(meshSt,theFirstLevFull);
360   const MEDFileField1TSStructItem2& otherNodeIt(other._items[0]);
361   if(otherNodeIt.getPflName().empty())
362     {//on all nodes
363       if(!ret0)
364         return false;
365       return theFirstLevFull==0;
366     }
367   else
368     {
369       const DataArrayInt *pfl=globs->getProfile(otherNodeIt.getPflName().c_str());
370       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cpyPfl(pfl->deepCpy());
371       cpyPfl->sort();
372       int nbOfNodes(meshSt->getNumberOfNodes());
373       if(cpyPfl->isIdentity() && cpyPfl->getNumberOfTuples()==nbOfNodes)
374         {//on all nodes also !
375           if(!ret0)
376             return false;
377           return theFirstLevFull==0;
378         }
379       std::vector<bool> nodesFetched(nbOfNodes,false);
380       meshSt->getTheMesh()->whichAreNodesFetched(*this,globs,nodesFetched);
381       return cpyPfl->isFittingWith(nodesFetched);
382     }
383 }
384
385 bool MEDFileField1TSStructItem::isFullyOnExactlyOneLev(const MEDFileMeshStruct *meshSt, int& theFirstLevFull) const throw(INTERP_KERNEL::Exception)
386 {
387   if(_type!=ON_CELLS)
388     throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::isFullyOnExactlyOneLev : works only for ON_CELLS discretization !");
389   if(_items.empty())
390     throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::isFullyOnExactlyOneLev : items vector is empty !");
391   int nbOfLevs(meshSt->getNumberOfLevs());
392   if(nbOfLevs==0)
393     throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::isFullyOnExactlyOneLev : no levels in input mesh structure !");
394   theFirstLevFull=1;
395   int nbOfGT=0;
396   bool firstShot(true);
397   std::set<INTERP_KERNEL::NormalizedCellType> gts;
398   for(std::vector< MEDFileField1TSStructItem2 >::const_iterator it=_items.begin();it!=_items.end();it++)
399     {
400       if(!(*it).getPflName().empty())
401         return false;
402       INTERP_KERNEL::NormalizedCellType gt((*it).getGeo());
403       if(gts.find(gt)!=gts.end())
404         throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::isFullyOnExactlyOneLev : internal error !");
405       gts.insert(gt);
406       int pos(meshSt->getLevelOfGeoType((*it).getGeo()));
407       if(firstShot)
408         theFirstLevFull=pos;
409       else
410         if(theFirstLevFull!=pos)
411           return false;
412       firstShot=false;
413       nbOfGT++;
414     }
415   return nbOfGT==meshSt->getNumberOfGeoTypesInLev(theFirstLevFull);
416 }
417
418 const MEDFileField1TSStructItem2& MEDFileField1TSStructItem::operator[](std::size_t i) const throw(INTERP_KERNEL::Exception)
419 {
420   if(i<0 || i>=_items.size())
421     throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::operator[] : input is not in valid range !");
422   return _items[i];
423 }
424
425 //=
426
427 MEDFileField1TSStruct *MEDFileField1TSStruct::New(const MEDFileAnyTypeField1TS *ref) throw(INTERP_KERNEL::Exception)
428 {
429   return new MEDFileField1TSStruct(ref);
430 }
431
432 MEDFileField1TSStruct::MEDFileField1TSStruct(const MEDFileAnyTypeField1TS *ref)
433 {
434   _already_checked.push_back(BuildItemFrom(ref));
435 }
436
437 void MEDFileField1TSStruct::checkWithMeshStruct(MEDFileMeshStruct *mst, const MEDFileFieldGlobs *globs) throw(INTERP_KERNEL::Exception)
438 {
439   if(_already_checked.empty())
440     throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::checkWithMeshStruct : not correctly initialized !");
441   _already_checked.back().checkWithMeshStruct(mst,globs);
442 }
443
444 bool MEDFileField1TSStruct::isEqualConsideringThePast(const MEDFileAnyTypeField1TS *other) const throw(INTERP_KERNEL::Exception)
445 {
446   MEDFileField1TSStructItem b(BuildItemFrom(other));
447   for(std::vector<MEDFileField1TSStructItem>::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++)
448     {
449       if((*it)==b)
450         return true;
451     }
452   return false;
453 }
454
455 /*!
456  * Not const because \a other structure will be added to the \c _already_checked attribute in case of success.
457  */
458 bool MEDFileField1TSStruct::isSupportSameAs(const MEDFileAnyTypeField1TS *other) throw(INTERP_KERNEL::Exception)
459 {
460   if(_already_checked.empty())
461     throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::isSupportSameAs : no ref !");
462   MEDFileField1TSStructItem b(BuildItemFrom(other));
463   if(!_already_checked[0].isEntityCell() || !b.isEntityCell())
464     throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::isSupportSameAs : only available on cell entities !");
465   MEDFileField1TSStructItem other1(b.simplifyMeOnCellEntity(other->contentNotNull()));
466   int found=-1,i=0;
467   for(std::vector<MEDFileField1TSStructItem>::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++,i++)
468     if((*it).isComputed())
469       { found=i; break; }
470   bool ret(false);
471   if(found==-1)
472     {
473       MEDFileField1TSStructItem this1(_already_checked[0].simplifyMeOnCellEntity(other->contentNotNull()));
474       ret=this1.isCellSupportEqual(other1);
475       if(ret)
476         _already_checked.push_back(this1);
477     }
478   else
479     ret=_already_checked[found].isCellSupportEqual(other1);
480   if(ret)
481     _already_checked.push_back(b);
482   return ret;
483 }
484
485 bool MEDFileField1TSStruct::isCompatibleWithNodesDiscr(const MEDFileAnyTypeField1TS *other, const MEDFileMeshStruct *meshSt) throw(INTERP_KERNEL::Exception)
486 {
487   if(_already_checked.empty())
488     throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::isCompatibleWithNodesDiscr : no ref !");
489   if(!_already_checked[0].isEntityCell())
490     throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::isCompatibleWithNodesDiscr : only available on cell entities !");
491   MEDFileField1TSStructItem other1(BuildItemFrom(other));
492   //
493   int found=-1,i=0;
494   for(std::vector<MEDFileField1TSStructItem>::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++,i++)
495     if((*it).isComputed())
496       { found=i; break; }
497   bool ret(false);
498   if(found==-1)
499     {
500       MEDFileField1TSStructItem this1(_already_checked[0].simplifyMeOnCellEntity(other->contentNotNull()));
501       ret=this1.isCompatibleWithNodesDiscr(other1,meshSt,other->contentNotNull());
502       if(ret)
503         _already_checked.push_back(this1);
504     }
505   else
506     ret=_already_checked[found].isCompatibleWithNodesDiscr(other1,meshSt,other->contentNotNull());
507   if(ret)
508     _already_checked.push_back(other1);
509   return ret;
510 }
511
512 std::size_t MEDFileField1TSStruct::getHeapMemorySize() const
513 {
514   return 0;
515 }
516
517 MEDFileField1TSStructItem MEDFileField1TSStruct::BuildItemFrom(const MEDFileAnyTypeField1TS *ref)
518 {
519   TypeOfField atype;
520   std::vector< MEDFileField1TSStructItem2 > anItems;
521   //
522   std::vector< std::vector<std::string> > pfls,locs;
523   std::vector< std::vector<TypeOfField> > typesF;
524   std::vector<INTERP_KERNEL::NormalizedCellType> geoTypes;
525   std::vector< std::vector<std::pair<int,int> > > strtEnds=ref->getFieldSplitedByType(0,geoTypes,typesF,pfls,locs);
526   std::size_t nbOfGeoTypes(geoTypes.size());
527   if(nbOfGeoTypes==0)
528     throw INTERP_KERNEL::Exception("MEDFileField1TSStruct : not null by empty ref  !");
529   bool isFirst=true;
530   for(std::size_t i=0;i<nbOfGeoTypes;i++)
531     {
532       std::size_t sz=typesF[i].size();
533       if(strtEnds[i].size()<1 || sz<1 || pfls[i].size()<1)
534         throw INTERP_KERNEL::Exception("MEDFileField1TSStruct : internal error #1 !");
535       //
536       if(isFirst)
537         atype=typesF[i][0];
538       isFirst=false;
539       //
540       for(std::size_t j=0;j<sz;j++)
541         {
542           if(atype==typesF[i][j])
543             anItems.push_back(MEDFileField1TSStructItem2(geoTypes[i],strtEnds[i][j],pfls[i][j],locs[i][j]));
544           else
545             throw INTERP_KERNEL::Exception("MEDFileField1TSStruct : can be applied only on single spatial discretization fields ! Call SplitPerDiscretization method !");
546         }
547     }
548   return MEDFileField1TSStructItem(atype,anItems);
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);
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))
595         if(!_f1ts_cmps[i]->isSupportSameAs(elt))
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 }