]> SALOME platform Git repositories - modules/med.git/blob - src/MEDLoader/MEDFileFieldOverView.cxx
Salome HOME
6aeaa1ff59e04530dee707ba236ef53625947666
[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 const unsigned char MEDMeshMultiLev::PARAMEDMEM_2_VTKTYPE[MEDMeshMultiLev::PARAMEDMEM_2_VTKTYPE_LGTH]=
30   {1,3,21,5,9,7,22,34,23,28,255,255,255,255,10,14,13,255,12,255,24,255,16,27,255,26,255,29,255,255,25,42,255,4};
31
32 const char MEDFileField1TSStructItem2::NEWLY_CREATED_PFL_NAME[]="???";
33
34 MEDFileMeshStruct *MEDFileMeshStruct::New(const MEDFileMesh *mesh)
35 {
36   return new MEDFileMeshStruct(mesh);
37 }
38
39 std::size_t MEDFileMeshStruct::getHeapMemorySizeWithoutChildren() const
40 {
41   std::size_t ret(0);
42   for(std::vector< std::vector<int> >::const_iterator it0=_geo_types_distrib.begin();it0!=_geo_types_distrib.end();it0++)
43     ret+=(*it0).capacity()*sizeof(int);
44   ret+=_geo_types_distrib.capacity()*sizeof(std::vector<int>);
45   return ret;
46 }
47
48 std::vector<const BigMemoryObject *> MEDFileMeshStruct::getDirectChildren() const
49 {
50   return std::vector<const BigMemoryObject *>();
51 }
52
53 MEDFileMeshStruct::MEDFileMeshStruct(const MEDFileMesh *mesh):_mesh(mesh)
54 {
55   std::vector<int> levs=mesh->getNonEmptyLevels();
56   _name=mesh->getName();
57   _nb_nodes=mesh->getNumberOfNodes();
58   _geo_types_distrib.resize(levs.size());
59   for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
60     _geo_types_distrib[-(*lev)]=mesh->getDistributionOfTypes(*lev);
61 }
62
63 int MEDFileMeshStruct::getLevelOfGeoType(INTERP_KERNEL::NormalizedCellType t) const
64 {
65   int j=0;
66   for(std::vector< std::vector<int> >::const_iterator it1=_geo_types_distrib.begin();it1!=_geo_types_distrib.end();it1++,j--)
67     {
68       std::size_t sz=(*it1).size();
69       if(sz%3!=0)
70         throw INTERP_KERNEL::Exception("MEDFileMeshStruct::getLevelOfGeoType : internal error in code !");
71       std::size_t nbGeo=sz/3;
72       for(std::size_t i=0;i<nbGeo;i++)
73         if((*it1)[3*i]==(int)t)
74           return j;
75     }
76   throw INTERP_KERNEL::Exception("MEDFileMeshStruct::getLevelOfGeoType : The specified geometric type is not present in the mesh structure !");
77 }
78
79 int MEDFileMeshStruct::getNumberOfElemsOfGeoType(INTERP_KERNEL::NormalizedCellType t) const
80 {
81   for(std::vector< std::vector<int> >::const_iterator it1=_geo_types_distrib.begin();it1!=_geo_types_distrib.end();it1++)
82     {
83       std::size_t sz=(*it1).size();
84       if(sz%3!=0)
85         throw INTERP_KERNEL::Exception("MEDFileMeshStruct::getNumberOfElemsOfGeoType : internal error in code !");
86       std::size_t nbGeo=sz/3;
87       for(std::size_t i=0;i<nbGeo;i++)
88         if((*it1)[3*i]==(int)t)
89           return (*it1)[3*i+1];
90     }
91   throw INTERP_KERNEL::Exception("The specified geometric type is not present in the mesh structure !");
92 }
93
94 int MEDFileMeshStruct::getNumberOfLevs() const
95 {
96   return (int)_geo_types_distrib.size();
97 }
98
99 int MEDFileMeshStruct::getNumberOfGeoTypesInLev(int relativeLev) const
100 {
101   int pos(-relativeLev);
102   if(pos<0 || pos>=(int)_geo_types_distrib.size())
103     throw INTERP_KERNEL::Exception("MEDFileMeshStruct::getNumberOfGeoTypesInLev : invalid level specified !");
104   std::size_t sz=_geo_types_distrib[pos].size();
105   if(sz%3!=0)
106     throw INTERP_KERNEL::Exception("MEDFileMeshStruct::getNumberOfGeoTypesInLev : internal error in code !");
107   return (int)(sz/3);
108 }
109
110 //=
111
112 std::size_t MEDMeshMultiLev::getHeapMemorySizeWithoutChildren() const
113 {
114   return 0;
115 }
116
117 std::vector<const BigMemoryObject *> MEDMeshMultiLev::getDirectChildren() const
118 {
119   return std::vector<const BigMemoryObject *>();
120 }
121
122 MEDMeshMultiLev *MEDMeshMultiLev::New(const MEDFileMesh *m, const std::vector<int>& levs)
123 {
124   if(!m)
125     throw INTERP_KERNEL::Exception("MEDMeshMultiLev::New : null input pointer !");
126   const MEDFileUMesh *um(dynamic_cast<const MEDFileUMesh *>(m));
127   if(um)
128     return MEDUMeshMultiLev::New(um,levs);
129   const MEDFileCMesh *cm(dynamic_cast<const MEDFileCMesh *>(m));
130   if(cm)
131     return MEDCMeshMultiLev::New(cm,levs);
132   const MEDFileCurveLinearMesh *clm(dynamic_cast<const MEDFileCurveLinearMesh *>(m));
133   if(clm)
134     return MEDCurveLinearMeshMultiLev::New(clm,levs);
135   throw INTERP_KERNEL::Exception("MEDMeshMultiLev::New : unrecognized type of mesh ! Must be in [MEDFileUMesh,MEDFileCMesh,MEDFileCurveLinearMesh] !");
136 }
137
138 MEDMeshMultiLev *MEDMeshMultiLev::New(const MEDFileMesh *m, const std::vector<INTERP_KERNEL::NormalizedCellType>& gts, const std::vector<const DataArrayInt *>& pfls, const std::vector<int>& nbEntities)
139 {
140   if(!m)
141     throw INTERP_KERNEL::Exception("MEDMeshMultiLev::New 2 : null input pointer !");
142   const MEDFileUMesh *um(dynamic_cast<const MEDFileUMesh *>(m));
143   if(um)
144     return MEDUMeshMultiLev::New(um,gts,pfls,nbEntities);
145   const MEDFileCMesh *cm(dynamic_cast<const MEDFileCMesh *>(m));
146   if(cm)
147     return MEDCMeshMultiLev::New(cm,gts,pfls,nbEntities);
148   const MEDFileCurveLinearMesh *clm(dynamic_cast<const MEDFileCurveLinearMesh *>(m));
149   if(clm)
150     return MEDCurveLinearMeshMultiLev::New(clm,gts,pfls,nbEntities);
151   throw INTERP_KERNEL::Exception("MEDMeshMultiLev::New 2 : unrecognized type of mesh ! Must be in [MEDFileUMesh,MEDFileCMesh,MEDFileCurveLinearMesh] !");
152 }
153
154 MEDMeshMultiLev *MEDMeshMultiLev::NewOnlyOnNode(const MEDFileMesh *m, const DataArrayInt *pflOnNode)
155 {
156   std::vector<int> levs(1,0);
157   MEDCouplingAutoRefCountObjectPtr<MEDMeshMultiLev> ret(MEDMeshMultiLev::New(m,levs));
158   ret->selectPartOfNodes(pflOnNode);
159   return ret.retn();
160 }
161
162 void MEDMeshMultiLev::setNodeReduction(const DataArrayInt *nr)
163 {
164   if(nr)
165     nr->incrRef();
166   _node_reduction=const_cast<DataArrayInt*>(nr);
167 }
168
169 bool MEDMeshMultiLev::isFastlyTheSameStruct(const MEDFileField1TSStructItem& fst, const MEDFileFieldGlobsReal *globs) const
170 {
171   if(fst.getType()==ON_NODES)
172     {
173       if(fst.getNumberOfItems()!=1)
174         throw INTERP_KERNEL::Exception("MEDMeshMultiLev::isFastlyTheSameStruct : unexpected situation for nodes !");
175       const MEDFileField1TSStructItem2& p(fst[0]);
176       std::string pflName(p.getPflName());
177       const DataArrayInt *nr(_node_reduction);
178       if(pflName.empty() && !nr)
179         return true;
180       if(pflName==nr->getName())
181         return true;
182       return false;
183     }
184   else
185     {
186       std::size_t sz(fst.getNumberOfItems());
187       if(sz!=_geo_types.size())
188         return false;
189       int strt(0);
190       for(std::size_t i=0;i<sz;i++)
191         {
192           const MEDFileField1TSStructItem2& p(fst[i]);
193           if(!p.isFastlyEqual(strt,_geo_types[i],getPflNameOfId(i).c_str()))
194             return false;
195         }
196       return true;
197     }
198 }
199
200 DataArray *MEDMeshMultiLev::buildDataArray(const MEDFileField1TSStructItem& fst, const MEDFileFieldGlobsReal *globs, const DataArray *vals) const
201 {
202   MEDCouplingAutoRefCountObjectPtr<DataArray> ret(const_cast<DataArray *>(vals)); ret->incrRef();
203   if(isFastlyTheSameStruct(fst,globs))
204     return ret.retn();
205   else
206     return constructDataArray(fst,globs,vals);
207 }
208
209 /*!
210  * \param [out] famIds - Can be null. If not null the instance has to be dealt by the caller (decrRef).
211  * \param [out] isWithoutCopy - When true the returned instance \a famIds if not null is directly those in the data structure.
212  */
213 void MEDMeshMultiLev::retrieveFamilyIdsOnCells(DataArrayInt *& famIds, bool& isWithoutCopy) const
214 {
215   const DataArrayInt *fids(_cell_fam_ids);
216   if(!fids)
217     { famIds=0; isWithoutCopy=true; return ; }
218   std::size_t sz(_geo_types.size());
219   bool presenceOfPfls(false);
220   for(std::size_t i=0;i<sz && !presenceOfPfls;i++)
221     {
222       const DataArrayInt *pfl(_pfls[i]);
223       if(pfl)
224         presenceOfPfls=true;
225     }
226   if(!presenceOfPfls)
227     { famIds=const_cast<DataArrayInt *>(fids); famIds->incrRef(); isWithoutCopy=_cell_fam_ids_nocpy; return ; }
228   //bad luck the slowest part
229   isWithoutCopy=false;
230   std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > retSafe(sz);
231   std::vector< const DataArrayInt *> ret(sz);
232   int start(0);
233   for(std::size_t i=0;i<sz;i++)
234     {
235       const DataArrayInt *pfl(_pfls[i]);
236       int lgth(_nb_entities[i]);
237       if(pfl)
238         {
239           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp(fids->selectByTupleId2(start,start+lgth,1));
240           retSafe[i]=tmp->selectByTupleIdSafe(pfl->begin(),pfl->end());
241         }
242       else
243         {
244           retSafe[i]=fids->selectByTupleId2(start,start+lgth,1);
245         }
246       ret[i]=retSafe[i];
247       start+=lgth;
248     }
249   famIds=DataArrayInt::Aggregate(ret);
250 }
251
252 /*!
253  * \param [out] numIds - Can be null. If not null the instance has to be dealt by the caller (decrRef).
254  * \param [out] isWithoutCopy - When true the returned instance \a numIds if not null is directly those in the data structure.
255  */
256 void MEDMeshMultiLev::retrieveNumberIdsOnCells(DataArrayInt *& numIds, bool& isWithoutCopy) const
257 {
258   const DataArrayInt *nids(_cell_num_ids);
259   if(!nids)
260     { numIds=0; isWithoutCopy=true; return ; }
261   std::size_t sz(_geo_types.size());
262   bool presenceOfPfls(false);
263   for(std::size_t i=0;i<sz && !presenceOfPfls;i++)
264     {
265       const DataArrayInt *pfl(_pfls[i]);
266       if(pfl)
267         presenceOfPfls=true;
268     }
269   if(!presenceOfPfls)
270     { numIds=const_cast<DataArrayInt *>(nids); numIds->incrRef(); isWithoutCopy=_cell_num_ids_nocpy; return ; }
271   //bad luck the slowest part
272   isWithoutCopy=false;
273   std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > retSafe(sz);
274   std::vector< const DataArrayInt *> ret(sz);
275   int start(0);
276   for(std::size_t i=0;i<sz;i++)
277     {
278       const DataArrayInt *pfl(_pfls[i]);
279       int lgth(_nb_entities[i]);
280       if(pfl)
281         {
282           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp(nids->selectByTupleId2(start,start+lgth,1));
283           retSafe[i]=tmp->selectByTupleIdSafe(pfl->begin(),pfl->end());
284         }
285       else
286         {
287           retSafe[i]=nids->selectByTupleId2(start,start+lgth,1);
288         }
289       ret[i]=retSafe[i];
290       start+=lgth;
291     }
292   numIds=DataArrayInt::Aggregate(ret);
293 }
294
295 void MEDMeshMultiLev::setFamilyIdsOnCells(DataArrayInt *famIds, bool isNoCopy)
296 {
297   _cell_fam_ids=famIds;
298   if(famIds)
299     famIds->incrRef();
300   _cell_fam_ids_nocpy=isNoCopy;
301 }
302
303 void MEDMeshMultiLev::setNumberIdsOnCells(DataArrayInt *numIds, bool isNoCopy)
304 {
305   _cell_num_ids=numIds;
306   if(numIds)
307     numIds->incrRef();
308   _cell_num_ids_nocpy=isNoCopy;
309 }
310
311 std::string MEDMeshMultiLev::getPflNameOfId(int id) const
312 {
313   std::size_t sz(_pfls.size());
314   if(id<0 || id>=(int)sz)
315     throw INTERP_KERNEL::Exception("MEDMeshMultiLev::getPflNameOfId : invalid input id !");
316   const DataArrayInt *pfl(_pfls[id]);
317   if(!pfl)
318     return std::string("");
319   return pfl->getName();
320 }
321
322 /*!
323  * Returns the number of cells having geometric type \a t.
324  * The profiles are **NOT** taken into account here.
325  */
326 int MEDMeshMultiLev::getNumberOfCells(INTERP_KERNEL::NormalizedCellType t) const
327 {
328   std::size_t sz(_nb_entities.size());
329   for(std::size_t i=0;i<sz;i++)
330     if(_geo_types[i]==t)
331         return _nb_entities[i];
332   throw INTERP_KERNEL::Exception("MEDMeshMultiLev::getNumberOfCells : not existing geometric type in this !");
333 }
334
335 int MEDMeshMultiLev::getNumberOfNodes() const
336 {
337   return _nb_nodes;
338 }
339
340 DataArray *MEDMeshMultiLev::constructDataArray(const MEDFileField1TSStructItem& fst, const MEDFileFieldGlobsReal *globs, const DataArray *vals) const
341 {
342   if(fst.getType()==ON_NODES)
343     {
344       if(fst.getNumberOfItems()!=1)
345         throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for nodes !");
346       const MEDFileField1TSStructItem2& p(fst[0]);
347       std::string pflName(p.getPflName());
348       const DataArrayInt *nr(_node_reduction);
349       if(pflName.empty() && !nr)
350         return vals->deepCpy();
351       if(pflName.empty() && nr)
352          throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for nodes 2 !");
353       if(!pflName.empty() && nr)
354         {
355           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p1(globs->getProfile(pflName.c_str())->deepCpy());
356           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p2(nr->deepCpy());
357           p1->sort(true); p2->sort(true);
358           if(!p1->isEqualWithoutConsideringStr(*p2))
359             throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for nodes 3 !");
360           p1=DataArrayInt::FindPermutationFromFirstToSecond(globs->getProfile(pflName.c_str()),nr);
361           MEDCouplingAutoRefCountObjectPtr<DataArray> ret(vals->deepCpy());
362           ret->renumberInPlace(p1->begin());
363           return ret.retn();
364         }
365       if(!pflName.empty() && !nr)
366         {
367           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p1(globs->getProfile(pflName.c_str())->deepCpy());
368           p1->sort(true);
369           if(!p1->isIdentity() || p1->getNumberOfTuples()!=getNumberOfNodes())
370             throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for nodes 4 !");
371           MEDCouplingAutoRefCountObjectPtr<DataArray> ret(vals->deepCpy());
372           ret->renumberInPlace(globs->getProfile(pflName.c_str())->begin());
373           return ret.retn();
374         }
375       throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for nodes 5 !");
376     }
377   else
378     {
379       std::size_t sz(fst.getNumberOfItems());
380       std::set<INTERP_KERNEL::NormalizedCellType> s(_geo_types.begin(),_geo_types.end());
381       if(s.size()!=_geo_types.size())
382         throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for cells 2 !");
383       std::vector< const DataArray *> arr(s.size());
384       std::vector< MEDCouplingAutoRefCountObjectPtr<DataArray> > arrSafe(s.size());
385       int iii(0);
386       int nc(vals->getNumberOfComponents());
387       std::vector<std::string> compInfo(vals->getInfoOnComponents());
388       for(std::vector< INTERP_KERNEL::NormalizedCellType >::const_iterator it=_geo_types.begin();it!=_geo_types.end();it++,iii++)
389         {
390           const DataArrayInt *thisP(_pfls[iii]);
391           std::vector<const MEDFileField1TSStructItem2 *> ps;
392           for(std::size_t i=0;i<sz;i++)
393             {
394               const MEDFileField1TSStructItem2& p(fst[i]);
395               if(p.getGeo()==*it)
396                 ps.push_back(&p);
397             }
398           if(ps.empty())
399             throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for cells 1 !");
400           if(ps.size()==1)
401             {
402               int nbi(ps[0]->getNbOfIntegrationPts(globs));
403               const DataArrayInt *otherP(ps[0]->getPfl(globs));
404               const std::pair<int,int>& strtStop(ps[0]->getStartStop());
405               MEDCouplingAutoRefCountObjectPtr<DataArray> ret(vals->selectByTupleId2(strtStop.first,strtStop.second,1));
406               if(!thisP && !otherP)
407                 {
408                   arrSafe[iii]=ret; arr[iii]=ret;
409                   continue;
410                 }
411               if(thisP && otherP)
412                 {
413                   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p1(otherP->invertArrayN2O2O2N(getNumberOfCells(ps[0]->getGeo())));
414                   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p2(thisP->deepCpy());
415                   p2->transformWithIndArr(p1->begin(),p1->end());
416                   //p1=p2->getIdsNotEqual(-1);
417                   //p1=p2->selectByTupleIdSafe(p1->begin(),p1->end());
418                   ret->rearrange(nbi*nc); ret=ret->selectByTupleIdSafe(p2->begin(),p2->end()); ret->rearrange(nc); ret->setInfoOnComponents(compInfo);
419                   arrSafe[iii]=ret; arr[iii]=ret;
420                   continue;
421                 }
422               if(!thisP && otherP)
423                 {
424                   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p1(otherP->deepCpy());
425                   p1->sort(true);
426                   p1->checkAllIdsInRange(0,getNumberOfCells(ps[0]->getGeo()));
427                   p1=DataArrayInt::FindPermutationFromFirstToSecond(otherP,p1);
428                   ret->rearrange(nbi*nc); ret->renumberInPlace(p1->begin()); ret->rearrange(nc); ret->setInfoOnComponents(compInfo);
429                   arrSafe[iii]=ret; arr[iii]=ret;
430                   continue;
431                 }
432               throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for cells 3 !");
433             }
434           else
435             {
436               std::vector< const DataArrayInt * >otherPS(ps.size());
437               std::vector< const DataArray * > arr2(ps.size());
438               std::vector< MEDCouplingAutoRefCountObjectPtr<DataArray> > arr2Safe(ps.size());
439               std::vector< const DataArrayInt * > nbis(ps.size());
440               std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > nbisSafe(ps.size());
441               int jj(0);
442               for(std::vector<const MEDFileField1TSStructItem2 *>::const_iterator it2=ps.begin();it2!=ps.end();it2++,jj++)
443                 {
444                   int nbi((*it2)->getNbOfIntegrationPts(globs));
445                   const DataArrayInt *otherPfl((*it2)->getPfl(globs));
446                   const std::pair<int,int>& strtStop((*it2)->getStartStop());
447                   MEDCouplingAutoRefCountObjectPtr<DataArray> ret2(vals->selectByTupleId2(strtStop.first,strtStop.second,1));
448                   if(!otherPfl)
449                     throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for cells 4 !");
450                   arr2[jj]=ret2; arr2Safe[jj]=ret2; otherPS[jj]=otherPfl;
451                   nbisSafe[jj]=DataArrayInt::New(); nbisSafe[jj]->alloc(otherPfl->getNumberOfTuples(),1); nbisSafe[jj]->fillWithValue(nbi);
452                   nbis[jj]=nbisSafe[jj];
453                 }
454               MEDCouplingAutoRefCountObjectPtr<DataArray> arr3(DataArray::Aggregate(arr2));
455               MEDCouplingAutoRefCountObjectPtr<DataArrayInt> otherP(DataArrayInt::Aggregate(otherPS));
456               MEDCouplingAutoRefCountObjectPtr<DataArrayInt> zenbis(DataArrayInt::Aggregate(nbis));
457               MEDCouplingAutoRefCountObjectPtr<DataArrayInt> otherPN(otherP->invertArrayN2O2O2N(getNumberOfCells(*it)));
458               MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p1;
459               if(thisP)
460                 p1=DataArrayInt::FindPermutationFromFirstToSecond(otherP,thisP);
461               else
462                 p1=otherP->deepCpy();
463               MEDCouplingAutoRefCountObjectPtr<DataArrayInt> zenbisN(zenbis->renumber(p1->begin()));
464               zenbisN->computeOffsets2();
465               jj=0;
466               for(std::vector<const MEDFileField1TSStructItem2 *>::const_iterator it2=ps.begin();it2!=ps.end();it2++,jj++)
467                 {
468                   //int nbi((*it2)->getNbOfIntegrationPts(globs));
469                   const DataArrayInt *otherPfl((*it2)->getPfl(globs));
470                   const std::pair<int,int>& strtStop((*it2)->getStartStop());
471                   MEDCouplingAutoRefCountObjectPtr<DataArray> ret2(vals->selectByTupleId2(strtStop.first,strtStop.second,1));
472                   //
473                   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p2(otherPfl->deepCpy());
474                   p2->transformWithIndArr(otherPN->begin(),otherPN->end());
475                   p2->transformWithIndArr(p1->begin(),p1->end());
476                   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> idsN(p2->buildExplicitArrByRanges(zenbisN));
477                   arr3->setPartOfValuesBase3(ret2,idsN->begin(),idsN->end(),0,nc,1);
478                 }
479               arrSafe[iii]=arr3; arr[iii]=arr3;
480               continue;
481             }
482         }
483       return DataArray::Aggregate(arr);
484     }
485 }
486
487 MEDMeshMultiLev::MEDMeshMultiLev():_nb_nodes(0),_cell_fam_ids_nocpy(false)
488 {
489 }
490
491 MEDMeshMultiLev::MEDMeshMultiLev(int nbNodes, const std::vector<INTERP_KERNEL::NormalizedCellType>& gts, const std::vector<const DataArrayInt *>& pfls, const std::vector<int>& nbEntities):_geo_types(gts),_nb_entities(nbEntities),_nb_nodes(nbNodes),_cell_fam_ids_nocpy(false),_cell_num_ids_nocpy(false)
492 {
493   std::size_t sz(_geo_types.size());
494   if(sz!=pfls.size() || sz!=nbEntities.size())
495     throw INTERP_KERNEL::Exception("MEDMeshMultiLev::MEDMeshMultiLev : input vector must have the same size !");
496   _pfls.resize(sz);
497   for(std::size_t i=0;i<sz;i++)
498     {
499       if(pfls[i])
500         pfls[i]->incrRef();
501       _pfls[i]=const_cast<DataArrayInt *>(pfls[i]);
502     }
503 }
504
505 MEDMeshMultiLev::MEDMeshMultiLev(const MEDMeshMultiLev& other):RefCountObject(other),_pfls(other._pfls),_geo_types(other._geo_types),_nb_entities(other._nb_entities),_node_reduction(other._node_reduction),_nb_nodes(other._nb_nodes),_cell_fam_ids(other._cell_fam_ids),_cell_fam_ids_nocpy(other._cell_fam_ids_nocpy),_cell_num_ids(other._cell_num_ids),_cell_num_ids_nocpy(other._cell_num_ids_nocpy)
506 {
507 }
508
509 //=
510
511 MEDUMeshMultiLev *MEDUMeshMultiLev::New(const MEDFileUMesh *m, const std::vector<int>& levs)
512 {
513   return new MEDUMeshMultiLev(m,levs);
514 }
515
516 MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDFileUMesh *m, const std::vector<int>& levs)
517 {
518   if(!m)
519     throw INTERP_KERNEL::Exception("MEDUMeshMultiLev constructor : null input pointer !");
520   std::vector<MEDCoupling1GTUMesh *> v;
521   for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
522     {
523       std::vector<MEDCoupling1GTUMesh *> vTmp(m->getDirectUndergroundSingleGeoTypeMeshes(*it));
524       v.insert(v.end(),vTmp.begin(),vTmp.end());
525     }
526   std::size_t sz(v.size());
527   _parts.resize(sz);
528   _pfls.resize(sz);
529   _geo_types.resize(sz);
530   _nb_entities.resize(sz);
531   for(std::size_t i=0;i<sz;i++)
532     {
533       MEDCoupling1GTUMesh *obj(v[i]);
534       if(obj)
535         obj->incrRef();
536       else
537         throw INTERP_KERNEL::Exception("MEDUMeshMultiLev constructor : presence of a null pointer !");
538       _parts[i]=obj;
539       _geo_types[i]=obj->getCellModelEnum();
540       _nb_entities[i]=obj->getNumberOfCells();
541     }
542   // ids fields management
543   _cell_fam_ids_nocpy=(levs.size()==1);
544   if(_cell_fam_ids_nocpy)
545     {
546       const DataArrayInt *tmp(m->getFamilyFieldAtLevel(levs[0]));
547       if(tmp)
548         {
549           tmp->incrRef();
550           _cell_fam_ids=(const_cast<DataArrayInt *>(tmp));
551         }
552     }
553   else
554     {
555       std::vector<const DataArrayInt *> tmps(levs.size());
556       bool f(true);
557       for(std::size_t i=0;i<levs.size();i++)
558         {
559           tmps[i]=m->getFamilyFieldAtLevel(levs[i]);
560           if(!tmps[i])
561             f=false;
562         }
563       if(f)
564         _cell_fam_ids=DataArrayInt::Aggregate(tmps);
565     }
566   _cell_num_ids_nocpy=(levs.size()==1);
567   if(_cell_num_ids_nocpy)
568     {
569       const DataArrayInt *tmp(m->getNumberFieldAtLevel(levs[0]));
570       if(tmp)
571         {
572           tmp->incrRef();
573           _cell_num_ids=(const_cast<DataArrayInt *>(tmp));
574         }
575     }
576   else
577     {
578       std::vector<const DataArrayInt *> tmps(levs.size());
579       bool n(true);
580       for(std::size_t i=0;i<levs.size();i++)
581         {
582           tmps[i]=m->getNumberFieldAtLevel(levs[i]);
583           if(!tmps[i])
584             n=false;
585         }
586       if(n)
587         _cell_num_ids=DataArrayInt::Aggregate(tmps);
588     }
589 }
590
591 MEDUMeshMultiLev *MEDUMeshMultiLev::New(const MEDFileUMesh *m, const std::vector<INTERP_KERNEL::NormalizedCellType>& gts, const std::vector<const DataArrayInt *>& pfls, const std::vector<int>& nbEntities)
592 {
593   return new MEDUMeshMultiLev(m,gts,pfls,nbEntities);
594 }
595
596 MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDFileUMesh *m, const std::vector<INTERP_KERNEL::NormalizedCellType>& gts, const std::vector<const DataArrayInt *>& pfls, const std::vector<int>& nbEntities):MEDMeshMultiLev(m->getNumberOfNodes(),gts,pfls,nbEntities)
597 {
598   std::size_t sz(gts.size());
599   _parts.resize(sz);
600   for(std::size_t i=0;i<sz;i++)
601     {
602       MEDCoupling1GTUMesh *elt(m->getDirectUndergroundSingleGeoTypeMesh(gts[i]));
603       if(elt)
604         elt->incrRef();
605       _parts[i]=elt;
606     }
607   // ids fields management
608   _cell_fam_ids_nocpy=false;
609   std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > famIdsSafe(sz);
610   std::vector<const DataArrayInt *> famIds(sz);
611   bool f(true);
612   for(std::size_t i=0;i<sz;i++)
613     {
614       famIdsSafe[i]=m->extractFamilyFieldOnGeoType(gts[i]);
615       famIds[i]=famIdsSafe[i];
616       if(!famIds[i])
617         f=false;
618     }
619   if(f)
620     _cell_fam_ids=DataArrayInt::Aggregate(famIds);
621   _cell_num_ids_nocpy=false;
622   std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > numIdsSafe(sz);
623   std::vector<const DataArrayInt *> numIds(sz);
624   bool n(true);
625   for(std::size_t i=0;i<sz;i++)
626     {
627       numIdsSafe[i]=m->extractNumberFieldOnGeoType(gts[i]);
628       numIds[i]=numIdsSafe[i];
629       if(!numIds[i])
630         n=false;
631     }
632   if(n)
633     _cell_num_ids=DataArrayInt::Aggregate(numIds);
634 }
635
636 void MEDUMeshMultiLev::selectPartOfNodes(const DataArrayInt *pflNodes)
637 {
638    if(!pflNodes || !pflNodes->isAllocated())
639      return ;
640    std::size_t sz(_parts.size());
641    std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > a(sz);
642    std::vector< const DataArrayInt *> aa(sz);
643    for(std::size_t i=0;i<sz;i++)
644      {
645        
646        const DataArrayInt *pfl(_pfls[i]);
647        MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> m(_parts[i]);
648        if(pfl)
649          m=dynamic_cast<MEDCoupling1GTUMesh *>(_parts[i]->buildPartOfMySelfKeepCoords(pfl->begin(),pfl->end()));
650        DataArrayInt *cellIds=0;
651        m->fillCellIdsToKeepFromNodeIds(pflNodes->begin(),pflNodes->end(),true,cellIds);
652        MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIdsSafe(cellIds);
653        MEDCouplingAutoRefCountObjectPtr<MEDCouplingPointSet> m2(m->buildPartOfMySelfKeepCoords(cellIds->begin(),cellIds->end()));
654        int tmp=-1;
655        MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n(m2->getNodeIdsInUse(tmp));
656        a[i]=o2n->invertArrayO2N2N2O(tmp); aa[i]=a[i];
657        if(pfl)
658          _pfls[i]=pfl->selectByTupleIdSafe(cellIds->begin(),cellIds->end());
659        else
660          _pfls[i]=cellIdsSafe;
661      }
662    _node_reduction=DataArrayInt::Aggregate(aa);
663    _node_reduction->sort(true);
664    _node_reduction=_node_reduction->buildUnique();
665 }
666
667 MEDMeshMultiLev *MEDUMeshMultiLev::prepare() const
668 {
669   return new MEDUMeshMultiLev(*this);
670 }
671
672 MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDUMeshMultiLev& other):MEDMeshMultiLev(other),_parts(other._parts)
673 {
674 }
675
676 MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDStructuredMeshMultiLev& other, const MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh>& part):MEDMeshMultiLev(other)
677 {
678   _parts.resize(1);
679   _parts[0]=part;
680   _geo_types.resize(1); _geo_types[0]=part->getCellModelEnum();
681   _nb_entities.resize(1); _nb_entities[0]=part->getNumberOfCells();
682   _pfls.resize(1); _pfls[0]=0;
683 }
684
685 /*! 
686  * If returned value is false output pointer \a coords is not the internal pointer. If returned value is true output pointer \a coords is directly the internal pointer.
687  * If true is returned, the \a coords output parameter should be used with care (non const method call) to avoid to change the internal state of MEDFileUMesh instance.
688  */
689 bool MEDUMeshMultiLev::buildVTUArrays(DataArrayDouble *& coords, DataArrayByte *&types, DataArrayInt *&cellLocations, DataArrayInt *& cells, DataArrayInt *&faceLocations, DataArrayInt *&faces) const
690 {
691   if(_parts.empty())
692     throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::getVTUArrays : empty array !");
693   if(!(const MEDCoupling1GTUMesh *)_parts[0])
694     throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::getVTUArrays : first part is null !");
695   const DataArrayDouble *tmp(_parts[0]->getCoords());
696   if(!tmp)
697     throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::getVTUArrays : the coordinates are null !");
698   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> a(const_cast<DataArrayDouble *>(tmp)); tmp->incrRef();
699   int szBCE(0),szD(0),szF(0);
700   bool isPolyh(false);
701   int iii(0);
702   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> >::const_iterator it=_parts.begin();it!=_parts.end();it++,iii++)
703     {
704       const MEDCoupling1GTUMesh *cur(*it);
705       if(!cur)
706         throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::getVTUArrays : a part is null !");
707       //
708       const DataArrayInt *pfl(_pfls[iii]);
709       MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> cur2;
710       if(!pfl)
711         { cur2=const_cast<MEDCoupling1GTUMesh *>(cur); cur2->incrRef(); }
712       else
713         { cur2=dynamic_cast<MEDCoupling1GTUMesh *>(cur->buildPartOfMySelfKeepCoords(pfl->begin(),pfl->end())); cur=cur2; }
714       //
715       int curNbCells(cur->getNumberOfCells());
716       szBCE+=curNbCells;
717       if((*it)->getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
718         szD+=cur->getNodalConnectivity()->getNumberOfTuples()+curNbCells;
719       else
720         {
721           isPolyh=true;
722           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp2(cur->computeEffectiveNbOfNodesPerCell());
723           szD+=tmp2->accumulate(0)+curNbCells;
724           szF+=2*curNbCells+cur->getNodalConnectivity()->getNumberOfTuples();
725         }
726     }
727   MEDCouplingAutoRefCountObjectPtr<DataArrayByte> b(DataArrayByte::New()); b->alloc(szBCE,1); char *bPtr(b->getPointer());
728   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(DataArrayInt::New()); c->alloc(szBCE,1); int *cPtr(c->getPointer());
729   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d(DataArrayInt::New()); d->alloc(szD,1); int *dPtr(d->getPointer());
730   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> e(DataArrayInt::New()),f(DataArrayInt::New()); int *ePtr(0),*fPtr(0);
731   if(isPolyh)
732     { e->alloc(szBCE,1); ePtr=e->getPointer(); f->alloc(szF,1); fPtr=f->getPointer(); }
733   int k(0);
734   iii=0;
735   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> >::const_iterator it=_parts.begin();it!=_parts.end();it++,iii++)
736     {
737       const MEDCoupling1GTUMesh *cur(*it);
738       //
739       const DataArrayInt *pfl(_pfls[iii]);
740       MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> cur2;
741       if(!pfl)
742         { cur2=const_cast<MEDCoupling1GTUMesh *>(cur); cur2->incrRef(); }
743       else
744         { cur2=dynamic_cast<MEDCoupling1GTUMesh *>(cur->buildPartOfMySelfKeepCoords(pfl->begin(),pfl->end())); cur=cur2; }
745       //
746       int curNbCells(cur->getNumberOfCells());
747       int gt((int)cur->getCellModelEnum());
748       if(gt<0 || gt>=PARAMEDMEM_2_VTKTYPE_LGTH)
749         throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::getVTUArrays : invalid geometric type !");
750       unsigned char gtvtk(PARAMEDMEM_2_VTKTYPE[gt]);
751       if(gtvtk==255)
752         throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::getVTUArrays : no VTK type for the requested INTERP_KERNEL geometric type !");
753       std::fill(bPtr,bPtr+curNbCells,gtvtk); bPtr+=curNbCells;
754       const MEDCoupling1SGTUMesh *scur(dynamic_cast<const MEDCoupling1SGTUMesh *>(cur));
755       const MEDCoupling1DGTUMesh *dcur(dynamic_cast<const MEDCoupling1DGTUMesh *>(cur));
756       const int *connPtr(cur->getNodalConnectivity()->begin());
757       if(!scur && !dcur)
758         throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::getVTUArrays : internal error !");
759       if(scur)
760         {
761           int nnpc(scur->getNumberOfNodesPerCell());
762           for(int i=0;i<curNbCells;i++,connPtr+=nnpc)
763             {
764               *dPtr++=nnpc;
765               dPtr=std::copy(connPtr,connPtr+nnpc,dPtr);
766               *cPtr=k+nnpc; k=*cPtr++;
767             }
768           if(isPolyh)
769             { std::fill(ePtr,ePtr+curNbCells,-1); ePtr+=curNbCells; }
770         }
771       else
772         {
773           const int *connIPtr(dcur->getNodalConnectivityIndex()->begin());
774           if(cur->getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
775             {
776               for(int i=0;i<curNbCells;i++,connIPtr++)
777                 {
778                   *dPtr++=connIPtr[1]-connIPtr[0];
779                   dPtr=std::copy(connPtr+connIPtr[0],connPtr+connIPtr[1],dPtr);
780                   *cPtr=k+connIPtr[1]-connIPtr[0]; k=*cPtr++;
781                 }
782             }
783           else
784             {
785               for(int i=0;i<curNbCells;i++,connIPtr++)
786                 {
787                   std::set<int> s(connPtr+connIPtr[0],connPtr+connIPtr[1]); s.erase(-1);
788                   *dPtr++=(int)s.size();
789                   dPtr=std::copy(s.begin(),s.end(),dPtr);
790                   *cPtr=k+(int)s.size(); k=*cPtr++;
791                 }
792             }
793           if(isPolyh)
794             {
795               connIPtr=dcur->getNodalConnectivityIndex()->begin();
796               if(cur->getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
797                 { std::fill(ePtr,ePtr+curNbCells,-1); ePtr+=curNbCells; }
798               else
799                 {
800                   int kk(0);
801                   for(int i=0;i<curNbCells;i++,connIPtr++)
802                     {
803                       int nbFace(std::count(connPtr+connIPtr[0],connPtr+connIPtr[1],-1)+1);
804                       *fPtr++=nbFace;
805                       const int *work(connPtr+connIPtr[0]);
806                       for(int j=0;j<nbFace;j++)
807                         {
808                           const int *work2=std::find(work,connPtr+connIPtr[1],-1);
809                           *fPtr++=std::distance(work,work2);
810                           fPtr=std::copy(work,work2,fPtr);
811                           work=work2+1;
812                         }
813                       *ePtr++=kk; kk+=connIPtr[1]-connIPtr[0]+2;
814                     }
815                 }
816             }
817         }
818     }
819   if(!isPolyh)
820     reorderNodesIfNecessary(a,d,0);
821   else
822     reorderNodesIfNecessary(a,d,f);
823   if(a->getNumberOfComponents()!=3)
824     a=a->changeNbOfComponents(3,0.);
825   coords=a.retn(); types=b.retn(); cellLocations=c.retn(); cells=d.retn();
826   if(!isPolyh)
827     { faceLocations=0; faces=0; }
828   else
829     { faceLocations=e.retn(); faces=f.retn(); }
830   return tmp==((DataArrayDouble *)a);
831 }
832
833 void MEDUMeshMultiLev::reorderNodesIfNecessary(MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>& coords, DataArrayInt *nodalConnVTK, DataArrayInt *polyhedNodalConnVTK) const
834 {
835   const DataArrayInt *nr(_node_reduction);
836   if(!nr)
837     return ;
838   int sz(coords->getNumberOfTuples());
839   std::vector<bool> b(sz,false);
840   const int *work(nodalConnVTK->begin()),*endW(nodalConnVTK->end());
841   while(work!=endW)
842     {
843       int nb(*work++);
844       for(int i=0;i<nb && work!=endW;i++,work++)
845         {
846           if(*work>=0 && *work<sz)
847             b[*work]=true;
848           else
849             throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::reorderNodesIfNecessary : internal error !");
850         }
851     }
852   if(polyhedNodalConnVTK)
853     {
854       work=polyhedNodalConnVTK->begin(); endW=polyhedNodalConnVTK->end();
855       while(work!=endW)
856         {
857           int nb(*work++);
858           for(int i=0;i<nb && work!=endW;i++)
859             {
860               int nb2(*work++);
861               for(int j=0;j<nb2 && work!=endW;j++,work++)
862                 {
863                   if(*work>=0 && *work<sz)
864                     b[*work]=true;
865                   else
866                     throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::reorderNodesIfNecessary : internal error #2 !");
867                 }
868             }
869         }
870     }
871   int szExp(std::count(b.begin(),b.end(),true));
872   if(szExp!=nr->getNumberOfTuples())
873     throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::reorderNodesIfNecessary : internal error #3 !");
874   // Go renumbering !
875   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n(DataArrayInt::New()); o2n->alloc(sz,1);
876   int *o2nPtr(o2n->getPointer());
877   int newId(0);
878   for(int i=0;i<sz;i++,o2nPtr++)
879     if(b[i]) *o2nPtr=newId++; else *o2nPtr=-1;
880   const int *o2nPtrc(o2n->begin());
881   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> n2o(o2n->invertArrayO2N2N2O(nr->getNumberOfTuples()));
882   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> perm(DataArrayInt::FindPermutationFromFirstToSecond(n2o,nr));
883   const int *permPtr(perm->begin());
884   int *work2(nodalConnVTK->getPointer()),*endW2(nodalConnVTK->getPointer()+nodalConnVTK->getNumberOfTuples());
885   while(work2!=endW2)
886     {
887       int nb(*work2++);
888       for(int i=0;i<nb && work2!=endW2;i++,work2++)
889         *work2=permPtr[o2nPtrc[*work2]];
890     }
891   if(polyhedNodalConnVTK)
892     {
893       work2=polyhedNodalConnVTK->getPointer(); endW2=polyhedNodalConnVTK->getPointer()+polyhedNodalConnVTK->getNumberOfTuples();
894       while(work2!=endW2)
895         {
896           int nb(*work2++);
897           for(int i=0;i<nb && work2!=endW2;i++)
898             {
899               int nb2(*work2++);
900               for(int j=0;j<nb2 && work2!=endW2;j++,work2++)
901                 *work2=permPtr[o2nPtrc[*work2]];
902             }
903         }
904     }
905   coords=(coords->selectByTupleIdSafe(nr->begin(),nr->end()));
906 }
907
908 //=
909
910 MEDStructuredMeshMultiLev::MEDStructuredMeshMultiLev()
911 {
912 }
913
914 MEDStructuredMeshMultiLev::MEDStructuredMeshMultiLev(int nbOfNodes, const std::vector<INTERP_KERNEL::NormalizedCellType>& gts, const std::vector<const DataArrayInt *>& pfls, const std::vector<int>& nbEntities):MEDMeshMultiLev(nbOfNodes,gts,pfls,nbEntities)
915 {
916 }
917
918 void MEDStructuredMeshMultiLev::selectPartOfNodes(const DataArrayInt *pflNodes)
919 {
920   if(!pflNodes || !pflNodes->isAllocated())
921     return ;
922   std::vector<int> ngs(getNodeGridStructure());
923   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(MEDCouplingStructuredMesh::Build1GTNodalConnectivity(&ngs[0],&ngs[0]+ngs.size()));
924   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> m(MEDCoupling1SGTUMesh::New("",MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(ngs.size())));
925   m->setNodalConnectivity(conn);
926   const DataArrayInt *pfl(_pfls[0]);
927   if(pfl)
928     {
929       m=dynamic_cast<MEDCoupling1SGTUMesh *>(m->buildPartOfMySelfKeepCoords(pfl->begin(),pfl->end()));
930     }
931   DataArrayInt *cellIds=0;
932   m->fillCellIdsToKeepFromNodeIds(pflNodes->begin(),pflNodes->end(),true,cellIds);
933   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIdsSafe(cellIds);
934   MEDCouplingAutoRefCountObjectPtr<MEDCouplingPointSet> m2(m->buildPartOfMySelfKeepCoords(cellIds->begin(),cellIds->end()));
935   int tmp=-1;
936   _node_reduction=m2->getNodeIdsInUse(tmp);
937   if(pfl)
938     _pfls[0]=pfl->selectByTupleIdSafe(cellIds->begin(),cellIds->end());
939   else
940     _pfls[0]=cellIdsSafe;
941 }
942
943 MEDStructuredMeshMultiLev::MEDStructuredMeshMultiLev(const MEDStructuredMeshMultiLev& other):MEDMeshMultiLev(other)
944 {
945 }
946
947 //=
948
949 MEDCMeshMultiLev *MEDCMeshMultiLev::New(const MEDFileCMesh *m, const std::vector<int>& levs)
950 {
951   return new MEDCMeshMultiLev(m,levs);
952 }
953
954 MEDCMeshMultiLev *MEDCMeshMultiLev::New(const MEDFileCMesh *m, const std::vector<INTERP_KERNEL::NormalizedCellType>& gts, const std::vector<const DataArrayInt *>& pfls, const std::vector<int>& nbEntities)
955 {
956   return new MEDCMeshMultiLev(m,gts,pfls,nbEntities);
957 }
958
959 MEDCMeshMultiLev::MEDCMeshMultiLev(const MEDFileCMesh *m, const std::vector<int>& levs)
960 {
961   if(!m)
962     throw INTERP_KERNEL::Exception("MEDCMeshMultiLev constructor : null input pointer !");
963   if(levs.size()!=1 || levs[0]!=0)
964     throw INTERP_KERNEL::Exception("MEDCMeshMultiLev constructor : levels supported is 0 only !");
965   int mdim(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(m->getMeshDimension()));
966   _coords.resize(mdim);
967   for(int i=0;i<mdim;i++)
968     {
969       DataArrayDouble *elt(const_cast<DataArrayDouble *>(m->getMesh()->getCoordsAt(i)));
970       if(!elt)
971         throw INTERP_KERNEL::Exception("MEDCMeshMultiLev constructor 2 : presence of null pointer for an vector of double along an axis !");
972       _coords[i]=elt;
973     }
974   // ids fields management
975   _cell_fam_ids_nocpy=true; _cell_num_ids_nocpy=true;
976   const DataArrayInt *tmp(0);
977   tmp=m->getFamilyFieldAtLevel(0);
978   if(tmp)
979     {
980       tmp->incrRef();
981       _cell_fam_ids=const_cast<DataArrayInt *>(tmp);
982     }
983   tmp=m->getNumberFieldAtLevel(0);
984   if(tmp)
985     {
986       tmp->incrRef();
987       _cell_num_ids=const_cast<DataArrayInt *>(tmp);
988     }
989 }
990
991 MEDCMeshMultiLev::MEDCMeshMultiLev(const MEDFileCMesh *m, const std::vector<INTERP_KERNEL::NormalizedCellType>& gts, const std::vector<const DataArrayInt *>& pfls, const std::vector<int>& nbEntities):MEDStructuredMeshMultiLev(m->getNumberOfNodes(),gts,pfls,nbEntities)
992 {
993   if(!m)
994     throw INTERP_KERNEL::Exception("MEDCMeshMultiLev constructor 2 : null input pointer !");
995   if(gts.size()!=1 || pfls.size()!=1)
996     throw INTERP_KERNEL::Exception("MEDCMeshMultiLev constructor 2 : lengthes of gts and pfls must be equal to one !");
997   int mdim(m->getMeshDimension());
998   INTERP_KERNEL::NormalizedCellType gt(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(mdim));
999   if(gt!=gts[0])
1000     throw INTERP_KERNEL::Exception("MEDCMeshMultiLev constructor 2 : the unique geo type is invalid regarding meshdim !");
1001   _coords.resize(mdim);
1002   for(int i=0;i<mdim;i++)
1003     {
1004       DataArrayDouble *elt(const_cast<DataArrayDouble *>(m->getMesh()->getCoordsAt(i)));
1005       if(!elt)
1006         throw INTERP_KERNEL::Exception("MEDCMeshMultiLev constructor 2 : presence of null pointer for an vector of double along an axis !");
1007       _coords[i]=elt; _coords[i]->incrRef();
1008     }
1009   // ids fields management
1010   _cell_fam_ids_nocpy=true; _cell_num_ids_nocpy=true;
1011   const DataArrayInt *tmp(0);
1012   tmp=m->getFamilyFieldAtLevel(0);
1013   if(tmp)
1014     {
1015       tmp->incrRef();
1016       _cell_fam_ids=const_cast<DataArrayInt *>(tmp);
1017     }
1018   tmp=m->getNumberFieldAtLevel(0);
1019   if(tmp)
1020     {
1021       tmp->incrRef();
1022       _cell_num_ids=const_cast<DataArrayInt *>(tmp);
1023     }
1024 }
1025
1026 MEDCMeshMultiLev::MEDCMeshMultiLev(const MEDCMeshMultiLev& other):MEDStructuredMeshMultiLev(other),_coords(other._coords)
1027 {
1028 }
1029
1030 std::vector<int> MEDCMeshMultiLev::getNodeGridStructure() const
1031 {
1032   std::vector<int> ret(_coords.size());
1033   for(std::size_t i=0;i<_coords.size();i++)
1034     ret[i]=_coords[i]->getNumberOfTuples();
1035   return ret;
1036 }
1037
1038 MEDMeshMultiLev *MEDCMeshMultiLev::prepare() const
1039 {
1040   const DataArrayInt *pfl(_pfls[0]),*nr(_node_reduction);
1041   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nnr;
1042   std::vector<int> cgs,ngs(getNodeGridStructure());
1043   cgs.resize(ngs.size());
1044   std::transform(ngs.begin(),ngs.end(),cgs.begin(),std::bind2nd(std::plus<int>(),-1));
1045   if(pfl)
1046     {
1047       std::vector< std::pair<int,int> > cellParts;
1048       MEDCouplingAutoRefCountObjectPtr<MEDMeshMultiLev> ret2;
1049       if(MEDCouplingStructuredMesh::IsPartStructured(pfl->begin(),pfl->end(),cgs,cellParts))
1050         {
1051           MEDCouplingAutoRefCountObjectPtr<MEDCMeshMultiLev> ret(new MEDCMeshMultiLev(*this));
1052           if(nr)
1053             { nnr=nr->deepCpy(); nnr->sort(true); ret->setNodeReduction(nnr); }
1054           ret->_nb_entities[0]=pfl->getNumberOfTuples();
1055           ret->_pfls[0]=0;
1056           std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> > coords(_coords.size());
1057           for(std::size_t i=0;i<_coords.size();i++)
1058             coords[i]=_coords[i]->selectByTupleId2(cellParts[i].first,cellParts[i].second+1,1);
1059           ret->_coords=coords;
1060           ret2=(MEDCMeshMultiLev *)ret; ret2->incrRef();
1061         }
1062       else
1063         {
1064           MEDCouplingAutoRefCountObjectPtr<MEDCouplingCMesh> m(MEDCouplingCMesh::New());
1065           for(std::size_t i=0;i<ngs.size();i++)
1066             m->setCoordsAt(i,_coords[i]);
1067           MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> m2(m->build1SGTUnstructured());
1068           MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> m3=dynamic_cast<MEDCoupling1GTUMesh *>(m2->buildPartOfMySelfKeepCoords(pfl->begin(),pfl->end()));
1069           MEDCouplingAutoRefCountObjectPtr<MEDUMeshMultiLev> ret(new MEDUMeshMultiLev(*this,m3));
1070           if(nr)
1071             { m3->zipCoords(); nnr=nr->deepCpy(); nnr->sort(true); ret->setNodeReduction(nnr); }
1072           ret2=(MEDUMeshMultiLev *)ret; ret2->incrRef();
1073         }
1074       const DataArrayInt *famIds(_cell_fam_ids),*numIds(_cell_num_ids);
1075       if(famIds)
1076         {
1077           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp(famIds->selectByTupleIdSafe(pfl->begin(),pfl->end()));
1078           ret2->setFamilyIdsOnCells(tmp,false);
1079         }
1080       if(numIds)
1081         {
1082           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp(numIds->selectByTupleIdSafe(pfl->begin(),pfl->end()));
1083           ret2->setNumberIdsOnCells(tmp,false);
1084         }
1085       return ret2.retn();
1086       
1087     }
1088   else
1089     {
1090       MEDCouplingAutoRefCountObjectPtr<MEDCMeshMultiLev> ret(new MEDCMeshMultiLev(*this));
1091       if(nr)
1092         { nnr=nr->deepCpy(); nnr->sort(true); ret->setNodeReduction(nnr); }
1093       return ret.retn();
1094     }
1095 }
1096
1097 std::vector< DataArrayDouble * > MEDCMeshMultiLev::buildVTUArrays() const
1098 {
1099   std::size_t sz(_coords.size());
1100   std::vector< DataArrayDouble * > ret(sz);
1101   for(std::size_t i=0;i<sz;i++)
1102     {
1103       ret[i]=const_cast<DataArrayDouble *>((const DataArrayDouble *)_coords[i]);
1104       ret[i]->incrRef();
1105     }
1106   return ret;
1107 }
1108
1109 //=
1110
1111 MEDCurveLinearMeshMultiLev *MEDCurveLinearMeshMultiLev::New(const MEDFileCurveLinearMesh *m, const std::vector<int>& levs)
1112 {
1113   return new MEDCurveLinearMeshMultiLev(m,levs);
1114 }
1115
1116 MEDCurveLinearMeshMultiLev *MEDCurveLinearMeshMultiLev::New(const MEDFileCurveLinearMesh *m, const std::vector<INTERP_KERNEL::NormalizedCellType>& gts, const std::vector<const DataArrayInt *>& pfls, const std::vector<int>& nbEntities)
1117 {
1118   return new MEDCurveLinearMeshMultiLev(m,gts,pfls,nbEntities);
1119 }
1120
1121 MEDCurveLinearMeshMultiLev::MEDCurveLinearMeshMultiLev(const MEDFileCurveLinearMesh *m, const std::vector<int>& levs)
1122 {
1123   if(!m)
1124     throw INTERP_KERNEL::Exception("MEDCurveLinearMeshMultiLev constructor : null input pointer !");
1125   if(levs.size()!=1 || levs[0]!=0)
1126     throw INTERP_KERNEL::Exception("MEDCurveLinearMeshMultiLev constructor : levels supported is 0 only !");
1127   DataArrayDouble *coords(const_cast<DataArrayDouble *>(m->getMesh()->getCoords()));
1128   if(!coords)
1129     throw INTERP_KERNEL::Exception("MEDCurveLinearMeshMultiLev constructor 2 : no coords set !");
1130   coords->incrRef();
1131   _coords=coords;
1132   _structure=m->getMesh()->getNodeGridStructure();
1133   // ids fields management
1134   _cell_fam_ids_nocpy=true; _cell_num_ids_nocpy=true;
1135   const DataArrayInt *tmp(0);
1136   tmp=m->getFamilyFieldAtLevel(0);
1137   if(tmp)
1138     {
1139       tmp->incrRef();
1140       _cell_fam_ids=const_cast<DataArrayInt *>(tmp);
1141     }
1142   tmp=m->getNumberFieldAtLevel(0);
1143   if(tmp)
1144     {
1145       tmp->incrRef();
1146       _cell_num_ids=const_cast<DataArrayInt *>(tmp);
1147     }
1148 }
1149
1150 MEDCurveLinearMeshMultiLev::MEDCurveLinearMeshMultiLev(const MEDFileCurveLinearMesh *m, const std::vector<INTERP_KERNEL::NormalizedCellType>& gts, const std::vector<const DataArrayInt *>& pfls, const std::vector<int>& nbEntities):MEDStructuredMeshMultiLev(m->getNumberOfNodes(),gts,pfls,nbEntities)
1151 {
1152   if(!m)
1153     throw INTERP_KERNEL::Exception("MEDCurveLinearMeshMultiLev constructor 2 : null input pointer !");
1154   if(gts.size()!=1 || pfls.size()!=1)
1155     throw INTERP_KERNEL::Exception("MEDCurveLinearMeshMultiLev constructor 2 : lengthes of gts and pfls must be equal to one !");
1156   int mdim(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(m->getMeshDimension()));
1157   if(mdim!=gts[0])
1158     throw INTERP_KERNEL::Exception("MEDCurveLinearMeshMultiLev constructor 2 : the unique geo type is invalid regarding meshdim !");
1159   DataArrayDouble *coords(const_cast<DataArrayDouble *>(m->getMesh()->getCoords()));
1160   if(!coords)
1161     throw INTERP_KERNEL::Exception("MEDCurveLinearMeshMultiLev constructor 2 : no coords set !");
1162   coords->incrRef();
1163   _coords=coords;
1164   _structure=m->getMesh()->getNodeGridStructure();
1165   // ids fields management
1166   _cell_fam_ids_nocpy=true; _cell_num_ids_nocpy=true;
1167   const DataArrayInt *tmp(0);
1168   tmp=m->getFamilyFieldAtLevel(0);
1169   if(tmp)
1170     {
1171       tmp->incrRef();
1172       _cell_fam_ids=const_cast<DataArrayInt *>(tmp);
1173     }
1174   tmp=m->getNumberFieldAtLevel(0);
1175   if(tmp)
1176     {
1177       tmp->incrRef();
1178       _cell_num_ids=const_cast<DataArrayInt *>(tmp);
1179     }
1180 }
1181
1182 MEDCurveLinearMeshMultiLev::MEDCurveLinearMeshMultiLev(const MEDCurveLinearMeshMultiLev& other):MEDStructuredMeshMultiLev(other),_coords(other._coords),_structure(other._structure)
1183 {
1184 }
1185
1186 std::vector<int> MEDCurveLinearMeshMultiLev::getNodeGridStructure() const
1187 {
1188   return _structure;
1189 }
1190
1191 MEDMeshMultiLev *MEDCurveLinearMeshMultiLev::prepare() const
1192 {
1193   const DataArrayInt *pfl(_pfls[0]),*nr(_node_reduction);
1194   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nnr;
1195   std::vector<int> cgs,ngs(getNodeGridStructure());
1196   cgs.resize(ngs.size());
1197   std::transform(ngs.begin(),ngs.end(),cgs.begin(),std::bind2nd(std::plus<int>(),-1));
1198   if(pfl)
1199     {
1200       std::vector< std::pair<int,int> > cellParts,nodeParts;
1201       MEDCouplingAutoRefCountObjectPtr<MEDMeshMultiLev> ret2;
1202       if(MEDCouplingStructuredMesh::IsPartStructured(pfl->begin(),pfl->end(),cgs,cellParts))
1203         {
1204           nodeParts=cellParts;
1205           std::vector<int> st(ngs.size());
1206           for(std::size_t i=0;i<ngs.size();i++)
1207             {
1208               nodeParts[i].second++;
1209               st[i]=nodeParts[i].second-nodeParts[i].first;
1210             }
1211           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p(MEDCouplingStructuredMesh::BuildExplicitIdsFrom(ngs,nodeParts));
1212           MEDCouplingAutoRefCountObjectPtr<MEDCurveLinearMeshMultiLev> ret(new MEDCurveLinearMeshMultiLev(*this));
1213           if(nr)
1214             { nnr=nr->deepCpy(); nnr->sort(true); ret->setNodeReduction(nnr); }
1215           ret->_nb_entities[0]=pfl->getNumberOfTuples();
1216           ret->_pfls[0]=0;
1217           ret->_coords=_coords->selectByTupleIdSafe(p->begin(),p->end());
1218           ret->_structure=st;
1219           ret2=(MEDCurveLinearMeshMultiLev *)ret; ret2->incrRef();
1220         }
1221       else
1222         {
1223           MEDCouplingAutoRefCountObjectPtr<MEDCouplingCurveLinearMesh> m(MEDCouplingCurveLinearMesh::New());
1224           m->setCoords(_coords); m->setNodeGridStructure(&_structure[0],&_structure[0]+_structure.size());
1225           MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> m2(m->build1SGTUnstructured());
1226           MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> m3=dynamic_cast<MEDCoupling1GTUMesh *>(m2->buildPartOfMySelfKeepCoords(pfl->begin(),pfl->end()));
1227           MEDCouplingAutoRefCountObjectPtr<MEDUMeshMultiLev> ret(new MEDUMeshMultiLev(*this,m3));
1228           if(nr)
1229             { m3->zipCoords(); nnr=nr->deepCpy(); nnr->sort(true); ret->setNodeReduction(nnr); }
1230           ret2=(MEDUMeshMultiLev *)ret; ret2->incrRef();
1231         }
1232       const DataArrayInt *famIds(_cell_fam_ids),*numIds(_cell_num_ids);
1233       if(famIds)
1234         {
1235           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp(famIds->selectByTupleIdSafe(pfl->begin(),pfl->end()));
1236           ret2->setFamilyIdsOnCells(tmp,false);
1237         }
1238       if(numIds)
1239         {
1240           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp(numIds->selectByTupleIdSafe(pfl->begin(),pfl->end()));
1241           ret2->setNumberIdsOnCells(tmp,false);
1242         }
1243       return ret2.retn();
1244     }
1245   else
1246     {
1247       MEDCouplingAutoRefCountObjectPtr<MEDCurveLinearMeshMultiLev> ret(new MEDCurveLinearMeshMultiLev(*this));
1248       if(nr)
1249         { nnr=nr->deepCpy(); nnr->sort(true); ret->setNodeReduction(nnr); }
1250       return ret.retn();
1251     }
1252 }
1253
1254 void MEDCurveLinearMeshMultiLev::buildVTUArrays(DataArrayDouble *&coords, std::vector<int>& nodeStrct) const
1255 {
1256   nodeStrct=_structure;
1257   const DataArrayDouble *coo(_coords);
1258   if(!coo)
1259     throw INTERP_KERNEL::Exception("MEDCurveLinearMeshMultiLev::buildVTUArrays : null pointer on coordinates !");
1260   coords=const_cast<DataArrayDouble *>(coo); coords->incrRef();
1261 }
1262
1263 //=
1264
1265 MEDFileField1TSStructItem2::MEDFileField1TSStructItem2()
1266 {
1267 }
1268
1269 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)
1270 {
1271   _pfl->setName(c.c_str());
1272 }
1273
1274 void MEDFileField1TSStructItem2::checkWithMeshStructForCells(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs)
1275 {
1276   int nbOfEnt=mst->getNumberOfElemsOfGeoType(_geo_type);
1277   checkInRange(nbOfEnt,1,globs);
1278 }
1279
1280 void MEDFileField1TSStructItem2::checkWithMeshStructForGaussNE(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs)
1281 {
1282   int nbOfEnt=mst->getNumberOfElemsOfGeoType(_geo_type);
1283   const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_geo_type);
1284   checkInRange(nbOfEnt,(int)cm.getNumberOfNodes(),globs);
1285 }
1286
1287 void MEDFileField1TSStructItem2::checkWithMeshStructForGaussPT(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs)
1288 {
1289   if(!globs)
1290     throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::checkWithMeshStructForGaussPT : no globals specified !");
1291   if(_loc.empty())
1292     throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::checkWithMeshStructForGaussPT : no localization specified !");
1293   const MEDFileFieldLoc& loc=globs->getLocalization(_loc.c_str());
1294   int nbOfEnt=mst->getNumberOfElemsOfGeoType(_geo_type);
1295   checkInRange(nbOfEnt,loc.getNumberOfGaussPoints(),globs);
1296 }
1297
1298 int MEDFileField1TSStructItem2::getNbOfIntegrationPts(const MEDFileFieldGlobsReal *globs) const
1299 {
1300   if(_loc.empty())
1301     {
1302       if(getPflName().empty())
1303         return (_start_end.second-_start_end.first)/_nb_of_entity;
1304       else
1305         return (_start_end.second-_start_end.first)/getPfl(globs)->getNumberOfTuples();
1306     }
1307   else
1308     {
1309       const MEDFileFieldLoc& loc(globs->getLocalization(_loc.c_str()));
1310       return loc.getNumberOfGaussPoints();
1311     }
1312 }
1313
1314 std::string MEDFileField1TSStructItem2::getPflName() const
1315 {
1316   return _pfl->getName();
1317 }
1318
1319 const DataArrayInt *MEDFileField1TSStructItem2::getPfl(const MEDFileFieldGlobsReal *globs) const
1320 {
1321   if(!_pfl->isAllocated())
1322     {
1323       if(_pfl->getName().empty())
1324         return 0;
1325       else
1326         return globs->getProfile(_pfl->getName().c_str());
1327     }
1328   else
1329     return _pfl;
1330 }
1331
1332 /*!
1333  * \param [in] nbOfEntity - number of entity that can be either cells or nodes. Not other possiblity.
1334  * \param [in] nip - number of integration points. 1 for ON_CELLS and NO_NODES
1335  */
1336 void MEDFileField1TSStructItem2::checkInRange(int nbOfEntity, int nip, const MEDFileFieldGlobsReal *globs)
1337 {
1338   _nb_of_entity=nbOfEntity;
1339   if(_pfl->getName().empty())
1340     {
1341       if(nbOfEntity!=(_start_end.second-_start_end.first)/nip)
1342         throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::checkInRange : Mismatch between number of entities and size of node field !");
1343       return ;
1344     }
1345   else
1346     {
1347       if(!globs)
1348         throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::checkInRange : Presence of a profile on field whereas no globals found in file !");
1349       const DataArrayInt *pfl=globs->getProfile(_pfl->getName().c_str());
1350       if(!pfl)
1351         throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::checkInRange : Presence of a profile on field whereas no such profile found in file !");
1352       pfl->checkAllIdsInRange(0,nbOfEntity);
1353     }
1354 }
1355
1356 bool MEDFileField1TSStructItem2::isFastlyEqual(int& startExp, INTERP_KERNEL::NormalizedCellType gt, const char *pflName) const
1357 {
1358   if(startExp!=_start_end.first)
1359     return false;
1360   if(gt!=_geo_type)
1361     return false;
1362   if(getPflName()!=pflName)
1363     return false;
1364   startExp=_start_end.second;
1365   return true;
1366 }
1367
1368 bool MEDFileField1TSStructItem2::operator==(const MEDFileField1TSStructItem2& other) const throw(INTERP_KERNEL::Exception)
1369 {
1370   //_nb_of_entity is not taken into account here. It is not a bug, because no mesh consideration needed here to perform fast compare.
1371   //idem for _loc. It is not an effective attribute for support comparison.
1372   return _geo_type==other._geo_type && _start_end==other._start_end && _pfl->getName()==other._pfl->getName();
1373 }
1374
1375 bool MEDFileField1TSStructItem2::isCellSupportEqual(const MEDFileField1TSStructItem2& other, const MEDFileFieldGlobsReal *globs) const
1376 {
1377   if(_geo_type!=other._geo_type)
1378     return false;
1379   if(_nb_of_entity!=other._nb_of_entity)
1380     return false;
1381   if((_pfl->getName().empty() && !other._pfl->getName().empty()) || (!_pfl->getName().empty() && other._pfl->getName().empty()))
1382     return false;
1383   if(_pfl->getName().empty() && other._pfl->getName().empty())
1384     return true;
1385   const DataArrayInt *pfl1(getPfl(globs)),*pfl2(other.getPfl(globs));
1386   return pfl1->isEqualWithoutConsideringStr(*pfl2);
1387 }
1388
1389 bool MEDFileField1TSStructItem2::isNodeSupportEqual(const MEDFileField1TSStructItem2& other, const MEDFileFieldGlobsReal *globs) const
1390 {
1391   return isCellSupportEqual(other,globs);
1392 }
1393
1394 /*!
1395  * \a objs must be non empty. \a objs should contain items having same geometric type.
1396  */
1397 MEDFileField1TSStructItem2 MEDFileField1TSStructItem2::BuildAggregationOf(const std::vector<const MEDFileField1TSStructItem2 *>& objs, const MEDFileFieldGlobsReal *globs)
1398 {
1399   if(objs.empty())
1400     throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::BuildAggregationOf : empty input !");
1401   if(objs.size()==1)
1402     return MEDFileField1TSStructItem2(*objs[0]);
1403   INTERP_KERNEL::NormalizedCellType gt(objs[0]->_geo_type);
1404   int nbEntityRef(objs[0]->_nb_of_entity);
1405   std::size_t sz(objs.size());
1406   std::vector<const DataArrayInt *> arrs(sz);
1407   for(std::size_t i=0;i<sz;i++)
1408     {
1409       const MEDFileField1TSStructItem2 *obj(objs[i]);
1410       if(gt!=obj->_geo_type)
1411         throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::BuildAggregationOf : invalid situation ! All input must have the same geo type !");
1412       if(nbEntityRef!=obj->_nb_of_entity)
1413         throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::BuildAggregationOf : invalid situation ! All input must have the global nb of entity !");
1414       if(obj->_pfl->getName().empty())
1415         throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::BuildAggregationOf : invalid situation ! Several same geo type chunk must all lie on profiles !");
1416       arrs[i]=globs->getProfile(obj->_pfl->getName().c_str());
1417     }
1418   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr(DataArrayInt::Aggregate(arrs));
1419   arr->sort();
1420   int oldNbTuples(arr->getNumberOfTuples());
1421   arr=arr->buildUnique();
1422   if(oldNbTuples!=arr->getNumberOfTuples())
1423     throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::BuildAggregationOf : some entities are present several times !");
1424   if(arr->isIdentity() && oldNbTuples==nbEntityRef)
1425     {
1426       std::pair<int,int> p(0,nbEntityRef);
1427       std::string a,b;
1428       MEDFileField1TSStructItem2 ret(gt,p,a,b);
1429       ret._nb_of_entity=nbEntityRef;
1430       return ret;
1431     }
1432   else
1433     {
1434       arr->setName(NEWLY_CREATED_PFL_NAME);
1435       std::pair<int,int> p(0,oldNbTuples);
1436       std::string a,b;
1437       MEDFileField1TSStructItem2 ret(gt,p,a,b);
1438       ret._nb_of_entity=nbEntityRef;
1439       ret._pfl=arr;
1440       return ret;
1441     }
1442 }
1443
1444 std::size_t MEDFileField1TSStructItem2::getHeapMemorySizeWithoutChildren() const
1445 {
1446   std::size_t ret(_loc.capacity());
1447   return ret;
1448 }
1449
1450 std::vector<const BigMemoryObject *> MEDFileField1TSStructItem2::getDirectChildren() const
1451 {
1452   std::vector<const BigMemoryObject *> ret;
1453   const DataArrayInt *pfl(_pfl);
1454   if(pfl)
1455     ret.push_back(pfl);
1456   return ret;
1457 }
1458
1459 //=
1460
1461 MEDFileField1TSStructItem::MEDFileField1TSStructItem(TypeOfField a, const std::vector< MEDFileField1TSStructItem2 >& b):_computed(false),_type(a),_items(b)
1462 {
1463 }
1464
1465 void MEDFileField1TSStructItem::checkWithMeshStruct(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs)
1466 {
1467   switch(_type)
1468     {
1469     case ON_NODES:
1470       {
1471         int nbOfEnt=mst->getNumberOfNodes();
1472         if(_items.size()!=1)
1473           throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::checkWithMeshStruct : for nodes field only one subdivision supported !");
1474         _items[0].checkInRange(nbOfEnt,1,globs);
1475         break ;
1476       }
1477     case ON_CELLS:
1478       {
1479         for(std::vector< MEDFileField1TSStructItem2 >::iterator it=_items.begin();it!=_items.end();it++)
1480           (*it).checkWithMeshStructForCells(mst,globs);
1481         break;
1482       }
1483     case ON_GAUSS_NE:
1484       {
1485         for(std::vector< MEDFileField1TSStructItem2 >::iterator it=_items.begin();it!=_items.end();it++)
1486           (*it).checkWithMeshStructForGaussNE(mst,globs);
1487         break;
1488       }
1489     case ON_GAUSS_PT:
1490       {
1491         for(std::vector< MEDFileField1TSStructItem2 >::iterator it=_items.begin();it!=_items.end();it++)
1492           (*it).checkWithMeshStructForGaussPT(mst,globs);
1493         break;
1494       }
1495     default:
1496       throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::checkWithMeshStruct : not managed field type !");
1497     }
1498 }
1499
1500 bool MEDFileField1TSStructItem::operator==(const MEDFileField1TSStructItem& other) const throw(INTERP_KERNEL::Exception)
1501 {
1502   if(_type!=other._type)
1503     return false;
1504   if(_items.size()!=other._items.size())
1505     return false;
1506   for(std::size_t i=0;i<_items.size();i++)
1507     if(!(_items[i]==other._items[i]))
1508       return false;
1509   return true;
1510 }
1511
1512 bool MEDFileField1TSStructItem::isCellSupportEqual(const MEDFileField1TSStructItem& other, const MEDFileFieldGlobsReal *globs) const
1513 {
1514   if(_type!=other._type)
1515     return false;
1516   if(_items.size()!=other._items.size())
1517     return false;
1518   for(std::size_t i=0;i<_items.size();i++)
1519     if(!(_items[i].isCellSupportEqual(other._items[i],globs)))
1520       return false;
1521   return true;
1522 }
1523
1524 bool MEDFileField1TSStructItem::isNodeSupportEqual(const MEDFileField1TSStructItem& other, const MEDFileFieldGlobsReal *globs) const
1525 {
1526   if(_type!=other._type)
1527     return false;
1528   if(_items.size()!=other._items.size())
1529     return false;
1530   for(std::size_t i=0;i<_items.size();i++)
1531     if(!(_items[i].isNodeSupportEqual(other._items[i],globs)))
1532       return false;
1533   return true;
1534 }
1535
1536 bool MEDFileField1TSStructItem::isEntityCell() const
1537 {
1538   if(_type==ON_NODES)
1539     return false;
1540   else
1541     return true;
1542 }
1543
1544 class CmpGeo
1545 {
1546 public:
1547   CmpGeo(INTERP_KERNEL::NormalizedCellType geoTyp):_geo_type(geoTyp) { }
1548   bool operator()(const std::pair< INTERP_KERNEL::NormalizedCellType, std::vector<std::size_t> > & v) const { return _geo_type==v.first; }
1549 private:
1550   INTERP_KERNEL::NormalizedCellType _geo_type;
1551 };
1552
1553 MEDFileField1TSStructItem MEDFileField1TSStructItem::simplifyMeOnCellEntity(const MEDFileFieldGlobsReal *globs) const
1554 {
1555   if(!isEntityCell())
1556     throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::simplifyMeOnCellEntity : must be on ON_CELLS, ON_GAUSS_NE or ON_GAUSS_PT !");
1557   std::vector< std::pair< INTERP_KERNEL::NormalizedCellType, std::vector<std::size_t> > > m;
1558   std::size_t i=0;
1559   for(std::vector< MEDFileField1TSStructItem2 >::const_iterator it=_items.begin();it!=_items.end();it++,i++)
1560     {
1561       std::vector< std::pair< INTERP_KERNEL::NormalizedCellType, std::vector<std::size_t> > >::iterator it0(std::find_if(m.begin(),m.end(),CmpGeo((*it).getGeo())));
1562       if(it0==m.end())
1563         m.push_back(std::pair< INTERP_KERNEL::NormalizedCellType, std::vector<std::size_t> >((*it).getGeo(),std::vector<std::size_t>(1,i)));
1564       else
1565         (*it0).second.push_back(i);
1566     }
1567   if(m.size()==_items.size())
1568     {
1569       MEDFileField1TSStructItem ret(*this);
1570       ret._type=ON_CELLS;
1571       return ret;
1572     }
1573   std::size_t sz(m.size());
1574   std::vector< MEDFileField1TSStructItem2 > items(sz);
1575   for(i=0;i<sz;i++)
1576     {
1577       const std::vector<std::size_t>& ids=m[i].second;
1578       std::vector<const MEDFileField1TSStructItem2 *>objs(ids.size());
1579       for(std::size_t j=0;j<ids.size();j++)
1580         objs[j]=&_items[ids[j]];
1581       items[i]=MEDFileField1TSStructItem2::BuildAggregationOf(objs,globs);
1582     }
1583   MEDFileField1TSStructItem ret(ON_CELLS,items);
1584   ret._computed=true;
1585   return ret;
1586 }
1587
1588 /*!
1589  * \a this is expected to be ON_CELLS and simplified.
1590  */
1591 bool MEDFileField1TSStructItem::isCompatibleWithNodesDiscr(const MEDFileField1TSStructItem& other, const MEDFileMeshStruct *meshSt, const MEDFileFieldGlobsReal *globs) const
1592 {
1593   if(other._type!=ON_NODES)
1594     throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::isCompatibleWithNodesDiscr : other must be on nodes !");
1595   if(other._items.size()!=1)
1596     throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::isCompatibleWithNodesDiscr : other is on nodes but number of subparts !");
1597   int theFirstLevFull;
1598   bool ret0=isFullyOnOneLev(meshSt,theFirstLevFull);
1599   const MEDFileField1TSStructItem2& otherNodeIt(other._items[0]);
1600   if(otherNodeIt.getPflName().empty())
1601     {//on all nodes
1602       if(!ret0)
1603         return false;
1604       return theFirstLevFull==0;
1605     }
1606   else
1607     {
1608       const DataArrayInt *pfl=globs->getProfile(otherNodeIt.getPflName().c_str());
1609       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cpyPfl(pfl->deepCpy());
1610       cpyPfl->sort();
1611       int nbOfNodes(meshSt->getNumberOfNodes());
1612       if(cpyPfl->isIdentity() && cpyPfl->getNumberOfTuples()==nbOfNodes)
1613         {//on all nodes also !
1614           if(!ret0)
1615             return false;
1616           return theFirstLevFull==0;
1617         }
1618       std::vector<bool> nodesFetched(nbOfNodes,false);
1619       meshSt->getTheMesh()->whichAreNodesFetched(*this,globs,nodesFetched);
1620       return cpyPfl->isFittingWith(nodesFetched);
1621     }
1622 }
1623
1624 bool MEDFileField1TSStructItem::isFullyOnOneLev(const MEDFileMeshStruct *meshSt, int& theFirstLevFull) const
1625 {
1626   if(_type!=ON_CELLS)
1627     throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::isFullyOnOneLev : works only for ON_CELLS discretization !");
1628   if(_items.empty())
1629     throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::isFullyOnOneLev : items vector is empty !");
1630   int nbOfLevs(meshSt->getNumberOfLevs());
1631   if(nbOfLevs==0)
1632     throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::isFullyOnOneLev : no levels in input mesh structure !");
1633   std::vector<int> levs(nbOfLevs);
1634   theFirstLevFull=1;
1635   std::set<INTERP_KERNEL::NormalizedCellType> gts;
1636   for(std::vector< MEDFileField1TSStructItem2 >::const_iterator it=_items.begin();it!=_items.end();it++)
1637     {
1638       if(!(*it).getPflName().empty())
1639         return false;
1640       INTERP_KERNEL::NormalizedCellType gt((*it).getGeo());
1641       if(gts.find(gt)!=gts.end())
1642         throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::isFullyOnOneLev : internal error !");
1643       gts.insert(gt);
1644       int pos(meshSt->getLevelOfGeoType((*it).getGeo()));
1645       levs[-pos]++;
1646     }
1647   for(int i=0;i<nbOfLevs;i++)
1648     if(meshSt->getNumberOfGeoTypesInLev(-i)==levs[i])
1649       { theFirstLevFull=-i; return true; }
1650   return false;
1651 }
1652
1653 const MEDFileField1TSStructItem2& MEDFileField1TSStructItem::operator[](std::size_t i) const throw(INTERP_KERNEL::Exception)
1654 {
1655   if(i>=_items.size())
1656     throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::operator[] : input is not in valid range !");
1657   return _items[i];
1658 }
1659
1660 std::size_t MEDFileField1TSStructItem::getHeapMemorySizeWithoutChildren() const
1661 {
1662   std::size_t ret(_items.size()*sizeof(MEDFileField1TSStructItem2));
1663   return ret;
1664 }
1665
1666 std::vector<const BigMemoryObject *> MEDFileField1TSStructItem::getDirectChildren() const
1667 {
1668   std::vector<const BigMemoryObject *> ret;
1669   for(std::vector< MEDFileField1TSStructItem2 >::const_iterator it=_items.begin();it!=_items.end();it++)
1670     ret.push_back(&(*it));
1671   return ret;
1672 }
1673
1674 MEDMeshMultiLev *MEDFileField1TSStructItem::buildFromScratchDataSetSupportOnCells(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) const
1675 {
1676   std::size_t sz(_items.size());
1677   std::vector<INTERP_KERNEL::NormalizedCellType> a0(sz);
1678   std::vector<const DataArrayInt *> a1(sz);
1679   std::vector<int> a2(sz);
1680   std::size_t i(0);
1681   for(std::vector< MEDFileField1TSStructItem2 >::const_iterator it=_items.begin();it!=_items.end();it++,i++)
1682     {
1683       a0[i]=(*it).getGeo();
1684       a1[i]=(*it).getPfl(globs);
1685       a2[i]=mst->getNumberOfElemsOfGeoType((*it).getGeo());
1686     }
1687   return MEDMeshMultiLev::New(mst->getTheMesh(),a0,a1,a2);
1688 }
1689
1690 MEDFileField1TSStructItem MEDFileField1TSStructItem::BuildItemFrom(const MEDFileAnyTypeField1TS *ref, const MEDFileMeshStruct *meshSt)
1691 {
1692   TypeOfField atype;
1693   std::vector< MEDFileField1TSStructItem2 > anItems;
1694   //
1695   std::vector< std::vector<std::string> > pfls,locs;
1696   std::vector< std::vector<TypeOfField> > typesF;
1697   std::vector<INTERP_KERNEL::NormalizedCellType> geoTypes;
1698   std::vector< std::vector<std::pair<int,int> > > strtEnds=ref->getFieldSplitedByType(0,geoTypes,typesF,pfls,locs);
1699   std::size_t nbOfGeoTypes(geoTypes.size());
1700   if(nbOfGeoTypes==0)
1701     throw INTERP_KERNEL::Exception("MEDFileField1TSStruct : not null by empty ref  !");
1702   bool isFirst=true;
1703   for(std::size_t i=0;i<nbOfGeoTypes;i++)
1704     {
1705       std::size_t sz=typesF[i].size();
1706       if(strtEnds[i].size()<1 || sz<1 || pfls[i].size()<1)
1707         throw INTERP_KERNEL::Exception("MEDFileField1TSStruct : internal error #1 !");
1708       //
1709       if(isFirst)
1710         atype=typesF[i][0];
1711       isFirst=false;
1712       //
1713       for(std::size_t j=0;j<sz;j++)
1714         {
1715           if(atype==typesF[i][j])
1716             anItems.push_back(MEDFileField1TSStructItem2(geoTypes[i],strtEnds[i][j],pfls[i][j],locs[i][j]));
1717           else
1718             throw INTERP_KERNEL::Exception("MEDFileField1TSStruct : can be applied only on single spatial discretization fields ! Call SplitPerDiscretization method !");
1719         }
1720     }
1721   MEDFileField1TSStructItem ret(atype,anItems);
1722   ret.checkWithMeshStruct(meshSt,ref);
1723   return ret;
1724 }
1725
1726 //=
1727
1728 MEDFileField1TSStruct *MEDFileField1TSStruct::New(const MEDFileAnyTypeField1TS *ref, MEDFileMeshStruct *mst)
1729 {
1730   return new MEDFileField1TSStruct(ref,mst);
1731 }
1732
1733 MEDFileField1TSStruct::MEDFileField1TSStruct(const MEDFileAnyTypeField1TS *ref, MEDFileMeshStruct *mst)
1734 {
1735   _already_checked.push_back(MEDFileField1TSStructItem::BuildItemFrom(ref,mst));
1736 }
1737
1738 void MEDFileField1TSStruct::checkWithMeshStruct(MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs)
1739 {
1740   if(_already_checked.empty())
1741     throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::checkWithMeshStruct : not correctly initialized !");
1742   _already_checked.back().checkWithMeshStruct(mst,globs);
1743 }
1744
1745 bool MEDFileField1TSStruct::isEqualConsideringThePast(const MEDFileAnyTypeField1TS *other, const MEDFileMeshStruct *mst) const
1746 {
1747   MEDFileField1TSStructItem b(MEDFileField1TSStructItem::BuildItemFrom(other,mst));
1748   for(std::vector<MEDFileField1TSStructItem>::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++)
1749     {
1750       if((*it)==b)
1751         return true;
1752     }
1753   return false;
1754 }
1755
1756 /*!
1757  * Not const because \a other structure will be added to the \c _already_checked attribute in case of success.
1758  */
1759 bool MEDFileField1TSStruct::isSupportSameAs(const MEDFileAnyTypeField1TS *other, const MEDFileMeshStruct *meshSt)
1760 {
1761   if(_already_checked.empty())
1762     throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::isSupportSameAs : no ref !");
1763   MEDFileField1TSStructItem b(MEDFileField1TSStructItem::BuildItemFrom(other,meshSt));
1764   if(!_already_checked[0].isEntityCell() || !b.isEntityCell())
1765     throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::isSupportSameAs : only available on cell entities !");
1766   MEDFileField1TSStructItem other1(b.simplifyMeOnCellEntity(other));
1767   int found=-1,i=0;
1768   for(std::vector<MEDFileField1TSStructItem>::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++,i++)
1769     if((*it).isComputed())
1770       { found=i; break; }
1771   bool ret(false);
1772   if(found==-1)
1773     {
1774       MEDFileField1TSStructItem this1(_already_checked[0].simplifyMeOnCellEntity(other));
1775       ret=this1.isCellSupportEqual(other1,other);
1776       if(ret)
1777         _already_checked.push_back(this1);
1778     }
1779   else
1780     ret=_already_checked[found].isCellSupportEqual(other1,other);
1781   if(ret)
1782     _already_checked.push_back(b);
1783   return ret;
1784 }
1785
1786 /*!
1787  * \param [in] other - a field with only one spatial discretization : ON_NODES.
1788  */
1789 bool MEDFileField1TSStruct::isCompatibleWithNodesDiscr(const MEDFileAnyTypeField1TS *other, const MEDFileMeshStruct *meshSt)
1790 {
1791   if(_already_checked.empty())
1792     throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::isCompatibleWithNodesDiscr : no ref !");
1793   MEDFileField1TSStructItem other1(MEDFileField1TSStructItem::BuildItemFrom(other,meshSt));
1794   if(_already_checked[0].isEntityCell())
1795     {
1796       int found=-1,i=0;
1797       for(std::vector<MEDFileField1TSStructItem>::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++,i++)
1798         if((*it).isComputed())
1799           { found=i; break; }
1800       bool ret(false);
1801       if(found==-1)
1802         {
1803           MEDFileField1TSStructItem this1(_already_checked[0].simplifyMeOnCellEntity(other));
1804           ret=this1.isCompatibleWithNodesDiscr(other1,meshSt,other);
1805           if(ret)
1806             _already_checked.push_back(this1);
1807         }
1808       else
1809         ret=_already_checked[found].isCompatibleWithNodesDiscr(other1,meshSt,other);
1810       if(ret)
1811         _already_checked.push_back(other1);
1812       return ret;
1813     }
1814   else
1815     return _already_checked[0].isNodeSupportEqual(other1,other);
1816 }
1817
1818 std::size_t MEDFileField1TSStruct::getHeapMemorySizeWithoutChildren() const
1819 {
1820   std::size_t ret(_already_checked.capacity()*sizeof(MEDFileField1TSStructItem));
1821   return ret;
1822 }
1823
1824 std::vector<const BigMemoryObject *> MEDFileField1TSStruct::getDirectChildren() const
1825 {
1826   std::vector<const BigMemoryObject *> ret;
1827   for(std::vector<MEDFileField1TSStructItem>::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++)
1828     ret.push_back(&(*it));
1829   return ret;
1830 }
1831
1832 MEDMeshMultiLev *MEDFileField1TSStruct::buildFromScratchDataSetSupport(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) const
1833 {
1834   if(_already_checked.empty())
1835     throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::buildFromScratchDataSetSupport : No outline structure in this !");
1836   int pos0(-1),pos1(-1);
1837   if(presenceOfCellDiscr(pos0))
1838     {
1839       MEDCouplingAutoRefCountObjectPtr<MEDMeshMultiLev> ret(_already_checked[pos0].buildFromScratchDataSetSupportOnCells(mst,globs));
1840       if(presenceOfPartialNodeDiscr(pos1))
1841         ret->setNodeReduction(_already_checked[pos1][0].getPfl(globs));
1842       return ret.retn();
1843     }
1844   else
1845     {
1846       if(!presenceOfPartialNodeDiscr(pos1))
1847         {//we have only all nodes, no cell definition info -> level 0;
1848           std::vector<int> levs(1,0);
1849           return MEDMeshMultiLev::New(mst->getTheMesh(),levs);
1850         }
1851       else
1852         return MEDMeshMultiLev::NewOnlyOnNode(mst->getTheMesh(),_already_checked[pos1][0].getPfl(globs));
1853     }
1854 }
1855
1856 bool MEDFileField1TSStruct::isDataSetSupportFastlyEqualTo(const MEDFileField1TSStruct& other, const MEDFileFieldGlobsReal *globs) const
1857 {
1858   int b0,b1;
1859   bool a0(presenceOfCellDiscr(b0)),a1(presenceOfPartialNodeDiscr(b1));
1860   int d0,d1;
1861   bool c0(other.presenceOfCellDiscr(d0)),c1(other.presenceOfPartialNodeDiscr(d1)); 
1862   if(a0!=c0 || a1!=c1)
1863     return false;
1864   if(a0)
1865     if(!_already_checked[b0].isCellSupportEqual(other._already_checked[d0],globs))
1866       return false;
1867   if(a1)
1868     if(!_already_checked[b1].isNodeSupportEqual(other._already_checked[d1],globs))
1869       return false;
1870   return true;
1871 }
1872
1873 /*!
1874  * Returns true if presence in \a this of discretization ON_CELLS, ON_GAUSS_PT, ON_GAUSS_NE.
1875  * If true is returned the pos of the easiest is returned. The easiest is the first element in \a this having the less splitted subparts.
1876  */
1877 bool MEDFileField1TSStruct::presenceOfCellDiscr(int& pos) const
1878 {
1879   std::size_t refSz(std::numeric_limits<std::size_t>::max());
1880   bool ret(false);
1881   int i(0);
1882   for(std::vector<MEDFileField1TSStructItem>::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++,i++)
1883     {
1884       if((*it).getType()!=ON_NODES)
1885         {
1886           ret=true;
1887           std::size_t sz((*it).getNumberOfItems());
1888           if(refSz>sz)
1889             { pos=i; refSz=sz; }
1890         }
1891     }
1892   if(refSz==0)
1893     throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::presenceOfCellDiscr : an element in this on entity CELL is empty !");
1894   return ret;
1895 }
1896
1897 /*!
1898  * Returns true if presence in \a this of discretization ON_NODES.
1899  * If true is returned the pos of the first element containing the single subpart.
1900  */
1901 bool MEDFileField1TSStruct::presenceOfPartialNodeDiscr(int& pos) const
1902 {
1903   int i(0);
1904   for(std::vector<MEDFileField1TSStructItem>::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++,i++)
1905     {
1906       if((*it).getType()==ON_NODES)
1907         {
1908           std::size_t sz((*it).getNumberOfItems());
1909           if(sz==1)
1910             {
1911               if(!(*it)[0].getPflName().empty())
1912                 { pos=i; return true; }
1913             }
1914           else
1915             throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::presenceOfPartialNodeDiscr : an element in this on entity NODE is split into several parts !");
1916         }
1917     }
1918   return false;
1919 }
1920
1921 //=
1922
1923 MEDFileFastCellSupportComparator *MEDFileFastCellSupportComparator::New(const MEDFileMeshStruct *m, const MEDFileAnyTypeFieldMultiTS *ref)
1924 {
1925   return new MEDFileFastCellSupportComparator(m,ref);
1926 }
1927
1928 MEDFileFastCellSupportComparator::MEDFileFastCellSupportComparator(const MEDFileMeshStruct *m, const MEDFileAnyTypeFieldMultiTS *ref)
1929 {
1930   if(!m)
1931     throw INTERP_KERNEL::Exception("MEDFileFastCellSupportComparator constructor : null input mesh struct !");
1932   _mesh_comp=const_cast<MEDFileMeshStruct *>(m); _mesh_comp->incrRef();
1933   int nbPts=ref->getNumberOfTS();
1934   _f1ts_cmps.resize(nbPts);
1935   for(int i=0;i<nbPts;i++)
1936     {
1937       MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TS> elt=ref->getTimeStepAtPos(i);
1938       _f1ts_cmps[i]=MEDFileField1TSStruct::New(elt,_mesh_comp);
1939       _f1ts_cmps[i]->checkWithMeshStruct(_mesh_comp,elt);
1940     }
1941 }
1942
1943 std::size_t MEDFileFastCellSupportComparator::getHeapMemorySizeWithoutChildren() const
1944 {
1945   std::size_t ret(_f1ts_cmps.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileField1TSStruct>));
1946   return ret;
1947 }
1948
1949 std::vector<const BigMemoryObject *> MEDFileFastCellSupportComparator::getDirectChildren() const
1950 {
1951   std::vector<const BigMemoryObject *> ret;
1952   const MEDFileMeshStruct *mst(_mesh_comp);
1953   if(mst)
1954     ret.push_back(mst);
1955   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileField1TSStruct> >::const_iterator it=_f1ts_cmps.begin();it!=_f1ts_cmps.end();it++)
1956     {
1957       const MEDFileField1TSStruct *cur(*it);
1958       if(cur)
1959         ret.push_back(cur);
1960     }
1961   return ret;
1962 }
1963
1964 bool MEDFileFastCellSupportComparator::isEqual(const MEDFileAnyTypeFieldMultiTS *other)
1965 {
1966   int nbPts=other->getNumberOfTS();
1967   if(nbPts!=(int)_f1ts_cmps.size())
1968     {
1969       std::ostringstream oss; oss << "MEDFileFastCellSupportComparator::isEqual : unexpected nb of time steps in  input ! Should be " << _f1ts_cmps.size() << " it is in reality " << nbPts << " !";
1970       throw INTERP_KERNEL::Exception(oss.str().c_str());
1971     }
1972   for(int i=0;i<nbPts;i++)
1973     {
1974       MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TS> elt=other->getTimeStepAtPos(i);
1975       if(!_f1ts_cmps[i]->isEqualConsideringThePast(elt,_mesh_comp))
1976         if(!_f1ts_cmps[i]->isSupportSameAs(elt,_mesh_comp))
1977           return false;
1978     }
1979   return true;
1980 }
1981
1982 bool MEDFileFastCellSupportComparator::isCompatibleWithNodesDiscr(const MEDFileAnyTypeFieldMultiTS *other)
1983 {
1984   int nbPts=other->getNumberOfTS();
1985   if(nbPts!=(int)_f1ts_cmps.size())
1986     {
1987       std::ostringstream oss; oss << "MEDFileFastCellSupportComparator::isCompatibleWithNodesDiscr : unexpected nb of time steps in  input ! Should be " << _f1ts_cmps.size() << " it is in reality " << nbPts << " !";
1988       throw INTERP_KERNEL::Exception(oss.str().c_str());
1989     }
1990   for(int i=0;i<nbPts;i++)
1991     {
1992       MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TS> elt=other->getTimeStepAtPos(i);
1993       if(!_f1ts_cmps[i]->isCompatibleWithNodesDiscr(elt,_mesh_comp))
1994         return false;
1995     }
1996   return true;
1997 }
1998
1999 MEDMeshMultiLev *MEDFileFastCellSupportComparator::buildFromScratchDataSetSupport(int timeStepId, const MEDFileFieldGlobsReal *globs) const
2000 {
2001   if(timeStepId<0 || timeStepId>=(int)_f1ts_cmps.size())
2002     {
2003       std::ostringstream oss; oss << "MEDFileFastCellSupportComparator::buildFromScratchDataSetSupport : requested time step id #" << timeStepId << " is not in [0," << _f1ts_cmps.size() << ") !";
2004       throw INTERP_KERNEL::Exception(oss.str().c_str());
2005     }
2006   const MEDFileField1TSStruct *obj(_f1ts_cmps[timeStepId]);
2007   if(!obj)
2008     {
2009       std::ostringstream oss; oss << "MEDFileFastCellSupportComparator::buildFromScratchDataSetSupport : at time step id #" << timeStepId << " no field structure overview defined !";
2010       throw INTERP_KERNEL::Exception(oss.str().c_str());
2011     }
2012   return obj->buildFromScratchDataSetSupport(_mesh_comp,globs);
2013 }
2014
2015 bool MEDFileFastCellSupportComparator::isDataSetSupportEqualToThePreviousOne(int timeStepId, const MEDFileFieldGlobsReal *globs) const
2016 {
2017   if(timeStepId<=0 || timeStepId>=(int)_f1ts_cmps.size())
2018     {
2019       std::ostringstream oss; oss << "MEDFileFastCellSupportComparator::isDataSetSupportEqualToThePreviousOne : requested time step id #" << timeStepId << " is not in [1," << _f1ts_cmps.size() << ") !";
2020       throw INTERP_KERNEL::Exception(oss.str().c_str());
2021     }
2022   const MEDFileField1TSStruct *obj(_f1ts_cmps[timeStepId]);
2023   const MEDFileField1TSStruct *objRef(_f1ts_cmps[timeStepId-1]);
2024   return objRef->isDataSetSupportFastlyEqualTo(*obj,globs);
2025 }