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