Salome HOME
On the road of last imps for MEDReader
[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       (*it0).second.push_back(i);
326     }
327   if(m.size()==_items.size())
328     {
329       MEDFileField1TSStructItem ret(*this);
330       ret._type=ON_CELLS;
331       return ret;
332     }
333   std::size_t sz(m.size());
334   std::vector< MEDFileField1TSStructItem2 > items(sz);
335   for(i=0;i<sz;i++)
336     {
337       const std::vector<std::size_t>& ids=m[i].second;
338       std::vector<const MEDFileField1TSStructItem2 *>objs(ids.size());
339       for(std::size_t j=0;j<ids.size();j++)
340         objs[j]=&_items[j];
341       items[i]=MEDFileField1TSStructItem2::BuildAggregationOf(objs,globs);
342     }
343   MEDFileField1TSStructItem ret(ON_CELLS,items);
344   ret._computed=true;
345   return ret;
346 }
347
348 /*!
349  * \a this is expected to be ON_CELLS and simplified.
350  */
351 bool MEDFileField1TSStructItem::isCompatibleWithNodesDiscr(const MEDFileField1TSStructItem& other, const MEDFileMeshStruct *meshSt, const MEDFileFieldGlobs *globs) const throw(INTERP_KERNEL::Exception)
352 {
353   if(other._type!=ON_NODES)
354     throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::isCompatibleWithNodesDiscr : other must be on nodes !");
355   if(other._items.size()!=1)
356     throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::isCompatibleWithNodesDiscr : other is on nodes but number of subparts !");
357   int theFirstLevFull;
358   bool ret0=isFullyOnExactlyOneLev(meshSt,theFirstLevFull);
359   const MEDFileField1TSStructItem2& otherNodeIt(other._items[0]);
360   if(otherNodeIt.getPflName().empty())
361     {//on all nodes
362       if(!ret0)
363         return false;
364       return theFirstLevFull==0;
365     }
366   else
367     {
368       const DataArrayInt *pfl=globs->getProfile(otherNodeIt.getPflName().c_str());
369       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cpyPfl(pfl->deepCpy());
370       cpyPfl->sort();
371       int nbOfNodes(meshSt->getNumberOfNodes());
372       if(cpyPfl->isIdentity() && cpyPfl->getNumberOfTuples()==nbOfNodes)
373         {//on all nodes also !
374           if(!ret0)
375             return false;
376           return theFirstLevFull==0;
377         }
378       std::vector<bool> nodesFetched(nbOfNodes,false);
379       meshSt->getTheMesh()->whichAreNodesFetched(*this,globs,nodesFetched);
380       return cpyPfl->isFittingWith(nodesFetched);
381     }
382 }
383
384 bool MEDFileField1TSStructItem::isFullyOnExactlyOneLev(const MEDFileMeshStruct *meshSt, int& theFirstLevFull) const throw(INTERP_KERNEL::Exception)
385 {
386   if(_type!=ON_CELLS)
387     throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::isFullyOnExactlyOneLev : works only for ON_CELLS discretization !");
388   if(_items.empty())
389     throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::isFullyOnExactlyOneLev : items vector is empty !");
390   int nbOfLevs(meshSt->getNumberOfLevs());
391   if(nbOfLevs==0)
392     throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::isFullyOnExactlyOneLev : no levels in input mesh structure !");
393   theFirstLevFull=1;
394   int nbOfGT=0;
395   bool firstShot(true);
396   std::set<INTERP_KERNEL::NormalizedCellType> gts;
397   for(std::vector< MEDFileField1TSStructItem2 >::const_iterator it=_items.begin();it!=_items.end();it++)
398     {
399       if(!(*it).getPflName().empty())
400         return false;
401       INTERP_KERNEL::NormalizedCellType gt;
402       if(gts.find(gt)!=gts.end())
403         throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::isFullyOnExactlyOneLev : internal error !");
404       gts.insert(gt);
405       int pos(meshSt->getLevelOfGeoType((*it).getGeo()));
406       if(firstShot)
407         theFirstLevFull=pos;
408       else
409         if(theFirstLevFull!=pos)
410           return false;
411       firstShot=false;
412       nbOfGT++;
413     }
414   return nbOfGT==meshSt->getNumberOfGeoTypesInLev(theFirstLevFull);
415 }
416
417 const MEDFileField1TSStructItem2& MEDFileField1TSStructItem::operator[](std::size_t i) const throw(INTERP_KERNEL::Exception)
418 {
419   if(i<0 || i>=_items.size())
420     throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::operator[] : input is not in valid range !");
421   return _items[i];
422 }
423
424 //=
425
426 MEDFileField1TSStruct *MEDFileField1TSStruct::New(const MEDFileAnyTypeField1TS *ref) throw(INTERP_KERNEL::Exception)
427 {
428   return new MEDFileField1TSStruct(ref);
429 }
430
431 MEDFileField1TSStruct::MEDFileField1TSStruct(const MEDFileAnyTypeField1TS *ref)
432 {
433   _already_checked.push_back(BuildItemFrom(ref));
434 }
435
436 void MEDFileField1TSStruct::checkWithMeshStruct(MEDFileMeshStruct *mst, const MEDFileFieldGlobs *globs) throw(INTERP_KERNEL::Exception)
437 {
438   if(_already_checked.empty())
439     throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::checkWithMeshStruct : not correctly initialized !");
440   _already_checked.back().checkWithMeshStruct(mst,globs);
441 }
442
443 bool MEDFileField1TSStruct::isEqualConsideringThePast(const MEDFileAnyTypeField1TS *other) const throw(INTERP_KERNEL::Exception)
444 {
445   MEDFileField1TSStructItem b(BuildItemFrom(other));
446   for(std::vector<MEDFileField1TSStructItem>::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++)
447     {
448       if((*it)==b)
449         return true;
450     }
451   return false;
452 }
453
454 /*!
455  * Not const because \a other structure will be added to the \c _already_checked attribute in case of success.
456  */
457 bool MEDFileField1TSStruct::isSupportSameAs(const MEDFileAnyTypeField1TS *other) throw(INTERP_KERNEL::Exception)
458 {
459   if(_already_checked.empty())
460     throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::isSupportSameAs : no ref !");
461   MEDFileField1TSStructItem b(BuildItemFrom(other));
462   if(!_already_checked[0].isEntityCell() || !b.isEntityCell())
463     throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::isSupportSameAs : only available on cell entities !");
464   MEDFileField1TSStructItem other1(b.simplifyMeOnCellEntity(other->contentNotNull()));
465   int found=-1,i=0;
466   for(std::vector<MEDFileField1TSStructItem>::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++,i++)
467     if((*it).isComputed())
468       { found=i; break; }
469   bool ret(false);
470   if(found==-1)
471     {
472       MEDFileField1TSStructItem this1(_already_checked[0].simplifyMeOnCellEntity(other->contentNotNull()));
473       ret=this1.isCellSupportEqual(other1);
474       if(ret)
475         _already_checked.push_back(this1);
476     }
477   else
478     ret=_already_checked[found].isCellSupportEqual(other1);
479   if(ret)
480     _already_checked.push_back(b);
481   return ret;
482 }
483
484 bool MEDFileField1TSStruct::isCompatibleWithNodesDiscr(const MEDFileAnyTypeField1TS *other, const MEDFileMeshStruct *meshSt) throw(INTERP_KERNEL::Exception)
485 {
486   if(_already_checked.empty())
487     throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::isCompatibleWithNodesDiscr : no ref !");
488   if(!_already_checked[0].isEntityCell())
489     throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::isCompatibleWithNodesDiscr : only available on cell entities !");
490   MEDFileField1TSStructItem other1(BuildItemFrom(other));
491   //
492   int found=-1,i=0;
493   for(std::vector<MEDFileField1TSStructItem>::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++,i++)
494     if((*it).isComputed())
495       { found=i; break; }
496   bool ret(false);
497   if(found==-1)
498     {
499       MEDFileField1TSStructItem this1(_already_checked[0].simplifyMeOnCellEntity(other->contentNotNull()));
500       ret=this1.isCompatibleWithNodesDiscr(other1,meshSt,other->contentNotNull());
501       if(ret)
502         _already_checked.push_back(this1);
503     }
504   else
505     ret=_already_checked[found].isCompatibleWithNodesDiscr(other1,meshSt,other->contentNotNull());
506   return true;//tony
507 }
508
509 std::size_t MEDFileField1TSStruct::getHeapMemorySize() const
510 {
511   return 0;
512 }
513
514 MEDFileField1TSStructItem MEDFileField1TSStruct::BuildItemFrom(const MEDFileAnyTypeField1TS *ref)
515 {
516   TypeOfField atype;
517   std::vector< MEDFileField1TSStructItem2 > anItems;
518   //
519   std::vector< std::vector<std::string> > pfls,locs;
520   std::vector< std::vector<TypeOfField> > typesF;
521   std::vector<INTERP_KERNEL::NormalizedCellType> geoTypes;
522   std::vector< std::vector<std::pair<int,int> > > strtEnds=ref->getFieldSplitedByType(0,geoTypes,typesF,pfls,locs);
523   std::size_t nbOfGeoTypes(geoTypes.size());
524   if(nbOfGeoTypes==0)
525     throw INTERP_KERNEL::Exception("MEDFileField1TSStruct : not null by empty ref  !");
526   bool isFirst=true;
527   for(std::size_t i=0;i<nbOfGeoTypes;i++)
528     {
529       std::size_t sz=typesF.size();
530       if(strtEnds[i].size()<1 || sz<1 || pfls[i].size()<1)
531         throw INTERP_KERNEL::Exception("MEDFileField1TSStruct : internal error #1 !");
532       //
533       if(isFirst)
534         atype=typesF[i][0];
535       isFirst=false;
536       //
537       for(std::size_t j=0;j<sz;j++)
538         {
539           if(atype!=typesF[i][j])
540             anItems.push_back(MEDFileField1TSStructItem2(geoTypes[i],strtEnds[i][j],pfls[i][j],locs[i][j]));
541           else
542             throw INTERP_KERNEL::Exception("MEDFileField1TSStruct : can be applied only on single spatial discretization fields ! Call SplitPerDiscretization method !");
543         }
544     }
545   return MEDFileField1TSStructItem(atype,anItems);
546 }
547
548 //=
549
550 MEDFileFastCellSupportComparator *MEDFileFastCellSupportComparator::New(const MEDFileMesh *m, const MEDFileAnyTypeFieldMultiTS *ref) throw(INTERP_KERNEL::Exception)
551 {
552   return new MEDFileFastCellSupportComparator(m,ref);
553 }
554
555 MEDFileFastCellSupportComparator::MEDFileFastCellSupportComparator(const MEDFileMesh *m, const MEDFileAnyTypeFieldMultiTS *ref)
556 {
557   _mesh_comp=MEDFileMeshStruct::New(m);
558   int nbPts=ref->getNumberOfTS();
559   _f1ts_cmps.resize(nbPts);
560   for(int i=0;i<nbPts;i++)
561     {
562       MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TS> elt=ref->getTimeStepAtPos(i);
563       _f1ts_cmps[i]=MEDFileField1TSStruct::New(elt);
564       _f1ts_cmps[i]->checkWithMeshStruct(_mesh_comp,elt->contentNotNull());
565     }
566 }
567
568 std::size_t MEDFileFastCellSupportComparator::getHeapMemorySize() const
569 {
570   /*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>);
571   std::size_t part2=0;
572   for(std::vector< std::vector<int> >::const_iterator it=_already_passed_code1.begin();it!=_already_passed_code1.end();it++)
573     part2+=(*it).capacity()*(sizeof(int)+sizeof(const DataArrayInt *));
574   for(std::vector< std::vector<int> >::const_iterator it2=_m_geo_types_distrib.begin();it2!=_m_geo_types_distrib.end();it2++)
575     part2+=(*it2).capacity()*sizeof(int);
576     return part1+part2;*/
577   return 0;
578 }
579
580 bool MEDFileFastCellSupportComparator::isEqual(const MEDFileAnyTypeFieldMultiTS *other) throw(INTERP_KERNEL::Exception)
581 {
582   int nbPts=other->getNumberOfTS();
583   if(nbPts!=(int)_f1ts_cmps.size())
584     {
585       std::ostringstream oss; oss << "MEDFileFastCellSupportComparator::isEqual : unexpected nb of time steps in  input ! Should be " << _f1ts_cmps.size() << " it is in reality " << nbPts << " !";
586       throw INTERP_KERNEL::Exception(oss.str().c_str());
587     }
588   for(int i=0;i<nbPts;i++)
589     {
590       MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TS> elt=other->getTimeStepAtPos(i);
591       if(!_f1ts_cmps[i]->isEqualConsideringThePast(elt))
592         if(!_f1ts_cmps[i]->isSupportSameAs(elt))
593           return false;
594     }
595   return true;
596 }
597
598 bool MEDFileFastCellSupportComparator::isCompatibleWithNodesDiscr(const MEDFileAnyTypeFieldMultiTS *other) throw(INTERP_KERNEL::Exception)
599 {
600   int nbPts=other->getNumberOfTS();
601   if(nbPts!=(int)_f1ts_cmps.size())
602     {
603       std::ostringstream oss; oss << "MEDFileFastCellSupportComparator::isCompatibleWithNodesDiscr : unexpected nb of time steps in  input ! Should be " << _f1ts_cmps.size() << " it is in reality " << nbPts << " !";
604       throw INTERP_KERNEL::Exception(oss.str().c_str());
605     }
606   for(int i=0;i<nbPts;i++)
607     {
608       MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TS> elt=other->getTimeStepAtPos(i);
609       if(!_f1ts_cmps[i]->isCompatibleWithNodesDiscr(elt,_mesh_comp))
610         return false;
611     }
612   return true;
613 }