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