Salome HOME
Typo and whitespace fixes by Kunda
[tools/medcoupling.git] / src / MEDLoader / MEDFileFieldInternal.cxx
1 // Copyright (C) 2017  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, or (at your option) any later version.
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 (EDF R&D)
20
21 #include "MEDFileFieldInternal.hxx"
22 #include "MEDFileField.hxx"
23 #include "MEDFileFieldVisitor.hxx"
24 #include "MEDFileStructureElement.hxx"
25 #include "MEDLoaderBase.hxx"
26 #include "MEDFileSafeCaller.txx"
27 #include "MEDFileEntities.hxx"
28
29 #include "MEDCouplingGaussLocalization.hxx"
30 #include "MEDCouplingFieldTemplate.hxx"
31 #include "MEDCouplingFieldDouble.hxx"
32
33 #include "CellModel.hxx"
34
35 extern med_geometry_type typmai[MED_N_CELL_FIXED_GEO];
36 extern INTERP_KERNEL::NormalizedCellType typmai2[MED_N_CELL_FIXED_GEO];
37 extern med_geometry_type typmai3[34];
38
39 using namespace MEDCoupling;
40
41 MEDFileGTKeeper::~MEDFileGTKeeper()
42 {
43 }
44
45 MEDFileGTKeeper *MEDFileGTKeeperSta::deepCopy() const
46 {
47   return new MEDFileGTKeeperSta(_geo_type);
48 }
49
50 INTERP_KERNEL::NormalizedCellType MEDFileGTKeeperSta::getGeoType() const
51 {
52   return _geo_type;
53 }
54
55 std::string MEDFileGTKeeperSta::getRepr() const
56 {
57   return INTERP_KERNEL::CellModel::GetCellModel(_geo_type).getRepr();
58 }
59
60 bool MEDFileGTKeeperSta::isEqual(const MEDFileGTKeeper *other) const
61 {
62   const MEDFileGTKeeperSta *otherC(dynamic_cast<const MEDFileGTKeeperSta *>(other));
63   if(!otherC)
64     return false;
65   return _geo_type==otherC->_geo_type;
66 }
67
68 MEDFileGTKeeperDyn::MEDFileGTKeeperDyn(const MEDFileUMesh *mesh, const MEDFileUMesh *section, const MEDFileStructureElement *se):_mesh(mesh),_section(section),_se(se)
69 {
70   if(mesh)
71     mesh->incrRef();
72   if(section)
73     section->incrRef();
74   if(se)
75     se->incrRef();
76   if(_mesh.isNull() || _section.isNull() || _se.isNull())
77     throw INTERP_KERNEL::Exception("MEDFileGTKeeperDyn constructor : null pointer not allowed !");
78 }
79
80 MEDFileGTKeeper *MEDFileGTKeeperDyn::deepCopy() const
81 {
82   return new MEDFileGTKeeperDyn(_mesh,_section,_se);
83 }
84
85 INTERP_KERNEL::NormalizedCellType MEDFileGTKeeperDyn::getGeoType() const
86 {
87   throw INTERP_KERNEL::Exception("MEDFileGTKeeperDyn::getGeoType : not valid !");
88 }
89
90 std::string MEDFileGTKeeperDyn::getRepr() const
91 {
92   std::ostringstream oss;
93   oss << _se->getDynGT();
94   return oss.str();
95 }
96
97 bool MEDFileGTKeeperDyn::isEqual(const MEDFileGTKeeper *other) const
98 {
99   const MEDFileGTKeeperDyn *otherC(dynamic_cast<const MEDFileGTKeeperDyn *>(other));
100   if(!otherC)
101     return false;
102   return this==otherC;
103 }
104
105 MEDFileFieldLoc *MEDFileFieldLoc::New(med_idt fid, const std::string& locName)
106 {
107   return new MEDFileFieldLoc(fid,locName);
108 }
109
110 MEDFileFieldLoc *MEDFileFieldLoc::New(med_idt fid, int id, const MEDFileEntities *entities)
111 {
112   return new MEDFileFieldLoc(fid,id,entities);
113 }
114
115 MEDFileFieldLoc *MEDFileFieldLoc::New(const std::string& locName, INTERP_KERNEL::NormalizedCellType geoType, const std::vector<double>& refCoo, const std::vector<double>& gsCoo, const std::vector<double>& w)
116 {
117   return new MEDFileFieldLoc(locName,geoType,refCoo,gsCoo,w);
118 }
119
120 MEDFileFieldLoc::MEDFileFieldLoc(med_idt fid, const std::string& locName):_name(locName)
121 {
122   med_geometry_type geotype;
123   med_geometry_type sectiongeotype;
124   int nsectionmeshcell;
125   INTERP_KERNEL::AutoPtr<char> geointerpname(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE));
126   INTERP_KERNEL::AutoPtr<char> sectionmeshname(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE));
127   MEDlocalizationInfoByName(fid,locName.c_str(),&geotype,&_dim,&_nb_gauss_pt,geointerpname,sectionmeshname,&nsectionmeshcell,&sectiongeotype);
128   _gt=new MEDFileGTKeeperSta((INTERP_KERNEL::NormalizedCellType)(std::distance(typmai3,std::find(typmai3,typmai3+34,geotype))));
129   const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(getGeoType()));
130   _nb_node_per_cell=cm.getNumberOfNodes();
131   _ref_coo.resize(_dim*_nb_node_per_cell);
132   _gs_coo.resize(_dim*_nb_gauss_pt);
133   _w.resize(_nb_gauss_pt);
134   MEDFILESAFECALLERRD0(MEDlocalizationRd,(fid,locName.c_str(),MED_FULL_INTERLACE,&_ref_coo[0],&_gs_coo[0],&_w[0]));
135 }
136
137 MEDFileFieldLoc::MEDFileFieldLoc(med_idt fid, int id, const MEDFileEntities *entities)
138 {
139   med_geometry_type geotype;
140   med_geometry_type sectiongeotype;
141   int nsectionmeshcell;
142   INTERP_KERNEL::AutoPtr<char> locName(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE));
143   INTERP_KERNEL::AutoPtr<char> geointerpname(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE));
144   INTERP_KERNEL::AutoPtr<char> sectionmeshname(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE));
145   MEDFILESAFECALLERRD0(MEDlocalizationInfo,(fid,id+1,locName,&geotype,&_dim,&_nb_gauss_pt,geointerpname,sectionmeshname,&nsectionmeshcell,&sectiongeotype));
146   _name=locName;
147   std::string sectionName(MEDLoaderBase::buildStringFromFortran(sectionmeshname,MED_NAME_SIZE));
148   if(sectionName.empty())
149     {
150       _gt=new MEDFileGTKeeperSta((INTERP_KERNEL::NormalizedCellType)(std::distance(typmai3,std::find(typmai3,typmai3+34,geotype))));
151       const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(getGeoType()));
152       _nb_node_per_cell=cm.getNumberOfNodes();
153     }
154   else
155     {
156       const MEDFileAllStaticEntitiesPlusDyn *entities2(dynamic_cast<const MEDFileAllStaticEntitiesPlusDyn *>(entities));
157       if(!entities2)
158         {
159           std::ostringstream oss; oss << "MEDFileFieldLoc cstr : for loc \"" << _name << "\" presence of non static type ! Expect entities !";
160           throw INTERP_KERNEL::Exception(oss.str());
161         }
162       const MEDFileStructureElement *se(entities2->getWithGT(geotype));
163       const MEDFileUMesh *um(entities2->getSupMeshWithName(se->getMeshName()));
164       const MEDFileUMesh *section(entities2->getSupMeshWithName(sectionName));
165       _gt=new MEDFileGTKeeperDyn(um,section,se);
166       {
167         int dummy;
168         MEDFILESAFECALLERRD0(MEDmeshGeotypeParameter,(fid,geotype,&dummy,&_nb_node_per_cell));
169       }
170     }
171   _ref_coo.resize(_dim*_nb_node_per_cell);
172   _gs_coo.resize(_dim*_nb_gauss_pt);
173   _w.resize(_nb_gauss_pt);
174   MEDFILESAFECALLERRD0(MEDlocalizationRd,(fid,locName,MED_FULL_INTERLACE,&_ref_coo[0],&_gs_coo[0],&_w[0]));
175 }
176
177 MEDFileFieldLoc::MEDFileFieldLoc(const std::string& locName, INTERP_KERNEL::NormalizedCellType geoType,
178                                  const std::vector<double>& refCoo, const std::vector<double>& gsCoo, const std::vector<double>& w):_name(locName),_gt(new MEDFileGTKeeperSta(geoType)),_ref_coo(refCoo),_gs_coo(gsCoo),_w(w)
179 {
180   const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(getGeoType()));
181   _dim=cm.getDimension();
182   _nb_node_per_cell=cm.getNumberOfNodes();
183   _nb_gauss_pt=_w.size();
184 }
185
186
187 MEDFileFieldLoc::MEDFileFieldLoc(const MEDFileFieldLoc& other):_dim(other._dim),_nb_gauss_pt(other._nb_gauss_pt),_gt(other._gt->deepCopy()),_nb_node_per_cell(other._nb_node_per_cell),_name(other._name),_ref_coo(other._ref_coo),_gs_coo(other._gs_coo),_w(other._w)
188 {
189 }
190
191 MEDFileFieldLoc *MEDFileFieldLoc::deepCopy() const
192 {
193   return new MEDFileFieldLoc(*this);
194 }
195
196 bool MEDFileFieldLoc::isOnStructureElement() const
197 {
198   const MEDFileGTKeeper *gt(_gt);
199   if(!gt)
200     throw INTERP_KERNEL::Exception("MEDFileFieldLoc::isOnStructureElement : null pointer !");
201   const MEDFileGTKeeperDyn *gt2(dynamic_cast<const MEDFileGTKeeperDyn *>(gt));
202   return gt2!=NULL;
203 }
204
205 std::size_t MEDFileFieldLoc::getHeapMemorySizeWithoutChildren() const
206 {
207   return (_ref_coo.capacity()+_gs_coo.capacity()+_w.capacity())*sizeof(double)+_name.capacity();
208 }
209
210 std::vector<const BigMemoryObject *> MEDFileFieldLoc::getDirectChildrenWithNull() const
211 {
212   return std::vector<const BigMemoryObject *>();
213 }
214
215 void MEDFileFieldLoc::simpleRepr(std::ostream& oss) const
216 {
217   static const char OFF7[]="\n    ";
218   oss << "\"" << _name << "\"" << OFF7;
219   oss << "GeoType=" << _gt->getRepr() << OFF7;
220   oss << "Dimension=" << _dim << OFF7;
221   oss << "Number of Gauss points=" << _nb_gauss_pt << OFF7;
222   oss << "Number of nodes per cell=" << _nb_node_per_cell << OFF7;
223   oss << "RefCoords="; std::copy(_ref_coo.begin(),_ref_coo.end(),std::ostream_iterator<double>(oss," ")); oss << OFF7;
224   oss << "Weights="; std::copy(_w.begin(),_w.end(),std::ostream_iterator<double>(oss," ")); oss << OFF7;
225   oss << "GaussPtsCoords="; std::copy(_gs_coo.begin(),_gs_coo.end(),std::ostream_iterator<double>(oss," ")); oss << std::endl;
226 }
227
228 void MEDFileFieldLoc::setName(const std::string& name)
229 {
230   _name=name;
231 }
232
233 bool MEDFileFieldLoc::isEqual(const MEDFileFieldLoc& other, double eps) const
234 {
235   if(_name!=other._name)
236     return false;
237   if(_dim!=other._dim)
238     return false;
239   if(_nb_gauss_pt!=other._nb_gauss_pt)
240     return false;
241   if(_nb_node_per_cell!=other._nb_node_per_cell)
242     return false;
243   if(!_gt->isEqual(other._gt))
244     return false;
245   if(!MEDCouplingGaussLocalization::AreAlmostEqual(_ref_coo,other._ref_coo,eps))
246     return false;
247   if(!MEDCouplingGaussLocalization::AreAlmostEqual(_gs_coo,other._gs_coo,eps))
248     return false;
249   if(!MEDCouplingGaussLocalization::AreAlmostEqual(_w,other._w,eps))
250     return false;
251
252   return true;
253 }
254
255 void MEDFileFieldLoc::writeLL(med_idt fid) const
256 {
257   MEDFILESAFECALLERWR0(MEDlocalizationWr,(fid,_name.c_str(),typmai3[(int)getGeoType()],_dim,&_ref_coo[0],MED_FULL_INTERLACE,_nb_gauss_pt,&_gs_coo[0],&_w[0],MED_NO_INTERPOLATION,MED_NO_MESH_SUPPORT));
258 }
259
260 std::string MEDFileFieldLoc::repr() const
261 {
262   std::ostringstream oss; oss.precision(15);
263   const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(getGeoType()));
264   oss << "Localization \"" << _name << "\" :\n" << "  - Geometric Type : " << cm.getRepr();
265   oss << "\n  - Dimension : " << _dim << "\n  - Number of gauss points : ";
266   oss << _nb_gauss_pt << "\n  - Number of nodes in cell : " << _nb_node_per_cell;
267   oss << "\n  - Ref coords are : ";
268   int sz=_ref_coo.size();
269   if(sz%_dim==0)
270     {
271       int nbOfTuples=sz/_dim;
272       for(int i=0;i<nbOfTuples;i++)
273         {
274           oss << "(";
275           for(int j=0;j<_dim;j++)
276             { oss << _ref_coo[i*_dim+j]; if(j!=_dim-1) oss << ", "; }
277           oss << ") ";
278         }
279     }
280   else
281     std::copy(_ref_coo.begin(),_ref_coo.end(),std::ostream_iterator<double>(oss," "));
282   oss << "\n  - Gauss coords in reference element : ";
283   sz=_gs_coo.size();
284   if(sz%_dim==0)
285     {
286       int nbOfTuples=sz/_dim;
287       for(int i=0;i<nbOfTuples;i++)
288         {
289           oss << "(";
290           for(int j=0;j<_dim;j++)
291             { oss << _gs_coo[i*_dim+j]; if(j!=_dim-1) oss << ", "; }
292           oss << ") ";
293         }
294     }
295   else
296     std::copy(_gs_coo.begin(),_gs_coo.end(),std::ostream_iterator<double>(oss," "));
297   oss << "\n  - Weights of Gauss coords are : "; std::copy(_w.begin(),_w.end(),std::ostream_iterator<double>(oss," "));
298   return oss.str();
299 }
300
301 void MEDFileFieldPerMeshPerTypePerDisc::assignFieldNoProfile(int& start, int offset, int nbOfCells, const MEDCouplingFieldTemplate *field, const DataArray *arrr, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc)
302 {
303   _type=field->getTypeOfField();
304   _start=start;
305   switch(_type)
306   {
307     case ON_CELLS:
308       {
309         getOrCreateAndGetArray()->setContigPartOfSelectedValuesSlice(_start,arrr,offset,offset+nbOfCells,1);
310         _end=_start+nbOfCells;
311         _nval=nbOfCells;
312         break;
313       }
314     case ON_GAUSS_NE:
315       {
316         MCAuto<DataArrayInt> arr=field->getDiscretization()->getOffsetArr(field->getMesh());
317         const int *arrPtr=arr->getConstPointer();
318         getOrCreateAndGetArray()->setContigPartOfSelectedValuesSlice(_start,arrr,arrPtr[offset],arrPtr[offset+nbOfCells],1);
319         _end=_start+(arrPtr[offset+nbOfCells]-arrPtr[offset]);
320         _nval=nbOfCells;
321         break;
322       }
323     case ON_GAUSS_PT:
324       {
325         const MEDCouplingFieldDiscretization *disc(field->getDiscretization());
326         const MEDCouplingGaussLocalization& gsLoc(field->getGaussLocalization(_loc_id));
327         const MEDCouplingFieldDiscretizationGauss *disc2(dynamic_cast<const MEDCouplingFieldDiscretizationGauss *>(disc));
328         if(!disc2)
329           throw INTERP_KERNEL::Exception("assignFieldNoProfile : invalid call to this method ! Internal Error !");
330         const DataArrayInt *dai(disc2->getArrayOfDiscIds());
331         MCAuto<DataArrayInt> dai2(disc2->getOffsetArr(field->getMesh()));
332         const int *dai2Ptr(dai2->getConstPointer());
333         int nbi(gsLoc.getWeights().size());
334         MCAuto<DataArrayInt> da2(dai->selectByTupleIdSafeSlice(offset,offset+nbOfCells,1));
335         MCAuto<DataArrayInt> da3(da2->findIdsEqual(_loc_id));
336         const int *da3Ptr(da3->getConstPointer());
337         if(da3->getNumberOfTuples()!=nbOfCells)
338           {//profile : for gauss even in NoProfile !!!
339             std::ostringstream oss; oss << "Pfl_" << nasc.getName() << "_" << INTERP_KERNEL::CellModel::GetCellModel(getGeoType()).getRepr() << "_" << _loc_id;
340             _profile=oss.str();
341             da3->setName(_profile.c_str());
342             glob.appendProfile(da3);
343           }
344         MCAuto<DataArrayInt> da4(DataArrayInt::New());
345         _nval=da3->getNbOfElems();
346         da4->alloc(_nval*nbi,1);
347         int *da4Ptr(da4->getPointer());
348         for(int i=0;i<_nval;i++)
349           {
350             int ref=dai2Ptr[offset+da3Ptr[i]];
351             for(int j=0;j<nbi;j++)
352               *da4Ptr++=ref+j;
353           }
354         std::ostringstream oss2; oss2 << "Loc_" << nasc.getName() << "_" << INTERP_KERNEL::CellModel::GetCellModel(getGeoType()).getRepr() << "_" << _loc_id;
355         _localization=oss2.str();
356         getOrCreateAndGetArray()->setContigPartOfSelectedValues(_start,arrr,da4);
357         _end=_start+_nval*nbi;
358         glob.appendLoc(_localization.c_str(),getGeoType(),gsLoc.getRefCoords(),gsLoc.getGaussCoords(),gsLoc.getWeights());
359         break;
360       }
361     default:
362       throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::assignFieldNoProfile : not implemented yet for such discretization type of field !");
363   }
364   start=_end;
365 }
366
367 /*!
368  * Leaf method of field with profile assignment. This method is the most general one. No optimization is done here.
369  * \param [in] pflName input containing name of profile if any. 0 if no profile (except for GAUSS_PT where a no profile can hide a profile when split by loc_id).
370  * \param [in] multiTypePfl is the end user profile specified in high level API
371  * \param [in] idsInPfl is the selection into the \a multiTypePfl whole profile that corresponds to the current geometric type.
372  * \param [in] locIds is the profile needed to be created for MED file format. It can be null if all cells of current geometric type are fetched in \a multiTypePfl.
373  *             \b WARNING if not null the MED file profile can be subdivided again in case of Gauss points.
374  * \param [in] mesh is the mesh coming from the MEDFileMesh instance in correspondence with the MEDFileField. The mesh inside the \a field is simply ignored.
375  */
376 void MEDFileFieldPerMeshPerTypePerDisc::assignFieldProfile(bool isPflAlone, int& start, const DataArrayInt *multiTypePfl, const DataArrayInt *idsInPfl, DataArrayInt *locIds, int nbOfEltsInWholeMesh, const MEDCouplingFieldTemplate *field, const DataArray *arrr, const MEDCouplingMesh *mesh, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc)
377 {
378   _profile.clear();
379   _type=field->getTypeOfField();
380   std::string pflName(multiTypePfl->getName());
381   std::ostringstream oss; oss << pflName;
382   if(_type!=ON_NODES)
383     {
384       if(!isPflAlone)
385         { const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(getGeoType()); oss << "_" <<  cm.getRepr(); }
386     }
387   else
388     { oss << "_NODE"; }
389   if(locIds)
390     {
391       if(pflName.empty())
392         throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::assignFieldProfile : existing profile with empty name !");
393       if(_type!=ON_GAUSS_PT)
394         {
395           locIds->setName(oss.str());
396           glob.appendProfile(locIds);
397           _profile=oss.str();
398         }
399     }
400   _start=start;
401   switch(_type)
402   {
403     case ON_NODES:
404       {
405         _nval=idsInPfl->getNumberOfTuples();
406         getOrCreateAndGetArray()->setContigPartOfSelectedValuesSlice(_start,arrr,0,arrr->getNumberOfTuples(),1);
407         _end=_start+_nval;
408         break;
409       }
410     case ON_CELLS:
411       {
412         _nval=idsInPfl->getNumberOfTuples();
413         getOrCreateAndGetArray()->setContigPartOfSelectedValues(_start,arrr,idsInPfl);
414         _end=_start+_nval;
415         break;
416       }
417     case ON_GAUSS_NE:
418       {
419         MCAuto<DataArrayInt> arr=field->getDiscretization()->getOffsetArr(mesh);
420         MCAuto<DataArrayInt> arr2=arr->deltaShiftIndex();
421         MCAuto<DataArrayInt> arr3=arr2->selectByTupleId(multiTypePfl->begin(),multiTypePfl->end());
422         arr3->computeOffsetsFull();
423         MCAuto<DataArrayInt> tmp=idsInPfl->buildExplicitArrByRanges(arr3);
424         int trueNval=tmp->getNumberOfTuples();
425         _nval=idsInPfl->getNumberOfTuples();
426         getOrCreateAndGetArray()->setContigPartOfSelectedValues(_start,arrr,tmp);
427         _end=_start+trueNval;
428         break;
429       }
430     case ON_GAUSS_PT:
431       {
432         const MEDCouplingFieldDiscretizationGauss *disc2=dynamic_cast<const MEDCouplingFieldDiscretizationGauss *>(field->getDiscretization());
433         if(!disc2)
434           throw INTERP_KERNEL::Exception("addNewEntryIfNecessaryGauss : invalid call to this method ! Internal Error !");
435         const DataArrayInt *da1=disc2->getArrayOfDiscIds();
436         const MEDCouplingGaussLocalization& gsLoc=field->getGaussLocalization(_loc_id);
437         MCAuto<DataArrayInt> da2=da1->selectByTupleId(idsInPfl->begin(),idsInPfl->end());
438         MCAuto<DataArrayInt> da3=da2->findIdsEqual(_loc_id);
439         MCAuto<DataArrayInt> da4=idsInPfl->selectByTupleId(da3->begin(),da3->end());
440         //
441         MCAuto<MEDCouplingMesh> mesh2=mesh->buildPart(multiTypePfl->begin(),multiTypePfl->end());
442         MCAuto<DataArrayInt> arr=disc2->getOffsetArr(mesh2);
443         //
444         MCAuto<DataArrayInt> tmp=DataArrayInt::New();
445         int trueNval=0;
446         for(const int *pt=da4->begin();pt!=da4->end();pt++)
447           trueNval+=arr->getIJ(*pt+1,0)-arr->getIJ(*pt,0);
448         tmp->alloc(trueNval,1);
449         int *tmpPtr=tmp->getPointer();
450         for(const int *pt=da4->begin();pt!=da4->end();pt++)
451           for(int j=arr->getIJ(*pt,0);j<arr->getIJ(*pt+1,0);j++)
452             *tmpPtr++=j;
453         //
454         _nval=da4->getNumberOfTuples();
455         getOrCreateAndGetArray()->setContigPartOfSelectedValues(_start,arrr,tmp);
456         _end=_start+trueNval;
457         oss << "_loc_" << _loc_id;
458         if(locIds)
459           {
460             MCAuto<DataArrayInt> da5=locIds->selectByTupleId(da3->begin(),da3->end());
461             da5->setName(oss.str());
462             glob.appendProfile(da5);
463             _profile=oss.str();
464           }
465         else
466           {
467             if(!da3->isIota(nbOfEltsInWholeMesh))
468               {
469                 da3->setName(oss.str());
470                 glob.appendProfile(da3);
471                 _profile=oss.str();
472               }
473           }
474         std::ostringstream oss2; oss2 << "Loc_" << nasc.getName() << "_" << INTERP_KERNEL::CellModel::GetCellModel(getGeoType()).getRepr() << "_" << _loc_id;
475         _localization=oss2.str();
476         glob.appendLoc(_localization.c_str(),getGeoType(),gsLoc.getRefCoords(),gsLoc.getGaussCoords(),gsLoc.getWeights());
477         break;
478       }
479     default:
480       throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::assignFieldProfile : not implemented yet for such discretization type of field !");
481   }
482   start=_end;
483 }
484
485 void MEDFileFieldPerMeshPerTypePerDisc::assignNodeFieldNoProfile(int& start, const MEDCouplingFieldTemplate *field, const DataArray *arrr, MEDFileFieldGlobsReal& glob)
486 {
487   _start=start;
488   _nval=arrr->getNumberOfTuples();
489   getOrCreateAndGetArray()->setContigPartOfSelectedValuesSlice(_start,arrr,0,_nval,1);
490   _end=_start+_nval;
491   start=_end;
492 }
493
494 MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMeshPerTypePerDisc::NewOnRead(MEDFileFieldPerMeshPerTypeCommon *fath, TypeOfField type, int profileIt, const PartDefinition *pd)
495 {
496   return new MEDFileFieldPerMeshPerTypePerDisc(fath,type,profileIt,pd);
497 }
498
499 MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMeshPerTypePerDisc::New(MEDFileFieldPerMeshPerTypeCommon *fath, TypeOfField type, int locId)
500 {
501   return new MEDFileFieldPerMeshPerTypePerDisc(fath,type,locId,std::string());
502 }
503
504 MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMeshPerTypePerDisc::New(const MEDFileFieldPerMeshPerTypePerDisc& other)
505 {
506   return new MEDFileFieldPerMeshPerTypePerDisc(other);
507 }
508
509 std::size_t MEDFileFieldPerMeshPerTypePerDisc::getHeapMemorySizeWithoutChildren() const
510 {
511   return _profile.capacity()+_localization.capacity()+sizeof(MEDFileFieldPerMeshPerTypePerDisc);
512 }
513
514 std::vector<const BigMemoryObject *> MEDFileFieldPerMeshPerTypePerDisc::getDirectChildrenWithNull() const
515 {
516   std::vector<const BigMemoryObject *> ret(1);
517   ret[0]=(const PartDefinition*)_pd;
518   return ret;
519 }
520
521 MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMeshPerTypePerDisc::deepCopy(MEDFileFieldPerMeshPerTypeCommon *father) const
522 {
523   MCAuto<MEDFileFieldPerMeshPerTypePerDisc> ret(new MEDFileFieldPerMeshPerTypePerDisc(*this));
524   ret->_father=father;
525   return ret.retn();
526 }
527
528 MEDFileFieldPerMeshPerTypePerDisc::MEDFileFieldPerMeshPerTypePerDisc(MEDFileFieldPerMeshPerTypeCommon *fath, TypeOfField atype, int profileIt, const PartDefinition *pd)
529 try:_type(atype),_father(fath),_profile_it(profileIt),_pd(const_cast<PartDefinition *>(pd))
530 {
531   if(pd)
532     pd->incrRef();
533 }
534 catch(INTERP_KERNEL::Exception& e)
535 {
536     throw e;
537 }
538
539 MEDFileFieldPerMeshPerTypePerDisc::MEDFileFieldPerMeshPerTypePerDisc(MEDFileFieldPerMeshPerTypeCommon *fath, TypeOfField type, int locId, const std::string& dummy):_type(type),_father(fath),_loc_id(locId)
540 {
541 }
542
543 MEDFileFieldPerMeshPerTypePerDisc::MEDFileFieldPerMeshPerTypePerDisc(const MEDFileFieldPerMeshPerTypePerDisc& other):RefCountObject(other),_type(other._type),_father(0),_start(other._start),_end(other._end),_nval(other._nval),_profile(other._profile),_localization(other._localization),_loc_id(other._loc_id),_profile_it(other._profile_it),_pd(other._pd),_tmp_work1(other._tmp_work1)
544 {
545 }
546
547 MEDFileFieldPerMeshPerTypePerDisc::MEDFileFieldPerMeshPerTypePerDisc():_type(ON_CELLS),_father(0),_start(-std::numeric_limits<int>::max()),_end(-std::numeric_limits<int>::max()),
548     _nval(-std::numeric_limits<int>::max()),_loc_id(-std::numeric_limits<int>::max())
549 {
550 }
551
552 void MEDFileFieldPerMeshPerTypePerDisc::goReadZeValuesInFile(med_idt fid, const std::string& fieldName, int nbOfCompo, int iteration, int order, med_entity_type menti, med_geometry_type mgeoti, unsigned char *startFeedingPtr)
553 {
554   const PartDefinition *pd(_pd);
555   if(!pd)
556     {
557       med_entity_type mentiCpy(menti);
558       INTERP_KERNEL::AutoPtr<char> locname(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE));
559       int nbi,tmp1;
560       med_int nbValsInFile(MEDfieldnValueWithProfileByName(fid,fieldName.c_str(),iteration,order,menti,mgeoti,_profile.c_str(),MED_COMPACT_PFLMODE,&tmp1,locname,&nbi));
561       if(nbValsInFile==0 && menti==MED_CELL)
562         {//
563           nbValsInFile=MEDfieldnValueWithProfileByName(fid,fieldName.c_str(),iteration,order,MED_DESCENDING_FACE,mgeoti,_profile.c_str(),MED_COMPACT_PFLMODE,&tmp1,locname,&nbi);
564           if(nbValsInFile==0)
565             {
566               nbValsInFile=MEDfieldnValueWithProfileByName(fid,fieldName.c_str(),iteration,order,MED_DESCENDING_EDGE,mgeoti,_profile.c_str(),MED_COMPACT_PFLMODE,&tmp1,locname,&nbi);
567               if(nbValsInFile!=0)
568                 { mentiCpy=MED_DESCENDING_EDGE; }
569             }
570           else
571             { mentiCpy=MED_DESCENDING_FACE; }
572         }
573       if(_end-_start!=nbValsInFile*nbi)
574         {
575           std::ostringstream oss; oss << "MEDFileFieldPerMeshPerTypePerDisc::goReadZeValuesInFile : The number of tuples to read is " << nbValsInFile << "*" << nbi <<  " (nb integration points) ! But in data structure it values " << _end-_start << " is expected !";
576           throw INTERP_KERNEL::Exception(oss.str());
577         }
578       MEDFILESAFECALLERRD0(MEDfieldValueWithProfileRd,(fid,fieldName.c_str(),iteration,order,mentiCpy,mgeoti,MED_COMPACT_PFLMODE,_profile.c_str(),MED_FULL_INTERLACE,MED_ALL_CONSTITUENT,startFeedingPtr));
579     }
580   else
581     {
582       if(!_profile.empty())
583         throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::goReadZeValuesInFile : not implemented !");
584       INTERP_KERNEL::AutoPtr<char> pflname(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE)),locname(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE));
585       int profilesize,nbi;
586       int overallNval(MEDfieldnValueWithProfile(fid,fieldName.c_str(),iteration,order,menti,mgeoti,_profile_it+1,MED_COMPACT_PFLMODE,pflname,&profilesize,locname,&nbi));
587       const SlicePartDefinition *spd(dynamic_cast<const SlicePartDefinition *>(pd));
588       if(spd)
589         {
590           int start,stop,step;
591           spd->getSlice(start,stop,step);
592           int nbOfEltsToLoad(DataArray::GetNumberOfItemGivenBES(start,stop,step,"MEDFileFieldPerMeshPerTypePerDisc::goReadZeValuesInFile"));
593           med_filter filter=MED_FILTER_INIT;
594           MEDFILESAFECALLERRD0(MEDfilterBlockOfEntityCr,(fid,/*nentity*/overallNval,/*nvaluesperentity*/nbi,/*nconstituentpervalue*/nbOfCompo,
595                                                          MED_ALL_CONSTITUENT,MED_FULL_INTERLACE,MED_COMPACT_STMODE,MED_NO_PROFILE,
596                                                          /*start*/start+1,/*stride*/step,/*count*/1,/*blocksize*/nbOfEltsToLoad,
597                                                          /*lastblocksize=useless because count=1*/0,&filter));
598           MEDFILESAFECALLERRD0(MEDfieldValueAdvancedRd,(fid,fieldName.c_str(),iteration,order,menti,mgeoti,&filter,startFeedingPtr));
599           MEDfilterClose(&filter);
600           return ;
601         }
602       const DataArrayPartDefinition *dpd(dynamic_cast<const DataArrayPartDefinition *>(pd));
603       if(dpd)
604         {
605           dpd->checkConsistencyLight();
606           MCAuto<DataArrayInt> myIds(dpd->toDAI());
607           int a(myIds->getMinValueInArray()),b(myIds->getMaxValueInArray());
608           myIds=myIds->deepCopy();// WARNING deep copy here because _pd is modified by applyLin !!!
609           myIds->applyLin(1,-a);
610           int nbOfEltsToLoad(b-a+1);
611           med_filter filter=MED_FILTER_INIT;
612           {//TODO : manage int32 !
613             MCAuto<DataArrayDouble> tmp(DataArrayDouble::New());
614             tmp->alloc(nbOfEltsToLoad,nbOfCompo);
615             MEDFILESAFECALLERRD0(MEDfilterBlockOfEntityCr,(fid,/*nentity*/overallNval,/*nvaluesperentity*/nbi,/*nconstituentpervalue*/nbOfCompo,
616                                                            MED_ALL_CONSTITUENT,MED_FULL_INTERLACE,MED_COMPACT_STMODE,MED_NO_PROFILE,
617                                                            /*start*/a+1,/*stride*/1,/*count*/1,/*blocksize*/nbOfEltsToLoad,
618                                                            /*lastblocksize=useless because count=1*/0,&filter));
619             MEDFILESAFECALLERRD0(MEDfieldValueAdvancedRd,(fid,fieldName.c_str(),iteration,order,menti,mgeoti,&filter,reinterpret_cast<unsigned char *>(tmp->getPointer())));
620             MCAuto<DataArrayDouble> feeder(DataArrayDouble::New());
621             feeder->useExternalArrayWithRWAccess(reinterpret_cast<double *>(startFeedingPtr),_nval,nbOfCompo);
622             feeder->setContigPartOfSelectedValues(0,tmp,myIds);
623           }
624           MEDfilterClose(&filter);
625         }
626       else
627         throw INTERP_KERNEL::Exception("Not implemented yet for not slices!");
628     }
629 }
630
631 const MEDFileFieldPerMeshPerTypeCommon *MEDFileFieldPerMeshPerTypePerDisc::getFather() const
632 {
633   return _father;
634 }
635
636 void MEDFileFieldPerMeshPerTypePerDisc::loadOnlyStructureOfDataRecursively(med_idt fid, int& start, const MEDFileFieldNameScope& nasc)
637 {
638   INTERP_KERNEL::AutoPtr<char> locname(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE));
639   INTERP_KERNEL::AutoPtr<char> pflname(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE));
640   std::string fieldName(nasc.getName()),meshName(getMeshName());
641   int iteration(getIteration()),order(getOrder()),profilesize,nbi;
642   TypeOfField type(getType());
643   med_geometry_type mgeoti;
644   med_entity_type menti;
645   _father->entriesForMEDfile(type,mgeoti,menti);
646   int zeNVal(MEDfieldnValueWithProfile(fid,fieldName.c_str(),iteration,order,menti,mgeoti,_profile_it+1,MED_COMPACT_PFLMODE,pflname,&profilesize,locname,&nbi));
647   if(zeNVal==0 && type==ON_CELLS)
648     {//eheh maybe there's a surprise :)
649       int zeNVal1(MEDfieldnValueWithProfile(fid,fieldName.c_str(),iteration,order,MED_DESCENDING_FACE,mgeoti,_profile_it+1,MED_COMPACT_PFLMODE,pflname,&profilesize,locname,&nbi));
650       if(zeNVal1==0)
651         {
652           int zeNVal2(MEDfieldnValueWithProfile(fid,fieldName.c_str(),iteration,order,MED_DESCENDING_EDGE,mgeoti,_profile_it+1,MED_COMPACT_PFLMODE,pflname,&profilesize,locname,&nbi));
653           if(zeNVal2!=0)
654             zeNVal=zeNVal2;
655         }
656       else
657         {
658           zeNVal=zeNVal1;
659         }
660     }
661   _profile=MEDLoaderBase::buildStringFromFortran(pflname,MED_NAME_SIZE);
662   _localization=MEDLoaderBase::buildStringFromFortran(locname,MED_NAME_SIZE);
663   const PartDefinition *pd(_pd);
664   if(!pd)
665     {
666       _nval=zeNVal;
667     }
668   else
669     {
670       if(!_profile.empty())
671         throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::loadOnlyStructureOfDataRecursively : profiles are not managed yet with part of def !");
672       _nval=pd->getNumberOfElems();
673     }
674   _start=start;
675   _end=start+_nval*nbi;
676   start=_end;
677   if(type==ON_CELLS && !_localization.empty())
678     {
679       if(_localization!="MED_GAUSS_ELNO")//For compatibility with MED2.3
680         setType(ON_GAUSS_PT);
681       else
682         {
683           setType(ON_GAUSS_NE);
684           _localization.clear();
685         }
686     }
687 }
688
689 void MEDFileFieldPerMeshPerTypePerDisc::loadBigArray(med_idt fid, const MEDFileFieldNameScope& nasc)
690 {
691   std::string fieldName(nasc.getName()),meshName(getMeshName());
692   int iteration(getIteration()),order(getOrder());
693   TypeOfField type(getType());
694   med_geometry_type mgeoti;
695   med_entity_type menti;
696   _father->entriesForMEDfile(type,mgeoti,menti);
697   if(_start>_end)
698     throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::loadBigArray : internal error in range !");
699   if(_start==_end)
700     return ;
701   DataArray *arr(getOrCreateAndGetArray());//arr is not null due to the spec of getOrCreateAndGetArray
702   if(_start<0 || _start>=arr->getNumberOfTuples())
703     {
704       std::ostringstream oss; oss << "MEDFileFieldPerMeshPerTypePerDisc::loadBigArray : Invalid start ("<< _start << ") regarding admissible range of allocated array [0," << arr->getNumberOfTuples() << ") !";
705       throw INTERP_KERNEL::Exception(oss.str());
706     }
707   if(_end<0 || _end>arr->getNumberOfTuples())
708     {
709       std::ostringstream oss; oss << "MEDFileFieldPerMeshPerTypePerDisc::loadBigArray : Invalid start ("<< _start << ") regarding admissible range of allocated array [0," << arr->getNumberOfTuples() << "] !";
710       throw INTERP_KERNEL::Exception(oss.str());
711     }
712   int nbOfCompo(arr->getNumberOfComponents());
713   DataArrayDouble *arrD(dynamic_cast<DataArrayDouble *>(arr));
714   if(arrD)
715     {
716       double *startFeeding(arrD->getPointer()+_start*nbOfCompo);
717       goReadZeValuesInFile(fid,fieldName,nbOfCompo,iteration,order,menti,mgeoti,reinterpret_cast<unsigned char*>(startFeeding));
718       return ;
719     }
720   DataArrayInt *arrI(dynamic_cast<DataArrayInt *>(arr));
721   if(arrI)
722     {
723       int *startFeeding(arrI->getPointer()+_start*nbOfCompo);
724       goReadZeValuesInFile(fid,fieldName,nbOfCompo,iteration,order,menti,mgeoti,reinterpret_cast<unsigned char*>(startFeeding));
725       return ;
726     }
727   DataArrayFloat *arrF(dynamic_cast<DataArrayFloat *>(arr));
728   if(arrF)
729     {
730       float *startFeeding(arrF->getPointer()+_start*nbOfCompo);
731       goReadZeValuesInFile(fid,fieldName,nbOfCompo,iteration,order,menti,mgeoti,reinterpret_cast<unsigned char*>(startFeeding));
732       return ;
733     }
734   throw INTERP_KERNEL::Exception("Error on array reading ! Unrecognized type of field ! Should be in FLOAT64 FLOAT32 or INT32 !");
735 }
736
737 /*!
738  * Set a \c this->_start **and** \c this->_end keeping the same delta between the two.
739  */
740 void MEDFileFieldPerMeshPerTypePerDisc::setNewStart(int newValueOfStart)
741 {
742   int delta=_end-_start;
743   _start=newValueOfStart;
744   _end=_start+delta;
745 }
746
747 int MEDFileFieldPerMeshPerTypePerDisc::getIteration() const
748 {
749   return _father->getIteration();
750 }
751
752 int MEDFileFieldPerMeshPerTypePerDisc::getOrder() const
753 {
754   return _father->getOrder();
755 }
756
757 double MEDFileFieldPerMeshPerTypePerDisc::getTime() const
758 {
759   return _father->getTime();
760 }
761
762 std::string MEDFileFieldPerMeshPerTypePerDisc::getMeshName() const
763 {
764   return _father->getMeshName();
765 }
766
767 void MEDFileFieldPerMeshPerTypePerDisc::simpleRepr(int bkOffset, std::ostream& oss, int id) const
768 {
769   const char startLine[]="    ## ";
770   std::string startLine2(bkOffset,' ');
771   startLine2+=startLine;
772   INTERP_KERNEL::AutoCppPtr<MEDCouplingFieldDiscretization> tmp(MEDCouplingFieldDiscretization::New(_type));
773   oss << startLine2 << "Localization #" << id << "." << std::endl;
774   oss << startLine2 << "  Type=" << tmp->getRepr() << "." << std::endl;
775   oss << startLine2 << "  This type discretization lies on profile : \"" << _profile << "\" and on the following localization : \"" << _localization << "\"." << std::endl;
776   oss << startLine2 << "  This type discretization has " << _end-_start << " tuples (start=" << _start << ", end=" << _end << ")." << std::endl;
777   oss << startLine2 << "  This type discretization has " << (_end-_start)/_nval << " integration points." << std::endl;
778 }
779
780 TypeOfField MEDFileFieldPerMeshPerTypePerDisc::getType() const
781 {
782   return _type;
783 }
784
785 INTERP_KERNEL::NormalizedCellType MEDFileFieldPerMeshPerTypePerDisc::getGeoType() const
786 {
787   return _father->getGeoType();
788 }
789
790 void MEDFileFieldPerMeshPerTypePerDisc::fillTypesOfFieldAvailable(std::set<TypeOfField>& types) const
791 {
792   types.insert(_type);
793 }
794
795 void MEDFileFieldPerMeshPerTypePerDisc::setType(TypeOfField newType)
796 {
797   _type=newType;
798 }
799
800 int MEDFileFieldPerMeshPerTypePerDisc::getNumberOfComponents() const
801 {
802   return _father->getNumberOfComponents();
803 }
804
805 int MEDFileFieldPerMeshPerTypePerDisc::getNumberOfTuples() const
806 {
807   return _end-_start;
808 }
809
810 void MEDFileFieldPerMeshPerTypePerDisc::incrementNbOfVals(int deltaNbVal)
811 {
812   int nbi((_end-_start)/_nval);
813   _nval+=deltaNbVal;
814   _end+=nbi*deltaNbVal;
815 }
816
817 DataArray *MEDFileFieldPerMeshPerTypePerDisc::getOrCreateAndGetArray()
818 {
819   return _father->getOrCreateAndGetArray();
820 }
821
822 const DataArray *MEDFileFieldPerMeshPerTypePerDisc::getOrCreateAndGetArray() const
823 {
824   const MEDFileFieldPerMeshPerTypeCommon *fath=_father;
825   return fath->getOrCreateAndGetArray();
826 }
827
828 const std::vector<std::string>& MEDFileFieldPerMeshPerTypePerDisc::getInfo() const
829 {
830   return _father->getInfo();
831 }
832
833 std::string MEDFileFieldPerMeshPerTypePerDisc::getProfile() const
834 {
835   return _profile;
836 }
837
838 void MEDFileFieldPerMeshPerTypePerDisc::setProfile(const std::string& newPflName)
839 {
840   _profile=newPflName;
841 }
842
843 std::string MEDFileFieldPerMeshPerTypePerDisc::getLocalization() const
844 {
845   return _localization;
846 }
847
848 void MEDFileFieldPerMeshPerTypePerDisc::setLocalization(const std::string& newLocName)
849 {
850   _localization=newLocName;
851 }
852
853 void MEDFileFieldPerMeshPerTypePerDisc::changePflsRefsNamesGen(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif)
854 {
855   for(std::vector< std::pair<std::vector<std::string>, std::string > >::const_iterator it2=mapOfModif.begin();it2!=mapOfModif.end();it2++)
856     {
857       if(std::find((*it2).first.begin(),(*it2).first.end(),_profile)!=(*it2).first.end())
858         {
859           _profile=(*it2).second;
860           return;
861         }
862     }
863 }
864
865 void MEDFileFieldPerMeshPerTypePerDisc::changeLocsRefsNamesGen(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif)
866 {
867   for(std::vector< std::pair<std::vector<std::string>, std::string > >::const_iterator it2=mapOfModif.begin();it2!=mapOfModif.end();it2++)
868     {
869       if(std::find((*it2).first.begin(),(*it2).first.end(),_localization)!=(*it2).first.end())
870         {
871           _localization=(*it2).second;
872           return;
873         }
874     }
875 }
876
877 void MEDFileFieldPerMeshPerTypePerDisc::getFieldAtLevel(TypeOfField type, const MEDFileFieldGlobsReal *glob, std::vector< std::pair<int,int> >& dads, std::vector<const DataArrayInt *>& pfls, std::vector<int>& locs, std::vector<INTERP_KERNEL::NormalizedCellType>& geoTypes) const
878 {
879   if(type!=_type)
880     return ;
881   dads.push_back(std::pair<int,int>(_start,_end));
882   geoTypes.push_back(getGeoType());
883   if(_profile.empty())
884     pfls.push_back(0);
885   else
886     {
887       pfls.push_back(glob->getProfile(_profile.c_str()));
888     }
889   if(_localization.empty())
890     locs.push_back(-1);
891   else
892     {
893       locs.push_back(glob->getLocalizationId(_localization.c_str()));
894     }
895 }
896
897 void MEDFileFieldPerMeshPerTypePerDisc::fillValues(int discId, int& startEntryId, std::vector< std::pair<std::pair<INTERP_KERNEL::NormalizedCellType,int>,std::pair<int,int> > >& entries) const
898 {
899   entries[startEntryId]=std::pair<std::pair<INTERP_KERNEL::NormalizedCellType,int> ,std::pair<int,int> >(std::pair<INTERP_KERNEL::NormalizedCellType,int>(getGeoType(),discId),std::pair<int,int>(_start,_end));
900   startEntryId++;
901 }
902
903 void MEDFileFieldPerMeshPerTypePerDisc::writeLL(med_idt fid, const MEDFileFieldNameScope& nasc) const
904 {
905   TypeOfField type=getType();
906   INTERP_KERNEL::NormalizedCellType geoType(getGeoType());
907   med_geometry_type mgeoti;
908   med_entity_type menti;
909   _father->entriesForMEDfile(getType(),mgeoti,menti);
910   const DataArray *arr(getOrCreateAndGetArray());
911   if(!arr)
912     throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::writeLL : no array set !");
913   if(!arr->isAllocated())
914     throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::writeLL : the array to be written is not allocated !");
915   const DataArrayDouble *arrD(dynamic_cast<const DataArrayDouble *>(arr));
916   const DataArrayInt *arrI(dynamic_cast<const DataArrayInt *>(arr));
917   const DataArrayFloat *arrF(dynamic_cast<const DataArrayFloat *>(arr));
918   const unsigned char *locToWrite=0;
919   if(arrD)
920     locToWrite=reinterpret_cast<const unsigned char *>(arrD->getConstPointer()+_start*arr->getNumberOfComponents());
921   else if(arrI)
922     locToWrite=reinterpret_cast<const unsigned char *>(arrI->getConstPointer()+_start*arr->getNumberOfComponents());
923   else if(arrF)
924     locToWrite=reinterpret_cast<const unsigned char *>(arrF->getConstPointer()+_start*arr->getNumberOfComponents());
925   else
926     throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::writeLL : not recognized type of values ! Supported are FLOAT64 FLOAT32 and INT32 !");
927   MEDFILESAFECALLERWR0(MEDfieldValueWithProfileWr,(fid,nasc.getName().c_str(),getIteration(),getOrder(),getTime(),menti,mgeoti,
928                                                    MED_COMPACT_PFLMODE,_profile.c_str(),_localization.c_str(),MED_FULL_INTERLACE,MED_ALL_CONSTITUENT,_nval,
929                                                    locToWrite));
930 }
931
932 void MEDFileFieldPerMeshPerTypePerDisc::getCoarseData(TypeOfField& type, std::pair<int,int>& dad, std::string& pfl, std::string& loc) const
933 {
934   type=_type;
935   pfl=_profile;
936   loc=_localization;
937   dad.first=_start; dad.second=_end;
938 }
939
940 /*!
941  * \param [in] codeOfMesh is of format returned by MEDCouplingUMesh::getDistributionOfTypes. And for each *i* oldCode[3*i+2] gives the position (MEDFileUMesh::PutInThirdComponentOfCodeOffset).
942  *             This code corresponds to the distribution of types in the corresponding mesh.
943  * \param [out] ptToFill memory zone where the output will be stored.
944  * \return the size of data pushed into output param \a ptToFill
945  */
946 int MEDFileFieldPerMeshPerTypePerDisc::fillEltIdsFromCode(int offset, const std::vector<int>& codeOfMesh, const MEDFileFieldGlobsReal& glob, int *ptToFill) const
947 {
948   _loc_id=offset;
949   std::ostringstream oss;
950   std::size_t nbOfType=codeOfMesh.size()/3;
951   int found=-1;
952   for(std::size_t i=0;i<nbOfType && found==-1;i++)
953     if(getGeoType()==(INTERP_KERNEL::NormalizedCellType)codeOfMesh[3*i])
954       found=(int)i;
955   if(found==-1)
956     {
957       const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(getGeoType());
958       oss << "MEDFileFieldPerMeshPerTypePerDisc::fillEltIdsFromCode : not found geometric type " << cm.getRepr() << " in the referenced mesh of field !";
959       throw INTERP_KERNEL::Exception(oss.str());
960     }
961   int *work=ptToFill;
962   if(_profile.empty())
963     {
964       if(_nval!=codeOfMesh[3*found+1])
965         {
966           const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(getGeoType());
967           oss << "MEDFileFieldPerMeshPerTypePerDisc::fillEltIdsFromCode : for geometric type " << cm.getRepr() << " number of elt ids in mesh is equal to " << _nval;
968           oss << " whereas mesh has " << codeOfMesh[3*found+1] << " for this geometric type !";
969           throw INTERP_KERNEL::Exception(oss.str());
970         }
971       for(int ii=codeOfMesh[3*found+2];ii<codeOfMesh[3*found+2]+_nval;ii++)
972         *work++=ii;
973     }
974   else
975     {
976       const DataArrayInt *pfl=glob.getProfile(_profile.c_str());
977       if(pfl->getNumberOfTuples()!=_nval)
978         {
979           const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(getGeoType());
980           oss << "MEDFileFieldPerMeshPerTypePerDisc::fillEltIdsFromCode : for geometric type " << cm.getRepr() << ", field is defined on profile \"" << _profile << "\" and size of profile is ";
981           oss << _nval;
982           oss << pfl->getNumberOfTuples() << " whereas the number of ids is set to " << _nval << " for this geometric type !";
983           throw INTERP_KERNEL::Exception(oss.str());
984         }
985       int offset2=codeOfMesh[3*found+2];
986       for(const int *pflId=pfl->begin();pflId!=pfl->end();pflId++)
987         {
988           if(*pflId<codeOfMesh[3*found+1])
989             *work++=offset2+*pflId;
990         }
991     }
992   return _nval;
993 }
994
995 int MEDFileFieldPerMeshPerTypePerDisc::fillTupleIds(int *ptToFill) const
996 {
997   for(int i=_start;i<_end;i++)
998     *ptToFill++=i;
999   return _end-_start;
1000 }
1001
1002 int MEDFileFieldPerMeshPerTypePerDisc::ConvertType(TypeOfField type, int locId)
1003 {
1004   switch(type)
1005   {
1006     case ON_CELLS:
1007       return -2;
1008     case ON_GAUSS_NE:
1009       return -1;
1010     case ON_GAUSS_PT:
1011       return locId;
1012     default:
1013       throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::ConvertType : not managed type of field !");
1014   }
1015 }
1016
1017 std::vector< std::vector< const MEDFileFieldPerMeshPerTypePerDisc *> > MEDFileFieldPerMeshPerTypePerDisc::SplitPerDiscretization(const std::vector< const MEDFileFieldPerMeshPerTypePerDisc *>& entries)
1018 {
1019   int id=0;
1020   std::map<std::pair<std::string,TypeOfField>,int> m;
1021   std::vector< std::vector< const MEDFileFieldPerMeshPerTypePerDisc *> > ret;
1022   for(std::vector< const MEDFileFieldPerMeshPerTypePerDisc *>::const_iterator it=entries.begin();it!=entries.end();it++)
1023     if(m.find(std::pair<std::string,TypeOfField>((*it)->getLocalization(),(*it)->getType()))==m.end())
1024       m[std::pair<std::string,TypeOfField>((*it)->getLocalization(),(*it)->getType())]=id++;
1025   ret.resize(id);
1026   for(std::vector< const MEDFileFieldPerMeshPerTypePerDisc *>::const_iterator it=entries.begin();it!=entries.end();it++)
1027     ret[m[std::pair<std::string,TypeOfField>((*it)->getLocalization(),(*it)->getType())]].push_back(*it);
1028   return ret;
1029 }
1030
1031 /*!
1032  * - \c this->_loc_id mutable attribute is used for elt id in mesh offsets.
1033  *
1034  * \param [in] offset the offset id used to take into account that \a result is not compulsory empty in input
1035  * \param [in] entriesOnSameDisc some entries **on same localization** if not the result can be invalid. The _start and _end on them are relative to \a arr parameter.
1036  * \param [in] explicitIdsInMesh ids in mesh of the considered chunk.
1037  * \param [in] newCode one of the input parameter to explicit the new geo type dispatch (in classical format same than those asked by MEDFileFields::renumberEntitiesLyingOnMesh)
1038  * \param [in,out] glob if necessary by the method, new profiles can be added to it
1039  * \param [in,out] arr after the call of this method \a arr is renumbered to be compliant with added entries to \a result.
1040  * \param [out] result All new entries will be appended on it.
1041  * \return false if the configuration of renumbering leads to an unnecessary resplit of input \a entriesOnSameDisc. If not true is returned (the most general case !)
1042  */
1043 bool MEDFileFieldPerMeshPerTypePerDisc::RenumberChunks(int offset, const std::vector< const MEDFileFieldPerMeshPerTypePerDisc *>& entriesOnSameDisc,
1044                                                        const DataArrayInt *explicitIdsInMesh,
1045                                                        const std::vector<int>& newCode,
1046                                                        MEDFileFieldGlobsReal& glob, DataArrayDouble *arr,
1047                                                        std::vector< MCAuto<MEDFileFieldPerMeshPerTypePerDisc> >& result)
1048 {
1049   if(entriesOnSameDisc.empty())
1050     return false;
1051   TypeOfField type=entriesOnSameDisc[0]->getType();
1052   int szEntities=0,szTuples=0;
1053   for(std::vector< const MEDFileFieldPerMeshPerTypePerDisc *>::const_iterator it=entriesOnSameDisc.begin();it!=entriesOnSameDisc.end();it++)
1054     { szEntities+=(*it)->_nval; szTuples+=(*it)->_end-(*it)->_start; }
1055   int nbi=szTuples/szEntities;
1056   if(szTuples%szEntities!=0)
1057     throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::RenumberChunks : internal error the splitting into same dicretization failed !");
1058   MCAuto<DataArrayInt> renumTuples=DataArrayInt::New(); renumTuples->alloc(szTuples,1);
1059   MCAuto<DataArrayInt> ranges=MEDCouplingUMesh::ComputeRangesFromTypeDistribution(newCode);
1060   std::vector< MCAuto<DataArrayInt> > newGeoTypesPerChunk(entriesOnSameDisc.size());
1061   std::vector< const DataArrayInt * > newGeoTypesPerChunk2(entriesOnSameDisc.size());
1062   std::vector< MCAuto<DataArrayInt> > newGeoTypesPerChunk_bis(entriesOnSameDisc.size());
1063   std::vector< const DataArrayInt * > newGeoTypesPerChunk3(entriesOnSameDisc.size());
1064   MCAuto<DataArrayInt> newGeoTypesPerChunk4=DataArrayInt::New(); newGeoTypesPerChunk4->alloc(szEntities,nbi);
1065   int id=0;
1066   for(std::vector< const MEDFileFieldPerMeshPerTypePerDisc *>::const_iterator it=entriesOnSameDisc.begin();it!=entriesOnSameDisc.end();it++,id++)
1067     {
1068       int startOfEltIdOfChunk=(*it)->_start;
1069       MCAuto<DataArrayInt> newEltIds=explicitIdsInMesh->subArray(startOfEltIdOfChunk,startOfEltIdOfChunk+(*it)->_nval);
1070       MCAuto<DataArrayInt> rangeIdsForChunk=newEltIds->findRangeIdForEachTuple(ranges);
1071       MCAuto<DataArrayInt> idsInRrangeForChunk=newEltIds->findIdInRangeForEachTuple(ranges);
1072       //
1073       MCAuto<DataArrayInt> tmp=rangeIdsForChunk->duplicateEachTupleNTimes(nbi); rangeIdsForChunk->rearrange(nbi);
1074       newGeoTypesPerChunk4->setPartOfValues1(tmp,(*it)->_tmp_work1-offset,(*it)->_tmp_work1+(*it)->_nval*nbi-offset,1,0,nbi,1);
1075       //
1076       newGeoTypesPerChunk[id]=rangeIdsForChunk; newGeoTypesPerChunk2[id]=rangeIdsForChunk;
1077       newGeoTypesPerChunk_bis[id]=idsInRrangeForChunk; newGeoTypesPerChunk3[id]=idsInRrangeForChunk;
1078     }
1079   MCAuto<DataArrayInt> newGeoTypesEltIdsAllGather=DataArrayInt::Aggregate(newGeoTypesPerChunk2); newGeoTypesPerChunk.clear(); newGeoTypesPerChunk2.clear();
1080   MCAuto<DataArrayInt> newGeoTypesEltIdsAllGather2=DataArrayInt::Aggregate(newGeoTypesPerChunk3); newGeoTypesPerChunk_bis.clear(); newGeoTypesPerChunk3.clear();
1081   MCAuto<DataArrayInt> diffVals=newGeoTypesEltIdsAllGather->getDifferentValues();
1082   MCAuto<DataArrayInt> renumEltIds=newGeoTypesEltIdsAllGather->buildPermArrPerLevel();
1083   //
1084   MCAuto<DataArrayInt> renumTupleIds=newGeoTypesPerChunk4->buildPermArrPerLevel();
1085   //
1086   MCAuto<DataArrayDouble> arrPart=arr->subArray(offset,offset+szTuples);
1087   arrPart->renumberInPlace(renumTupleIds->begin());
1088   arr->setPartOfValues1(arrPart,offset,offset+szTuples,1,0,arrPart->getNumberOfComponents(),1);
1089   bool ret=false;
1090   const int *idIt=diffVals->begin();
1091   std::list<const MEDFileFieldPerMeshPerTypePerDisc *> li(entriesOnSameDisc.begin(),entriesOnSameDisc.end());
1092   int offset2=0;
1093   for(int i=0;i<diffVals->getNumberOfTuples();i++,idIt++)
1094     {
1095       MCAuto<DataArrayInt> ids=newGeoTypesEltIdsAllGather->findIdsEqual(*idIt);
1096       MCAuto<DataArrayInt> subIds=newGeoTypesEltIdsAllGather2->selectByTupleId(ids->begin(),ids->end());
1097       int nbEntityElts=subIds->getNumberOfTuples();
1098       bool ret2;
1099       MCAuto<MEDFileFieldPerMeshPerTypePerDisc> eltToAdd=MEDFileFieldPerMeshPerTypePerDisc::
1100           NewObjectOnSameDiscThanPool(type,(INTERP_KERNEL::NormalizedCellType)newCode[3*(*idIt)],subIds,!subIds->isIota(newCode[3*(*idIt)+1]),nbi,
1101                                       offset+offset2,
1102                                       li,glob,ret2);
1103       ret=ret || ret2;
1104       result.push_back(eltToAdd);
1105       offset2+=nbEntityElts*nbi;
1106     }
1107   ret=ret || li.empty();
1108   return ret;
1109 }
1110
1111 /*!
1112  * \param [in] typeF type of field of new chunk
1113  * \param [in] geoType the geometric type of the chunk
1114  * \param [in] idsOfMeshElt the entity ids of mesh (cells or nodes) of the new chunk.
1115  * \param [in] isPfl specifies if a profile is requested regarding size of \a idsOfMeshElt and the number of such entities regarding underlying mesh.
1116  * \param [in] nbi number of integration points
1117  * \param [in] offset The offset in the **global array of data**.
1118  * \param [in,out] entriesOnSameDisc the pool **on the same discretization** inside which it will be attempted to find an existing entry corresponding exactly
1119  *                 to the new chunk to create.
1120  * \param [in,out] glob the global shared info that will be requested for existing profiles or to append a new profile if needed.
1121  * \param [out] notInExisting If false the return newly allocated entry is not coming from \a entriesOnSameDisc. If true the output comes from copy of \a entriesOnSameDisc
1122  *              and corresponding entry erased from \a entriesOnSameDisc.
1123  * \return a newly allocated chunk
1124  */
1125 MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMeshPerTypePerDisc::NewObjectOnSameDiscThanPool(TypeOfField typeF, INTERP_KERNEL::NormalizedCellType geoType, DataArrayInt *idsOfMeshElt,
1126                                                                                                   bool isPfl, int nbi, int offset,
1127                                                                                                   std::list< const MEDFileFieldPerMeshPerTypePerDisc *>& entriesOnSameDisc,
1128                                                                                                   MEDFileFieldGlobsReal& glob,
1129                                                                                                   bool &notInExisting)
1130 {
1131   int nbMeshEntities=idsOfMeshElt->getNumberOfTuples();
1132   std::list< const MEDFileFieldPerMeshPerTypePerDisc *>::iterator it=entriesOnSameDisc.begin();
1133   for(;it!=entriesOnSameDisc.end();it++)
1134     {
1135       if(((INTERP_KERNEL::NormalizedCellType)(*it)->_loc_id)==geoType && (*it)->_nval==nbMeshEntities)
1136         {
1137           if(!isPfl)
1138             {
1139               if((*it)->_profile.empty())
1140                 break;
1141               else
1142                 if(!(*it)->_profile.empty())
1143                   {
1144                     const DataArrayInt *pfl=glob.getProfile((*it)->_profile.c_str());
1145                     if(pfl->isEqualWithoutConsideringStr(*idsOfMeshElt))
1146                       break;
1147                   }
1148             }
1149         }
1150     }
1151   if(it==entriesOnSameDisc.end())
1152     {
1153       notInExisting=true;
1154       MEDFileFieldPerMeshPerTypePerDisc *ret=new MEDFileFieldPerMeshPerTypePerDisc;
1155       ret->_type=typeF;
1156       ret->_loc_id=(int)geoType;
1157       ret->_nval=nbMeshEntities;
1158       ret->_start=offset;
1159       ret->_end=ret->_start+ret->_nval*nbi;
1160       if(isPfl)
1161         {
1162           idsOfMeshElt->setName(glob.createNewNameOfPfl().c_str());
1163           glob.appendProfile(idsOfMeshElt);
1164           ret->_profile=idsOfMeshElt->getName();
1165         }
1166       //tony treatment of localization
1167       return ret;
1168     }
1169   else
1170     {
1171       notInExisting=false;
1172       MEDFileFieldPerMeshPerTypePerDisc *ret=MEDFileFieldPerMeshPerTypePerDisc::New(*(*it));
1173       ret->_loc_id=(int)geoType;
1174       ret->setNewStart(offset);
1175       entriesOnSameDisc.erase(it);
1176       return ret;
1177     }
1178
1179 }
1180
1181 ////////////////////////////////////
1182
1183 MEDFileFieldPerMeshPerTypeCommon::~MEDFileFieldPerMeshPerTypeCommon()
1184 {
1185 }
1186
1187 void MEDFileFieldPerMeshPerTypeCommon::setFather(MEDFileFieldPerMesh *father)
1188 {
1189   _father=father;
1190 }
1191
1192 void MEDFileFieldPerMeshPerTypeCommon::accept(MEDFileFieldVisitor& visitor) const
1193 {
1194   for(std::vector< MCAuto<MEDFileFieldPerMeshPerTypePerDisc> >::const_iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++)
1195     if((*it).isNotNull())
1196       {
1197         visitor.newPerMeshPerTypePerDisc(*it);
1198       }
1199 }
1200
1201 void MEDFileFieldPerMeshPerTypeCommon::deepCopyElements()
1202 {
1203   std::size_t i=0;
1204   for(std::vector< MCAuto<MEDFileFieldPerMeshPerTypePerDisc> >::const_iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++,i++)
1205     {
1206       if((const MEDFileFieldPerMeshPerTypePerDisc *)*it)
1207         _field_pm_pt_pd[i]=(*it)->deepCopy(this);
1208     }
1209 }
1210
1211 std::size_t MEDFileFieldPerMeshPerTypeCommon::getHeapMemorySizeWithoutChildren() const
1212 {
1213   return _field_pm_pt_pd.capacity()*sizeof(MCAuto<MEDFileFieldPerMeshPerTypePerDisc>);
1214 }
1215
1216 std::vector<const BigMemoryObject *> MEDFileFieldPerMeshPerTypeCommon::getDirectChildrenWithNull() const
1217 {
1218   std::vector<const BigMemoryObject *> ret;
1219   for(std::vector< MCAuto<MEDFileFieldPerMeshPerTypePerDisc> >::const_iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++)
1220     ret.push_back((const MEDFileFieldPerMeshPerTypePerDisc *)*it);
1221   return ret;
1222 }
1223
1224 void MEDFileFieldPerMeshPerTypeCommon::assignFieldNoProfile(int& start, int offset, int nbOfCells, const MEDCouplingFieldTemplate *field, const DataArray *arr, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc)
1225 {
1226   std::vector<int> pos=addNewEntryIfNecessary(field,offset,nbOfCells);
1227   for(std::vector<int>::const_iterator it=pos.begin();it!=pos.end();it++)
1228     _field_pm_pt_pd[*it]->assignFieldNoProfile(start,offset,nbOfCells,field,arr,glob,nasc);
1229 }
1230
1231 /*!
1232  * This method is the most general one. No optimization is done here.
1233  * \param [in] multiTypePfl is the end user profile specified in high level API
1234  * \param [in] idsInPfl is the selection into the \a multiTypePfl whole profile that corresponds to the current geometric type.
1235  * \param [in] locIds is the profile needed to be created for MED file format. It can be null if all cells of current geometric type are fetched in \a multiTypePfl.
1236  *             \b WARNING if not null the MED file profile can be subdivided again in case of Gauss points.
1237  * \param [in] nbOfEltsInWholeMesh nb of elts of type \a this->_geo_type in \b WHOLE mesh
1238  * \param [in] mesh is the mesh coming from the MEDFileMesh instance in correspondence with the MEDFileField. The mesh inside the \a field is simply ignored.
1239  */
1240 void MEDFileFieldPerMeshPerTypeCommon::assignFieldProfile(bool isPflAlone, int& start, const DataArrayInt *multiTypePfl, const DataArrayInt *idsInPfl, DataArrayInt *locIds, int nbOfEltsInWholeMesh, const MEDCouplingFieldTemplate *field, const DataArray *arr, const MEDCouplingMesh *mesh, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc)
1241 {
1242   std::vector<int> pos=addNewEntryIfNecessary(field,idsInPfl);
1243   for(std::vector<int>::const_iterator it=pos.begin();it!=pos.end();it++)
1244     _field_pm_pt_pd[*it]->assignFieldProfile(isPflAlone,start,multiTypePfl,idsInPfl,locIds,nbOfEltsInWholeMesh,field,arr,mesh,glob,nasc);
1245 }
1246
1247 void MEDFileFieldPerMeshPerTypeCommon::assignNodeFieldNoProfile(int& start, const MEDCouplingFieldTemplate *field, const DataArray *arr, MEDFileFieldGlobsReal& glob)
1248 {
1249   _field_pm_pt_pd.resize(1);
1250   _field_pm_pt_pd[0]=MEDFileFieldPerMeshPerTypePerDisc::New(this,ON_NODES,-3);
1251   _field_pm_pt_pd[0]->assignNodeFieldNoProfile(start,field,arr,glob);
1252 }
1253
1254 void MEDFileFieldPerMeshPerTypeCommon::assignNodeFieldProfile(int& start, const DataArrayInt *pfl, const MEDCouplingFieldTemplate *field, const DataArray *arr, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc)
1255 {
1256   MCAuto<DataArrayInt> pfl2=pfl->deepCopy();
1257   if(!arr || !arr->isAllocated())
1258     throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypeCommon::assignNodeFieldProfile : input array is null, or not allocated !");
1259   _field_pm_pt_pd.resize(1);
1260   _field_pm_pt_pd[0]=MEDFileFieldPerMeshPerTypePerDisc::New(this,ON_NODES,-3);
1261   _field_pm_pt_pd[0]->assignFieldProfile(true,start,pfl,pfl2,pfl2,-1,field,arr,0,glob,nasc);//mesh is not requested so 0 is send.
1262 }
1263
1264 std::vector<int> MEDFileFieldPerMeshPerTypeCommon::addNewEntryIfNecessary(const MEDCouplingFieldTemplate *field, int offset, int nbOfCells)
1265 {
1266   TypeOfField type=field->getTypeOfField();
1267   if(type!=ON_GAUSS_PT)
1268     {
1269       int locIdToFind=MEDFileFieldPerMeshPerTypePerDisc::ConvertType(type,0);
1270       int sz=_field_pm_pt_pd.size();
1271       bool found=false;
1272       for(int j=0;j<sz && !found;j++)
1273         {
1274           if(_field_pm_pt_pd[j]->getLocId()==locIdToFind)
1275             {
1276               _field_pm_pt_pd[j]=MEDFileFieldPerMeshPerTypePerDisc::New(this,type,locIdToFind);
1277               found=true;
1278             }
1279         }
1280       if(!found)
1281         {
1282           _field_pm_pt_pd.resize(sz+1);
1283           _field_pm_pt_pd[sz]=MEDFileFieldPerMeshPerTypePerDisc::New(this,type,locIdToFind);
1284         }
1285       std::vector<int> ret(1,(int)sz);
1286       return ret;
1287     }
1288   else
1289     {
1290       std::vector<int> ret2=addNewEntryIfNecessaryGauss(field,offset,nbOfCells);
1291       int sz2=ret2.size();
1292       std::vector<int> ret3(sz2);
1293       int k=0;
1294       for(int i=0;i<sz2;i++)
1295         {
1296           int sz=_field_pm_pt_pd.size();
1297           int locIdToFind=ret2[i];
1298           bool found=false;
1299           for(int j=0;j<sz && !found;j++)
1300             {
1301               if(_field_pm_pt_pd[j]->getLocId()==locIdToFind)
1302                 {
1303                   _field_pm_pt_pd[j]=MEDFileFieldPerMeshPerTypePerDisc::New(this,type,locIdToFind);
1304                   ret3[k++]=j;
1305                   found=true;
1306                 }
1307             }
1308           if(!found)
1309             {
1310               _field_pm_pt_pd.resize(sz+1);
1311               _field_pm_pt_pd[sz]=MEDFileFieldPerMeshPerTypePerDisc::New(this,type,locIdToFind);
1312               ret3[k++]=sz;
1313             }
1314         }
1315       return ret3;
1316     }
1317 }
1318
1319 std::vector<int> MEDFileFieldPerMeshPerTypeCommon::addNewEntryIfNecessaryGauss(const MEDCouplingFieldTemplate *field, int offset, int nbOfCells)
1320 {
1321   const MEDCouplingFieldDiscretization *disc=field->getDiscretization();
1322   const MEDCouplingFieldDiscretizationGauss *disc2=dynamic_cast<const MEDCouplingFieldDiscretizationGauss *>(disc);
1323   if(!disc2)
1324     throw INTERP_KERNEL::Exception("addNewEntryIfNecessaryGauss : invalid call to this method ! Internal Error !");
1325   const DataArrayInt *da=disc2->getArrayOfDiscIds();
1326   if(!da)
1327     throw INTERP_KERNEL::Exception("addNewEntryIfNecessaryGauss (no profile) : no localization ids per cell array available ! The input Gauss node field is maybe invalid !");
1328   MCAuto<DataArrayInt> da2=da->selectByTupleIdSafeSlice(offset,offset+nbOfCells,1);
1329   MCAuto<DataArrayInt> retTmp=da2->getDifferentValues();
1330   if(retTmp->presenceOfValue(-1))
1331     throw INTERP_KERNEL::Exception("addNewEntryIfNecessaryGauss : some cells have no dicretization description !");
1332   std::vector<int> ret(retTmp->begin(),retTmp->end());
1333   return ret;
1334 }
1335
1336 std::vector<int> MEDFileFieldPerMeshPerTypeCommon::addNewEntryIfNecessary(const MEDCouplingFieldTemplate *field, const DataArrayInt *subCells)
1337 {
1338   TypeOfField type=field->getTypeOfField();
1339   if(type!=ON_GAUSS_PT)
1340     {
1341       int locIdToFind=MEDFileFieldPerMeshPerTypePerDisc::ConvertType(type,0);
1342       int sz=_field_pm_pt_pd.size();
1343       bool found=false;
1344       for(int j=0;j<sz && !found;j++)
1345         {
1346           if(_field_pm_pt_pd[j]->getLocId()==locIdToFind)
1347             {
1348               _field_pm_pt_pd[j]=MEDFileFieldPerMeshPerTypePerDisc::New(this,type,locIdToFind);
1349               found=true;
1350             }
1351         }
1352       if(!found)
1353         {
1354           _field_pm_pt_pd.resize(sz+1);
1355           _field_pm_pt_pd[sz]=MEDFileFieldPerMeshPerTypePerDisc::New(this,type,locIdToFind);
1356         }
1357       std::vector<int> ret(1,0);
1358       return ret;
1359     }
1360   else
1361     {
1362       std::vector<int> ret2=addNewEntryIfNecessaryGauss(field,subCells);
1363       int sz2=ret2.size();
1364       std::vector<int> ret3(sz2);
1365       int k=0;
1366       for(int i=0;i<sz2;i++)
1367         {
1368           int sz=_field_pm_pt_pd.size();
1369           int locIdToFind=ret2[i];
1370           bool found=false;
1371           for(int j=0;j<sz && !found;j++)
1372             {
1373               if(_field_pm_pt_pd[j]->getLocId()==locIdToFind)
1374                 {
1375                   _field_pm_pt_pd[j]=MEDFileFieldPerMeshPerTypePerDisc::New(this,type,locIdToFind);
1376                   ret3[k++]=j;
1377                   found=true;
1378                 }
1379             }
1380           if(!found)
1381             {
1382               _field_pm_pt_pd.resize(sz+1);
1383               _field_pm_pt_pd[sz]=MEDFileFieldPerMeshPerTypePerDisc::New(this,type,locIdToFind);
1384               ret3[k++]=sz;
1385             }
1386         }
1387       return ret3;
1388     }
1389 }
1390
1391 std::vector<int> MEDFileFieldPerMeshPerTypeCommon::addNewEntryIfNecessaryGauss(const MEDCouplingFieldTemplate *field, const DataArrayInt *subCells)
1392 {
1393   const MEDCouplingFieldDiscretization *disc=field->getDiscretization();
1394   const MEDCouplingFieldDiscretizationGauss *disc2=dynamic_cast<const MEDCouplingFieldDiscretizationGauss *>(disc);
1395   if(!disc2)
1396     throw INTERP_KERNEL::Exception("addNewEntryIfNecessaryGauss : invalid call to this method ! Internal Error !");
1397   const DataArrayInt *da=disc2->getArrayOfDiscIds();
1398   if(!da)
1399     throw INTERP_KERNEL::Exception("addNewEntryIfNecessaryGauss : no localization ids per cell array available ! The input Gauss node field is maybe invalid !");
1400   MCAuto<DataArrayInt> da2=da->selectByTupleIdSafe(subCells->getConstPointer(),subCells->getConstPointer()+subCells->getNumberOfTuples());
1401   MCAuto<DataArrayInt> retTmp=da2->getDifferentValues();
1402   if(retTmp->presenceOfValue(-1))
1403     throw INTERP_KERNEL::Exception("addNewEntryIfNecessaryGauss : some cells have no dicretization description !");
1404   std::vector<int> ret(retTmp->begin(),retTmp->end());
1405   return ret;
1406 }
1407
1408 const MEDFileFieldPerMesh *MEDFileFieldPerMeshPerTypeCommon::getFather() const
1409 {
1410   return _father;
1411 }
1412
1413 bool MEDFileFieldPerMeshPerTypeCommon::isUniqueLevel(int& dim) const
1414 {
1415   const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(getGeoType()));
1416   int curDim((int)cm.getDimension());
1417   if(dim!=std::numeric_limits<int>::max())
1418     {
1419       if(dim!=curDim)
1420         return false;
1421     }
1422   else
1423     dim=curDim;
1424   return true;
1425 }
1426
1427 void MEDFileFieldPerMeshPerTypeCommon::fillTypesOfFieldAvailable(std::set<TypeOfField>& types) const
1428 {
1429   for(std::vector< MCAuto<MEDFileFieldPerMeshPerTypePerDisc> >::const_iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++)
1430     {
1431       (*it)->fillTypesOfFieldAvailable(types);
1432     }
1433 }
1434
1435 void MEDFileFieldPerMeshPerTypeCommon::fillFieldSplitedByType(std::vector< std::pair<int,int> >& dads, std::vector<TypeOfField>& types, std::vector<std::string>& pfls, std::vector<std::string>& locs) const
1436 {
1437   int sz=_field_pm_pt_pd.size();
1438   dads.resize(sz); types.resize(sz); pfls.resize(sz); locs.resize(sz);
1439   for(int i=0;i<sz;i++)
1440     {
1441       _field_pm_pt_pd[i]->getCoarseData(types[i],dads[i],pfls[i],locs[i]);
1442     }
1443 }
1444
1445 int MEDFileFieldPerMeshPerTypeCommon::getIteration() const
1446 {
1447   return _father->getIteration();
1448 }
1449
1450 int MEDFileFieldPerMeshPerTypeCommon::getOrder() const
1451 {
1452   return _father->getOrder();
1453 }
1454
1455 double MEDFileFieldPerMeshPerTypeCommon::getTime() const
1456 {
1457   return _father->getTime();
1458 }
1459
1460 std::string MEDFileFieldPerMeshPerTypeCommon::getMeshName() const
1461 {
1462   return _father->getMeshName();
1463 }
1464
1465 void MEDFileFieldPerMeshPerTypeCommon::getSizes(int& globalSz, int& nbOfEntries) const
1466 {
1467   for(std::vector< MCAuto<MEDFileFieldPerMeshPerTypePerDisc> >::const_iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++)
1468     {
1469       globalSz+=(*it)->getNumberOfTuples();
1470     }
1471   nbOfEntries+=(int)_field_pm_pt_pd.size();
1472 }
1473
1474 int MEDFileFieldPerMeshPerTypeCommon::getNumberOfComponents() const
1475 {
1476   return _father->getNumberOfComponents();
1477 }
1478
1479 bool MEDFileFieldPerMeshPerTypeCommon::presenceOfMultiDiscPerGeoType() const
1480 {
1481   std::size_t nb(0);
1482   for(std::vector< MCAuto<MEDFileFieldPerMeshPerTypePerDisc> >::const_iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++)
1483     {
1484       const MEDFileFieldPerMeshPerTypePerDisc *fmtd(*it);
1485       if(fmtd)
1486         nb++;
1487     }
1488   return nb>1;
1489 }
1490
1491 void MEDFileFieldPerMeshPerTypeCommon::pushDiscretization(MEDFileFieldPerMeshPerTypePerDisc *disc)
1492 {
1493   MCAuto<MEDFileFieldPerMeshPerTypePerDisc> elt;
1494   elt.takeRef(disc);
1495   _field_pm_pt_pd.push_back(elt);
1496 }
1497
1498 DataArray *MEDFileFieldPerMeshPerTypeCommon::getOrCreateAndGetArray()
1499 {
1500   return _father->getOrCreateAndGetArray();
1501 }
1502
1503 const DataArray *MEDFileFieldPerMeshPerTypeCommon::getOrCreateAndGetArray() const
1504 {
1505   const MEDFileFieldPerMesh *fath=_father;
1506   return fath->getOrCreateAndGetArray();
1507 }
1508
1509 const std::vector<std::string>& MEDFileFieldPerMeshPerTypeCommon::getInfo() const
1510 {
1511   return _father->getInfo();
1512 }
1513
1514 std::vector<std::string> MEDFileFieldPerMeshPerTypeCommon::getPflsReallyUsed() const
1515 {
1516   std::vector<std::string> ret;
1517   std::set<std::string> ret2;
1518   for(std::vector< MCAuto<MEDFileFieldPerMeshPerTypePerDisc> >::const_iterator it1=_field_pm_pt_pd.begin();it1!=_field_pm_pt_pd.end();it1++)
1519     {
1520       std::string tmp=(*it1)->getProfile();
1521       if(!tmp.empty())
1522         if(ret2.find(tmp)==ret2.end())
1523           {
1524             ret.push_back(tmp);
1525             ret2.insert(tmp);
1526           }
1527     }
1528   return ret;
1529 }
1530
1531 std::vector<std::string> MEDFileFieldPerMeshPerTypeCommon::getLocsReallyUsed() const
1532 {
1533   std::vector<std::string> ret;
1534   std::set<std::string> ret2;
1535   for(std::vector< MCAuto<MEDFileFieldPerMeshPerTypePerDisc> >::const_iterator it1=_field_pm_pt_pd.begin();it1!=_field_pm_pt_pd.end();it1++)
1536     {
1537       std::string tmp=(*it1)->getLocalization();
1538       if(!tmp.empty() && tmp!=MED_GAUSS_ELNO)
1539         if(ret2.find(tmp)==ret2.end())
1540           {
1541             ret.push_back(tmp);
1542             ret2.insert(tmp);
1543           }
1544     }
1545   return ret;
1546 }
1547
1548 std::vector<std::string> MEDFileFieldPerMeshPerTypeCommon::getPflsReallyUsedMulti() const
1549 {
1550   std::vector<std::string> ret;
1551   std::set<std::string> ret2;
1552   for(std::vector< MCAuto<MEDFileFieldPerMeshPerTypePerDisc> >::const_iterator it1=_field_pm_pt_pd.begin();it1!=_field_pm_pt_pd.end();it1++)
1553     {
1554       std::string tmp=(*it1)->getProfile();
1555       if(!tmp.empty())
1556         ret.push_back(tmp);
1557     }
1558   return ret;
1559 }
1560
1561 std::vector<std::string> MEDFileFieldPerMeshPerTypeCommon::getLocsReallyUsedMulti() const
1562 {
1563   std::vector<std::string> ret;
1564   for(std::vector< MCAuto<MEDFileFieldPerMeshPerTypePerDisc> >::const_iterator it1=_field_pm_pt_pd.begin();it1!=_field_pm_pt_pd.end();it1++)
1565     {
1566       std::string tmp=(*it1)->getLocalization();
1567       if(!tmp.empty() && tmp!=MED_GAUSS_ELNO)
1568         ret.push_back(tmp);
1569     }
1570   return ret;
1571 }
1572
1573 void MEDFileFieldPerMeshPerTypeCommon::changePflsRefsNamesGen(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif)
1574 {
1575   for(std::vector< MCAuto<MEDFileFieldPerMeshPerTypePerDisc> >::iterator it1=_field_pm_pt_pd.begin();it1!=_field_pm_pt_pd.end();it1++)
1576     (*it1)->changePflsRefsNamesGen(mapOfModif);
1577 }
1578
1579 void MEDFileFieldPerMeshPerTypeCommon::changeLocsRefsNamesGen(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif)
1580 {
1581   for(std::vector< MCAuto<MEDFileFieldPerMeshPerTypePerDisc> >::iterator it1=_field_pm_pt_pd.begin();it1!=_field_pm_pt_pd.end();it1++)
1582     (*it1)->changeLocsRefsNamesGen(mapOfModif);
1583 }
1584
1585 MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMeshPerTypeCommon::getLeafGivenLocId(int locId)
1586 {
1587   if(_field_pm_pt_pd.empty())
1588     {
1589       std::ostringstream oss; oss << "MEDFileFieldPerMeshPerTypeCommon::getLeafGivenLocId : no localizations for geotype \"" << getGeoTypeRepr() << "\" !";
1590       throw INTERP_KERNEL::Exception(oss.str());
1591     }
1592   if(locId>=0 && locId<(int)_field_pm_pt_pd.size())
1593     return _field_pm_pt_pd[locId];
1594   std::ostringstream oss2; oss2 << "MEDFileFieldPerMeshPerTypeCommon::getLeafGivenLocId : no such locId available (" << locId;
1595   oss2 << ") for geometric type \"" << getGeoTypeRepr() << "\" It should be in [0," << _field_pm_pt_pd.size() << ") !";
1596   throw INTERP_KERNEL::Exception(oss2.str().c_str());
1597   return static_cast<MEDFileFieldPerMeshPerTypePerDisc*>(0);
1598 }
1599
1600 const MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMeshPerTypeCommon::getLeafGivenLocId(int locId) const
1601 {
1602   if(_field_pm_pt_pd.empty())
1603     {
1604       std::ostringstream oss; oss << "MEDFileFieldPerMeshPerTypeCommon::getLeafGivenLocId : no localizations for geotype \"" << getGeoTypeRepr() << "\" !";
1605       throw INTERP_KERNEL::Exception(oss.str());
1606     }
1607   if(locId>=0 && locId<(int)_field_pm_pt_pd.size())
1608     return _field_pm_pt_pd[locId];
1609   std::ostringstream oss2; oss2 << "MEDFileFieldPerMeshPerTypeCommon::getLeafGivenLocId : no such locId available (" << locId;
1610   oss2 << ") for geometric type \"" << getGeoTypeRepr() << "\" It should be in [0," << _field_pm_pt_pd.size() << ") !";
1611   throw INTERP_KERNEL::Exception(oss2.str().c_str());
1612   return static_cast<const MEDFileFieldPerMeshPerTypePerDisc*>(0);
1613 }
1614
1615 int MEDFileFieldPerMeshPerTypeCommon::locIdOfLeaf(const MEDFileFieldPerMeshPerTypePerDisc *leaf) const
1616 {
1617   int ret(0);
1618   for(std::vector< MCAuto<MEDFileFieldPerMeshPerTypePerDisc> >::const_iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++,ret++)
1619     {
1620       const MEDFileFieldPerMeshPerTypePerDisc *cand(*it);
1621       if(cand==leaf)
1622         return ret;
1623     }
1624   throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypeCommon::locIdOfLeaf : not found such a leaf in this !");
1625 }
1626
1627 void MEDFileFieldPerMeshPerTypeCommon::fillValues(int& startEntryId, std::vector< std::pair<std::pair<INTERP_KERNEL::NormalizedCellType,int>,std::pair<int,int> > >& entries) const
1628 {
1629   int i=0;
1630   for(std::vector< MCAuto<MEDFileFieldPerMeshPerTypePerDisc> >::const_iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++,i++)
1631     {
1632       (*it)->fillValues(i,startEntryId,entries);
1633     }
1634 }
1635
1636 void MEDFileFieldPerMeshPerTypeCommon::setLeaves(const std::vector< MCAuto< MEDFileFieldPerMeshPerTypePerDisc > >& leaves)
1637 {
1638   _field_pm_pt_pd=leaves;
1639   for(std::vector< MCAuto<MEDFileFieldPerMeshPerTypePerDisc> >::iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++)
1640     (*it)->setFather(this);
1641 }
1642
1643 /*!
1644  *  \param [in,out] globalNum a global numbering counter for the renumbering.
1645  *  \param [out] its - list of pair (start,stop) kept
1646  *  \return bool - false if the type of field \a tof is not contained in \a this.
1647  */
1648 bool MEDFileFieldPerMeshPerTypeCommon::keepOnlySpatialDiscretization(TypeOfField tof, int &globalNum, std::vector< std::pair<int,int> >& its)
1649 {
1650   bool ret(false);
1651   std::vector< MCAuto<MEDFileFieldPerMeshPerTypePerDisc> > newPmPtPd;
1652   for(std::vector< MCAuto<MEDFileFieldPerMeshPerTypePerDisc> >::iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++)
1653     if((*it)->getType()==tof)
1654       {
1655         newPmPtPd.push_back(*it);
1656         std::pair<int,int> bgEnd; bgEnd.first=(*it)->getStart(); bgEnd.second=(*it)->getEnd();
1657         (*it)->setNewStart(globalNum);
1658         globalNum=(*it)->getEnd();
1659         its.push_back(bgEnd);
1660         ret=true;
1661       }
1662   if(ret)
1663     _field_pm_pt_pd=newPmPtPd;
1664   return ret;
1665 }
1666
1667 /*!
1668  *  \param [in,out] globalNum a global numbering counter for the renumbering.
1669  *  \param [out] its - list of pair (start,stop) kept
1670  *  \return bool - false if the type of field \a tof is not contained in \a this.
1671  */
1672 bool MEDFileFieldPerMeshPerTypeCommon::keepOnlyGaussDiscretization(std::size_t idOfDisc, int &globalNum, std::vector< std::pair<int,int> >& its)
1673 {
1674   if(_field_pm_pt_pd.size()<=idOfDisc)
1675     return false;
1676   MCAuto<MEDFileFieldPerMeshPerTypePerDisc> elt(_field_pm_pt_pd[idOfDisc]);
1677   std::vector< MCAuto<MEDFileFieldPerMeshPerTypePerDisc> > newPmPtPd(1,elt);
1678   std::pair<int,int> bgEnd; bgEnd.first=_field_pm_pt_pd[idOfDisc]->getStart(); bgEnd.second=_field_pm_pt_pd[idOfDisc]->getEnd();
1679   elt->setNewStart(globalNum);
1680   globalNum=elt->getEnd();
1681   its.push_back(bgEnd);
1682   _field_pm_pt_pd=newPmPtPd;
1683   return true;
1684 }
1685
1686 void MEDFileFieldPerMeshPerTypeCommon::loadOnlyStructureOfDataRecursively(med_idt fid, int &start, const MEDFileFieldNameScope& nasc)
1687 {
1688   for(std::vector< MCAuto<MEDFileFieldPerMeshPerTypePerDisc> >::iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++)
1689     (*it)->loadOnlyStructureOfDataRecursively(fid,start,nasc);
1690 }
1691
1692 void MEDFileFieldPerMeshPerTypeCommon::loadBigArraysRecursively(med_idt fid, const MEDFileFieldNameScope& nasc)
1693 {
1694   for(std::vector< MCAuto<MEDFileFieldPerMeshPerTypePerDisc> >::iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++)
1695     (*it)->loadBigArray(fid,nasc);
1696 }
1697
1698 void MEDFileFieldPerMeshPerTypeCommon::writeLL(med_idt fid, const MEDFileFieldNameScope& nasc) const
1699 {
1700   for(std::vector< MCAuto<MEDFileFieldPerMeshPerTypePerDisc> >::const_iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++)
1701     {
1702       (*it)->copyOptionsFrom(*this);
1703       (*it)->writeLL(fid,nasc);
1704     }
1705 }
1706
1707 med_entity_type MEDFileFieldPerMeshPerTypeCommon::ConvertIntoMEDFileType(TypeOfField ikType, INTERP_KERNEL::NormalizedCellType ikGeoType, med_geometry_type& medfGeoType)
1708 {
1709   switch(ikType)
1710   {
1711     case ON_CELLS:
1712       medfGeoType=typmai3[(int)ikGeoType];
1713       return MED_CELL;
1714     case ON_NODES:
1715       medfGeoType=MED_NONE;
1716       return MED_NODE;
1717     case ON_GAUSS_NE:
1718       medfGeoType=typmai3[(int)ikGeoType];
1719       return MED_NODE_ELEMENT;
1720     case ON_GAUSS_PT:
1721       medfGeoType=typmai3[(int)ikGeoType];
1722       return MED_CELL;
1723     default:
1724       throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypeCommon::ConvertIntoMEDFileType : unexpected entity type ! internal error");
1725   }
1726   return MED_UNDEF_ENTITY_TYPE;
1727 }
1728
1729 //////////////////////////////////////////////////
1730
1731 MEDFileFieldPerMeshPerType *MEDFileFieldPerMeshPerType::NewOnRead(med_idt fid, MEDFileFieldPerMesh *fath, TypeOfField type, INTERP_KERNEL::NormalizedCellType geoType, const MEDFileFieldNameScope& nasc, const PartDefinition *pd)
1732 {
1733   return new MEDFileFieldPerMeshPerType(fid,fath,type,geoType,nasc,pd);
1734 }
1735
1736 MEDFileFieldPerMeshPerType *MEDFileFieldPerMeshPerType::New(MEDFileFieldPerMesh *fath, INTERP_KERNEL::NormalizedCellType geoType)
1737 {
1738   return new MEDFileFieldPerMeshPerType(fath,geoType);
1739 }
1740
1741 MEDFileFieldPerMeshPerType *MEDFileFieldPerMeshPerType::deepCopy(MEDFileFieldPerMesh *father) const
1742 {
1743   MCAuto<MEDFileFieldPerMeshPerType> ret=new MEDFileFieldPerMeshPerType(*this);
1744   ret->setFather(father);
1745   ret->deepCopyElements();
1746   return ret.retn();
1747 }
1748
1749 void MEDFileFieldPerMeshPerType::getFieldAtLevel(int meshDim, TypeOfField type, const MEDFileFieldGlobsReal *glob, std::vector< std::pair<int,int> >& dads, std::vector<const DataArrayInt *>& pfls, std::vector<int>& locs, std::vector<INTERP_KERNEL::NormalizedCellType>& geoTypes) const
1750 {
1751   if(_geo_type!=INTERP_KERNEL::NORM_ERROR)
1752     {
1753       const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_geo_type);
1754       if(meshDim!=(int)cm.getDimension())
1755         return ;
1756     }
1757   for(std::vector< MCAuto<MEDFileFieldPerMeshPerTypePerDisc> >::const_iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++)
1758     (*it)->getFieldAtLevel(type,glob,dads,pfls,locs,geoTypes);
1759 }
1760
1761 INTERP_KERNEL::NormalizedCellType MEDFileFieldPerMeshPerType::getGeoType() const
1762 {
1763   return _geo_type;
1764 }
1765
1766 void MEDFileFieldPerMeshPerType::entriesForMEDfile(TypeOfField mct, med_geometry_type& gt, med_entity_type& ent) const
1767 {
1768   ent=MEDFileFieldPerMeshPerTypeCommon::ConvertIntoMEDFileType(mct,_geo_type,gt);
1769 }
1770
1771 void MEDFileFieldPerMeshPerType::getDimension(int& dim) const
1772 {
1773   const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(_geo_type));
1774   int curDim((int)cm.getDimension());
1775   dim=std::max(dim,curDim);
1776 }
1777
1778 void MEDFileFieldPerMeshPerType::simpleRepr(int bkOffset, std::ostream& oss, int id) const
1779 {
1780   const char startLine[]="  ## ";
1781   std::string startLine2(bkOffset,' ');
1782   std::string startLine3(startLine2);
1783   startLine3+=startLine;
1784   if(_geo_type!=INTERP_KERNEL::NORM_ERROR)
1785     {
1786       const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_geo_type);
1787       oss << startLine3 << "Entry geometry type #" << id << " is lying on geometry types " << cm.getRepr() << "." << std::endl;
1788     }
1789   else
1790     oss << startLine3 << "Entry geometry type #" << id << " is lying on NODES." << std::endl;
1791   oss << startLine3 << "Entry is defined on " <<  _field_pm_pt_pd.size() << " localizations." << std::endl;
1792   int i=0;
1793   for(std::vector< MCAuto<MEDFileFieldPerMeshPerTypePerDisc> >::const_iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++,i++)
1794     {
1795       const MEDFileFieldPerMeshPerTypePerDisc *cur=(*it);
1796       if(cur)
1797         cur->simpleRepr(bkOffset,oss,i);
1798       else
1799         {
1800           oss << startLine2 << "    ## " << "Localization #" << i << " is empty !" << std::endl;
1801         }
1802     }
1803 }
1804
1805 std::string MEDFileFieldPerMeshPerType::getGeoTypeRepr() const
1806 {
1807   const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(_geo_type));
1808   return std::string(cm.getRepr());
1809 }
1810
1811 MEDFileFieldPerMeshPerType::MEDFileFieldPerMeshPerType(MEDFileFieldPerMesh *father, INTERP_KERNEL::NormalizedCellType gt):MEDFileFieldPerMeshPerTypeCommon(father),_geo_type(gt)
1812 {
1813 }
1814
1815 MEDFileFieldPerMeshPerType::MEDFileFieldPerMeshPerType(med_idt fid, MEDFileFieldPerMesh *fath, TypeOfField type, INTERP_KERNEL::NormalizedCellType geoType, const MEDFileFieldNameScope& nasc, const PartDefinition *pd):MEDFileFieldPerMeshPerTypeCommon(fath),_geo_type(geoType)
1816 {
1817   INTERP_KERNEL::AutoPtr<char> pflName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
1818   INTERP_KERNEL::AutoPtr<char> locName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
1819   med_geometry_type mgeoti;
1820   med_entity_type menti(ConvertIntoMEDFileType(type,geoType,mgeoti));
1821   int nbProfiles(MEDfieldnProfile(fid,nasc.getName().c_str(),getIteration(),getOrder(),menti,mgeoti,pflName,locName));
1822   _field_pm_pt_pd.resize(nbProfiles);
1823   for(int i=0;i<nbProfiles;i++)
1824     {
1825       _field_pm_pt_pd[i]=MEDFileFieldPerMeshPerTypePerDisc::NewOnRead(this,type,i,pd);
1826     }
1827   if(type==ON_CELLS)
1828     {
1829       int nbProfiles2(MEDfieldnProfile(fid,nasc.getName().c_str(),getIteration(),getOrder(),MED_NODE_ELEMENT,mgeoti,pflName,locName));
1830       for(int i=0;i<nbProfiles2;i++)
1831         _field_pm_pt_pd.push_back(MEDFileFieldPerMeshPerTypePerDisc::NewOnRead(this,ON_GAUSS_NE,i,pd));
1832     }
1833   if(!_field_pm_pt_pd.empty() || type!=ON_CELLS)
1834     return ;
1835   // dark side of the force.
1836   {
1837     int nbProfiles1(MEDfieldnProfile(fid,nasc.getName().c_str(),getIteration(),getOrder(),MED_DESCENDING_FACE,mgeoti,pflName,locName));
1838     int nbProfiles2(MEDfieldnProfile(fid,nasc.getName().c_str(),getIteration(),getOrder(),MED_DESCENDING_EDGE,mgeoti,pflName,locName));
1839     if(nbProfiles1==0 && nbProfiles2==0)
1840       return ;// OK definitely nothing in field
1841     menti=nbProfiles1>=nbProfiles2?MED_DESCENDING_FACE:MED_DESCENDING_EDGE;//not enough words to describe the beauty
1842     nbProfiles=std::max(nbProfiles1,nbProfiles2);
1843     _field_pm_pt_pd.resize(nbProfiles);
1844     for(int i=0;i<nbProfiles;i++)
1845       _field_pm_pt_pd[i]=MEDFileFieldPerMeshPerTypePerDisc::NewOnRead(this,ON_CELLS,i,pd);
1846   }
1847 }
1848
1849 MCAuto<MEDFileFieldPerMeshPerType> MEDFileFieldPerMeshPerType::Aggregate(int &start, const std::vector<std::pair<int,const MEDFileFieldPerMeshPerType *> >& pms, const std::vector< std::vector< std::pair<int,int> > >& dts, INTERP_KERNEL::NormalizedCellType gt, MEDFileFieldPerMesh *father, std::vector<std::pair< int, std::pair<int,int> > >& extractInfo)
1850 {
1851   MCAuto<MEDFileFieldPerMeshPerType> ret(MEDFileFieldPerMeshPerType::New(father,gt));
1852   std::map<TypeOfField, std::vector< std::pair<int,const MEDFileFieldPerMeshPerTypePerDisc * > > > m;
1853   for(std::vector<std::pair<int,const MEDFileFieldPerMeshPerType *> >::const_iterator it=pms.begin();it!=pms.end();it++)
1854     {
1855       for(std::vector< MCAuto<MEDFileFieldPerMeshPerTypePerDisc> >::const_iterator it2=(*it).second->_field_pm_pt_pd.begin();it2!=(*it).second->_field_pm_pt_pd.end();it2++)
1856         m[(*it2)->getType()].push_back(std::pair<int,const MEDFileFieldPerMeshPerTypePerDisc * >((*it).first,*it2));
1857     }
1858   for(std::map<TypeOfField, std::vector< std::pair<int,const MEDFileFieldPerMeshPerTypePerDisc * > > >::const_iterator it=m.begin();it!=m.end();it++)
1859     {
1860       MCAuto<MEDFileFieldPerMeshPerTypePerDisc> agg(MEDFileFieldPerMeshPerTypePerDisc::Aggregate(start,(*it).second,dts,(*it).first,ret,extractInfo));
1861       ret->_field_pm_pt_pd.push_back(agg);
1862     }
1863   return ret;
1864 }
1865
1866 //////////////////////////////////////////////////
1867
1868 MEDFileFieldPerMeshPerTypeDyn *MEDFileFieldPerMeshPerTypeDyn::NewOnRead(med_idt fid, MEDFileFieldPerMesh *fath, const MEDFileEntities *entities, int idGT, const MEDFileFieldNameScope& nasc)
1869 {
1870   if(!entities)
1871     throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypeDyn::NewOnRead : null pointer !");
1872   const MEDFileAllStaticEntitiesPlusDyn *entities2(dynamic_cast<const MEDFileAllStaticEntitiesPlusDyn *>(entities));
1873   if(!entities2)
1874     throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypeDyn::NewOnRead : invalid type of entities !");
1875   const MEDFileStructureElement *se(entities2->getWithGT(idGT));
1876   return new MEDFileFieldPerMeshPerTypeDyn(fid,fath,se,nasc);
1877 }
1878
1879 MEDFileFieldPerMeshPerTypeDyn::MEDFileFieldPerMeshPerTypeDyn(med_idt fid, MEDFileFieldPerMesh *fath, const MEDFileStructureElement *se, const MEDFileFieldNameScope& nasc):MEDFileFieldPerMeshPerTypeCommon(fath)
1880 {
1881   _se.takeRef(se);
1882   INTERP_KERNEL::AutoPtr<char> pflName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
1883   INTERP_KERNEL::AutoPtr<char> locName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
1884   int nbProfiles(MEDfieldnProfile(fid,nasc.getName().c_str(),getIteration(),getOrder(),MED_STRUCT_ELEMENT,_se->getDynGT(),pflName,locName));
1885   _field_pm_pt_pd.resize(nbProfiles);
1886   for(int i=0;i<nbProfiles;i++)
1887     {
1888       _field_pm_pt_pd[i]=MEDFileFieldPerMeshPerTypePerDisc::NewOnRead(this,_se->getEntity(),i,NULL);
1889     }
1890 }
1891
1892 int MEDFileFieldPerMeshPerTypeDyn::getDynGT() const
1893 {
1894   return _se->getDynGT();
1895 }
1896
1897 std::string MEDFileFieldPerMeshPerTypeDyn::getModelName() const
1898 {
1899   return _se->getName();
1900 }
1901
1902 void MEDFileFieldPerMeshPerTypeDyn::getDimension(int& dim) const
1903 {
1904   throw INTERP_KERNEL::Exception("not implemented yet !");
1905 }
1906
1907 void MEDFileFieldPerMeshPerTypeDyn::entriesForMEDfile(TypeOfField mct, med_geometry_type& gt, med_entity_type& ent) const
1908 {
1909   gt=getDynGT();
1910   ent=MED_STRUCT_ELEMENT;
1911 }
1912
1913 INTERP_KERNEL::NormalizedCellType MEDFileFieldPerMeshPerTypeDyn::getGeoType() const
1914 {
1915   throw INTERP_KERNEL::Exception("not implemented yet !");
1916 }
1917
1918 void MEDFileFieldPerMeshPerTypeDyn::simpleRepr(int bkOffset, std::ostream& oss, int id) const
1919 {
1920   const char startLine[]="  ## ";
1921   std::string startLine2(bkOffset,' ');
1922   std::string startLine3(startLine2);
1923   startLine3+=startLine;
1924   oss << startLine3 << "Entry geometry type #" << id << " is lying on geometry STRUCTURE_ELEMENT type " << getDynGT() << "." << std::endl;
1925   oss << startLine3 << "Entry is defined on " <<  _field_pm_pt_pd.size() << " localizations." << std::endl;
1926   int i=0;
1927   for(std::vector< MCAuto<MEDFileFieldPerMeshPerTypePerDisc> >::const_iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++,i++)
1928     {
1929       if((*it).isNotNull())
1930         (*it)->simpleRepr(bkOffset,oss,i);
1931       else
1932         {
1933           oss << startLine2 << "    ## " << "Localization #" << i << " is empty !" << std::endl;
1934         }
1935     }
1936 }
1937
1938 std::string MEDFileFieldPerMeshPerTypeDyn::getGeoTypeRepr() const
1939 {
1940   throw INTERP_KERNEL::Exception("not implemented yet !");
1941 }
1942
1943 MEDFileFieldPerMeshPerTypeDyn *MEDFileFieldPerMeshPerTypeDyn::deepCopy(MEDFileFieldPerMesh *father) const
1944 {
1945   MCAuto<MEDFileFieldPerMeshPerTypeDyn> ret(new MEDFileFieldPerMeshPerTypeDyn(*this));
1946   ret->setFather(father);
1947   ret->deepCopyElements();
1948   return ret.retn();
1949 }
1950
1951 void MEDFileFieldPerMeshPerTypeDyn::getFieldAtLevel(int meshDim, TypeOfField type, const MEDFileFieldGlobsReal *glob, std::vector< std::pair<int,int> >& dads, std::vector<const DataArrayInt *>& pfls, std::vector<int>& locs, std::vector<INTERP_KERNEL::NormalizedCellType>& geoTypes) const
1952 {
1953   throw INTERP_KERNEL::Exception("not implemented yet !");
1954 }
1955
1956 //////////////////////////////////////////////////
1957
1958 MEDFileFieldPerMesh *MEDFileFieldPerMesh::NewOnRead(med_idt fid, MEDFileAnyTypeField1TSWithoutSDA *fath, int meshCsit, int meshIteration, int meshOrder, const MEDFileFieldNameScope& nasc, const MEDFileMesh *mm, const MEDFileEntities *entities)
1959 {
1960   return new MEDFileFieldPerMesh(fid,fath,meshCsit,meshIteration,meshOrder,nasc,mm,entities);
1961 }
1962
1963 MEDFileFieldPerMesh *MEDFileFieldPerMesh::New(MEDFileAnyTypeField1TSWithoutSDA *fath, const MEDCouplingMesh *mesh)
1964 {
1965   return new MEDFileFieldPerMesh(fath,mesh);
1966 }
1967
1968 std::size_t MEDFileFieldPerMesh::getHeapMemorySizeWithoutChildren() const
1969 {
1970   return _field_pm_pt.capacity()*sizeof(MCAuto< MEDFileFieldPerMeshPerType >);
1971 }
1972
1973 std::vector<const BigMemoryObject *> MEDFileFieldPerMesh::getDirectChildrenWithNull() const
1974 {
1975   std::vector<const BigMemoryObject *> ret;
1976   for(std::vector< MCAuto< MEDFileFieldPerMeshPerTypeCommon > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++)
1977     ret.push_back(*it);
1978   return ret;
1979 }
1980
1981 MEDFileFieldPerMesh *MEDFileFieldPerMesh::deepCopy(MEDFileAnyTypeField1TSWithoutSDA *father) const
1982 {
1983   MCAuto< MEDFileFieldPerMesh > ret=new MEDFileFieldPerMesh(*this);
1984   ret->_father=father;
1985   std::size_t i=0;
1986   for(std::vector< MCAuto< MEDFileFieldPerMeshPerTypeCommon > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++,i++)
1987     {
1988       if((*it).isNotNull())
1989         ret->_field_pm_pt[i]=(*it)->deepCopy((MEDFileFieldPerMesh *)(ret));
1990     }
1991   return ret.retn();
1992 }
1993
1994 void MEDFileFieldPerMesh::simpleRepr(int bkOffset, std::ostream& oss, int id) const
1995 {
1996   std::string startLine(bkOffset,' ');
1997   oss << startLine << "## Field part (" << id << ") lying on mesh \"" << getMeshName() << "\", Mesh iteration=" << _mesh_iteration << ". Mesh order=" << _mesh_order << "." << std::endl;
1998   oss << startLine << "## Field is defined on " << _field_pm_pt.size() << " types." << std::endl;
1999   int i=0;
2000   for(std::vector< MCAuto< MEDFileFieldPerMeshPerTypeCommon > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++,i++)
2001     {
2002       if((*it).isNotNull())
2003         (*it)->simpleRepr(bkOffset,oss,i);
2004       else
2005         {
2006           oss << startLine << "  ## Entry geometry type #" << i << " is empty !" << std::endl;
2007         }
2008     }
2009 }
2010
2011 void MEDFileFieldPerMesh::copyTinyInfoFrom(const MEDCouplingMesh *mesh)
2012 {
2013   mesh->getTime(_mesh_iteration,_mesh_order);
2014 }
2015
2016 void MEDFileFieldPerMesh::assignFieldNoProfileNoRenum(int& start, const std::vector<int>& code, const MEDCouplingFieldTemplate *field, const DataArray *arr, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc)
2017 {
2018   int nbOfTypes=code.size()/3;
2019   int offset=0;
2020   for(int i=0;i<nbOfTypes;i++)
2021     {
2022       INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)code[3*i];
2023       int nbOfCells=code[3*i+1];
2024       int pos=addNewEntryIfNecessary(type);
2025       _field_pm_pt[pos]->assignFieldNoProfile(start,offset,nbOfCells,field,arr,glob,nasc);
2026       offset+=nbOfCells;
2027     }
2028 }
2029
2030 /*!
2031  * This method is the most general one. No optimization is done here.
2032  * \param [in] multiTypePfl is the end user profile specified in high level API
2033  * \param [in] code is the code of \a mesh[multiTypePfl] mesh. It is of size of number of different geometric types into \a mesh[multiTypePfl].
2034  * \param [in] code2 is the code of the \b WHOLE mesh on the same level. So all types in \a code are in \a code2.
2035  * \param [in] idsInPflPerType is the selection into the \a multiTypePfl whole profile that corresponds to the given geometric type. This vector is always 3 times smaller than \a code.
2036  * \param [in] idsPerType is a vector containing the profiles needed to be created for MED file format. \b WARNING these processed MED file profiles can be subdivided again in case of Gauss points.
2037  * \param [in] mesh is the mesh coming from the MEDFileMesh instance in correspondence with the MEDFileField. The mesh inside the \a field is simply ignored.
2038  */
2039 void MEDFileFieldPerMesh::assignFieldProfile(int& start, const DataArrayInt *multiTypePfl, const std::vector<int>& code, const std::vector<int>& code2, const std::vector<DataArrayInt *>& idsInPflPerType, const std::vector<DataArrayInt *>& idsPerType, const MEDCouplingFieldTemplate *field, const DataArray *arr, const MEDCouplingMesh *mesh, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc)
2040 {
2041   int nbOfTypes(code.size()/3);
2042   for(int i=0;i<nbOfTypes;i++)
2043     {
2044       INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)code[3*i];
2045       int pos=addNewEntryIfNecessary(type);
2046       DataArrayInt *pfl=0;
2047       if(code[3*i+2]!=-1)
2048         pfl=idsPerType[code[3*i+2]];
2049       int nbOfTupes2=code2.size()/3;
2050       int found=0;
2051       for(;found<nbOfTupes2;found++)
2052         if(code[3*i]==code2[3*found])
2053           break;
2054       if(found==nbOfTupes2)
2055         throw INTERP_KERNEL::Exception("MEDFileFieldPerMesh::assignFieldProfile : internal problem ! Should never happen ! Please report bug to anthony.geay@cea.fr !");
2056       _field_pm_pt[pos]->assignFieldProfile(nbOfTypes==1,start,multiTypePfl,idsInPflPerType[i],pfl,code2[3*found+1],field,arr,mesh,glob,nasc);
2057     }
2058 }
2059
2060 void MEDFileFieldPerMesh::assignNodeFieldNoProfile(int& start, const MEDCouplingFieldTemplate *field, const DataArray *arr, MEDFileFieldGlobsReal& glob)
2061 {
2062   int pos=addNewEntryIfNecessary(INTERP_KERNEL::NORM_ERROR);
2063   _field_pm_pt[pos]->assignNodeFieldNoProfile(start,field,arr,glob);
2064 }
2065
2066 void MEDFileFieldPerMesh::assignNodeFieldProfile(int& start, const DataArrayInt *pfl, const MEDCouplingFieldTemplate *field, const DataArray *arr, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc)
2067 {
2068   int pos=addNewEntryIfNecessary(INTERP_KERNEL::NORM_ERROR);
2069   _field_pm_pt[pos]->assignNodeFieldProfile(start,pfl,field,arr,glob,nasc);
2070 }
2071
2072 void MEDFileFieldPerMesh::loadOnlyStructureOfDataRecursively(med_idt fid, int& start, const MEDFileFieldNameScope& nasc)
2073 {
2074   for(std::vector< MCAuto< MEDFileFieldPerMeshPerTypeCommon > >::iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++)
2075     (*it)->loadOnlyStructureOfDataRecursively(fid,start,nasc);
2076 }
2077
2078 void MEDFileFieldPerMesh::loadBigArraysRecursively(med_idt fid, const MEDFileFieldNameScope& nasc)
2079 {
2080   for(std::vector< MCAuto< MEDFileFieldPerMeshPerTypeCommon > >::iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++)
2081     (*it)->loadBigArraysRecursively(fid,nasc);
2082 }
2083
2084 void MEDFileFieldPerMesh::writeLL(med_idt fid, const MEDFileFieldNameScope& nasc) const
2085 {
2086   int nbOfTypes=_field_pm_pt.size();
2087   for(int i=0;i<nbOfTypes;i++)
2088     {
2089       _field_pm_pt[i]->copyOptionsFrom(*this);
2090       _field_pm_pt[i]->writeLL(fid,nasc);
2091     }
2092 }
2093
2094 void MEDFileFieldPerMesh::getDimension(int& dim) const
2095 {
2096   for(std::vector< MCAuto< MEDFileFieldPerMeshPerTypeCommon > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++)
2097     (*it)->getDimension(dim);
2098 }
2099
2100 bool MEDFileFieldPerMesh::isUniqueLevel(int& dim) const
2101 {
2102   for(std::vector< MCAuto< MEDFileFieldPerMeshPerTypeCommon > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++)
2103     if(!(*it)->isUniqueLevel(dim))
2104       return false;
2105   return true;
2106 }
2107
2108 void MEDFileFieldPerMesh::fillTypesOfFieldAvailable(std::set<TypeOfField>& types) const
2109 {
2110   for(std::vector< MCAuto< MEDFileFieldPerMeshPerTypeCommon > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++)
2111     (*it)->fillTypesOfFieldAvailable(types);
2112 }
2113
2114 std::vector< std::vector< std::pair<int,int> > > MEDFileFieldPerMesh::getFieldSplitedByType(std::vector<INTERP_KERNEL::NormalizedCellType>& types, std::vector< std::vector<TypeOfField> >& typesF, std::vector< std::vector<std::string> >& pfls, std::vector< std::vector<std::string> > & locs) const
2115 {
2116   int sz=_field_pm_pt.size();
2117   std::vector< std::vector<std::pair<int,int> > > ret(sz);
2118   types.resize(sz); typesF.resize(sz); pfls.resize(sz); locs.resize(sz);
2119   for(int i=0;i<sz;i++)
2120     {
2121       types[i]=_field_pm_pt[i]->getGeoType();
2122       _field_pm_pt[i]->fillFieldSplitedByType(ret[i],typesF[i],pfls[i],locs[i]);
2123     }
2124   return ret;
2125 }
2126
2127 double MEDFileFieldPerMesh::getTime() const
2128 {
2129   int tmp1,tmp2;
2130   return _father->getTime(tmp1,tmp2);
2131 }
2132
2133 int MEDFileFieldPerMesh::getIteration() const
2134 {
2135   return _father->getIteration();
2136 }
2137
2138 int MEDFileFieldPerMesh::getOrder() const
2139 {
2140   return _father->getOrder();
2141 }
2142
2143 int MEDFileFieldPerMesh::getNumberOfComponents() const
2144 {
2145   return _father->getNumberOfComponents();
2146 }
2147
2148 std::string MEDFileFieldPerMesh::getMeshName() const
2149 {
2150   return _father->getMeshName();
2151 }
2152
2153 void MEDFileFieldPerMesh::setMeshName(const std::string& meshName)
2154 {
2155   _father->setMeshName(meshName);
2156 }
2157
2158 bool MEDFileFieldPerMesh::presenceOfMultiDiscPerGeoType() const
2159 {
2160   for(std::vector< MCAuto< MEDFileFieldPerMeshPerTypeCommon > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++)
2161     {
2162       if((*it).isNull())
2163         continue;
2164       if((*it)->presenceOfMultiDiscPerGeoType())
2165         return true;
2166     }
2167   return false;
2168 }
2169
2170 bool MEDFileFieldPerMesh::presenceOfStructureElements() const
2171 {
2172   for(std::vector< MCAuto< MEDFileFieldPerMeshPerTypeCommon > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++)
2173     if((*it).isNotNull())
2174       {
2175         const MEDFileFieldPerMeshPerTypeDyn *pt(dynamic_cast<const MEDFileFieldPerMeshPerTypeDyn *>((const MEDFileFieldPerMeshPerTypeCommon *)*it));
2176         if(pt)
2177           return true;
2178       }
2179   return false;
2180 }
2181
2182 bool MEDFileFieldPerMesh::onlyStructureElements() const
2183 {
2184   for(std::vector< MCAuto< MEDFileFieldPerMeshPerTypeCommon > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++)
2185     if((*it).isNotNull())
2186       {
2187         const MEDFileFieldPerMeshPerTypeDyn *pt(dynamic_cast<const MEDFileFieldPerMeshPerTypeDyn *>((const MEDFileFieldPerMeshPerTypeCommon *)*it));
2188         if(!pt)
2189           return false;
2190       }
2191   return true;
2192 }
2193
2194 void MEDFileFieldPerMesh::killStructureElements()
2195 {
2196   std::vector< MCAuto< MEDFileFieldPerMeshPerTypeCommon > > res;
2197   for(std::vector< MCAuto< MEDFileFieldPerMeshPerTypeCommon > >::iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++)
2198     {
2199       if((*it).isNotNull())
2200         {
2201           const MEDFileFieldPerMeshPerTypeDyn *pt(dynamic_cast<const MEDFileFieldPerMeshPerTypeDyn *>((const MEDFileFieldPerMeshPerTypeCommon *)*it));
2202           if(!pt)
2203             res.push_back(*it);
2204         }
2205     }
2206   _field_pm_pt=res;
2207 }
2208
2209 void MEDFileFieldPerMesh::keepOnlyStructureElements()
2210 {
2211   std::vector< MCAuto< MEDFileFieldPerMeshPerTypeCommon > > res;
2212   for(std::vector< MCAuto< MEDFileFieldPerMeshPerTypeCommon > >::iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++)
2213     {
2214       if((*it).isNotNull())
2215         {
2216           const MEDFileFieldPerMeshPerTypeDyn *pt(dynamic_cast<const MEDFileFieldPerMeshPerTypeDyn *>((const MEDFileFieldPerMeshPerTypeCommon *)*it));
2217           if(pt)
2218             res.push_back(*it);
2219         }
2220     }
2221   _field_pm_pt=res;
2222 }
2223
2224 void MEDFileFieldPerMesh::keepOnlyOnSE(const std::string& seName)
2225 {
2226   std::vector< MCAuto< MEDFileFieldPerMeshPerTypeCommon > > res;
2227   for(std::vector< MCAuto< MEDFileFieldPerMeshPerTypeCommon > >::iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++)
2228     {
2229       if((*it).isNotNull())
2230         {
2231           const MEDFileFieldPerMeshPerTypeDyn *pt(dynamic_cast<const MEDFileFieldPerMeshPerTypeDyn *>((const MEDFileFieldPerMeshPerTypeCommon *)*it));
2232           if(!pt)
2233             throw INTERP_KERNEL::Exception("MEDFileFieldPerMesh::keepOnlyOnSE : presence of non SE !");
2234           if(pt->getModelName()==seName)
2235             res.push_back(*it);
2236         }
2237     }
2238   _field_pm_pt=res;
2239 }
2240
2241 void MEDFileFieldPerMesh::getMeshSENames(std::vector< std::pair<std::string,std::string> >& ps) const
2242 {
2243   for(std::vector< MCAuto< MEDFileFieldPerMeshPerTypeCommon > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++)
2244     {
2245       if((*it).isNotNull())
2246         {
2247           const MEDFileFieldPerMeshPerTypeDyn *pt(dynamic_cast<const MEDFileFieldPerMeshPerTypeDyn *>((const MEDFileFieldPerMeshPerTypeCommon *)*it));
2248           if(pt)
2249             {
2250               ps.push_back(std::pair<std::string,std::string>(getMeshName(),pt->getModelName()));
2251             }
2252           else
2253             throw INTERP_KERNEL::Exception("MEDFileFieldPerMesh::getMeshSENames : presence of a non structure element part !");
2254         }
2255     }
2256 }
2257
2258 DataArray *MEDFileFieldPerMesh::getOrCreateAndGetArray()
2259 {
2260   if(!_father)
2261     throw INTERP_KERNEL::Exception("MEDFileFieldPerMesh::getOrCreateAndGetArray : no father ! internal error !");
2262   return _father->getOrCreateAndGetArray();
2263 }
2264
2265 const DataArray *MEDFileFieldPerMesh::getOrCreateAndGetArray() const
2266 {
2267   if(!_father)
2268     throw INTERP_KERNEL::Exception("MEDFileFieldPerMesh::getOrCreateAndGetArray : no father ! internal error !");
2269   return _father->getOrCreateAndGetArray();
2270 }
2271
2272 const std::vector<std::string>& MEDFileFieldPerMesh::getInfo() const
2273 {
2274   return _father->getInfo();
2275 }
2276
2277 /*!
2278  * type,geoTypes,dads,pfls,locs are input parameters. They should have the same size.
2279  * Before the call of this method 'geoTypes','dads','pfls','locs' must be reorganized so that types in geoTypes are contiguous and ordered following typmai2 array.
2280  * It returns 2 output vectors :
2281  * - 'code' of size 3*sz where sz is the number of different values into 'geoTypes'
2282  * - 'notNullPfls' contains sz2 values that are extracted from 'pfls' in which null profiles have been removed.
2283  * 'code' and 'notNullPfls' are in MEDCouplingUMesh::checkTypeConsistencyAndContig format.
2284  */
2285 void MEDFileFieldPerMesh::SortArraysPerType(const MEDFileFieldGlobsReal *glob, TypeOfField type, const std::vector<INTERP_KERNEL::NormalizedCellType>& geoTypes, const std::vector< std::pair<int,int> >& dads, const std::vector<const DataArrayInt *>& pfls, const std::vector<int>& locs, std::vector<int>& code, std::vector<DataArrayInt *>& notNullPfls)
2286 {
2287   int notNullPflsSz=0;
2288   int nbOfArrs=geoTypes.size();
2289   for(int i=0;i<nbOfArrs;i++)
2290     if(pfls[i])
2291       notNullPflsSz++;
2292   std::set<INTERP_KERNEL::NormalizedCellType> geoTypes3(geoTypes.begin(),geoTypes.end());
2293   int nbOfDiffGeoTypes=geoTypes3.size();
2294   code.resize(3*nbOfDiffGeoTypes);
2295   notNullPfls.resize(notNullPflsSz);
2296   notNullPflsSz=0;
2297   int j=0;
2298   for(int i=0;i<nbOfDiffGeoTypes;i++)
2299     {
2300       int startZone=j;
2301       INTERP_KERNEL::NormalizedCellType refType=geoTypes[j];
2302       std::vector<const DataArrayInt *> notNullTmp;
2303       if(pfls[j])
2304         notNullTmp.push_back(pfls[j]);
2305       j++;
2306       for(;j<nbOfArrs;j++)
2307         if(geoTypes[j]==refType)
2308           {
2309             if(pfls[j])
2310               notNullTmp.push_back(pfls[j]);
2311           }
2312         else
2313           break;
2314       std::vector< std::pair<int,int> > tmpDads(dads.begin()+startZone,dads.begin()+j);
2315       std::vector<const DataArrayInt *> tmpPfls(pfls.begin()+startZone,pfls.begin()+j);
2316       std::vector<int> tmpLocs(locs.begin()+startZone,locs.begin()+j);
2317       code[3*i]=(int)refType;
2318       std::vector<INTERP_KERNEL::NormalizedCellType> refType2(1,refType);
2319       code[3*i+1]=ComputeNbOfElems(glob,type,refType2,tmpDads,tmpLocs);
2320       if(notNullTmp.empty())
2321         code[3*i+2]=-1;
2322       else
2323         {
2324           notNullPfls[notNullPflsSz]=DataArrayInt::Aggregate(notNullTmp);
2325           code[3*i+2]=notNullPflsSz++;
2326         }
2327     }
2328 }
2329
2330 /*!
2331  * 'dads' 'geoTypes' and 'locs' are input parameters that should have same size sz. sz should be >=1.
2332  */
2333 int MEDFileFieldPerMesh::ComputeNbOfElems(const MEDFileFieldGlobsReal *glob, TypeOfField type, const std::vector<INTERP_KERNEL::NormalizedCellType>& geoTypes, const std::vector< std::pair<int,int> >& dads, const std::vector<int>& locs)
2334 {
2335   int sz=dads.size();
2336   int ret=0;
2337   for(int i=0;i<sz;i++)
2338     {
2339       if(locs[i]==-1)
2340         {
2341           if(type!=ON_GAUSS_NE)
2342             ret+=dads[i].second-dads[i].first;
2343           else
2344             {
2345               const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(geoTypes[i]);
2346               ret+=(dads[i].second-dads[i].first)/cm.getNumberOfNodes();
2347             }
2348         }
2349       else
2350         {
2351           int nbOfGaussPtPerCell=glob->getNbOfGaussPtPerCell(locs[i]);
2352           ret+=(dads[i].second-dads[i].first)/nbOfGaussPtPerCell;
2353         }
2354     }
2355   return ret;
2356 }
2357
2358 std::vector<std::string> MEDFileFieldPerMesh::getPflsReallyUsed() const
2359 {
2360   std::vector<std::string> ret;
2361   std::set<std::string> ret2;
2362   for(std::vector< MCAuto< MEDFileFieldPerMeshPerTypeCommon > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++)
2363     {
2364       std::vector<std::string> tmp=(*it)->getPflsReallyUsed();
2365       for(std::vector<std::string>::const_iterator it2=tmp.begin();it2!=tmp.end();it2++)
2366         if(ret2.find(*it2)==ret2.end())
2367           {
2368             ret.push_back(*it2);
2369             ret2.insert(*it2);
2370           }
2371     }
2372   return ret;
2373 }
2374
2375 std::vector<std::string> MEDFileFieldPerMesh::getPflsReallyUsedMulti() const
2376 {
2377   std::vector<std::string> ret;
2378   for(std::vector< MCAuto< MEDFileFieldPerMeshPerTypeCommon > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++)
2379     {
2380       std::vector<std::string> tmp=(*it)->getPflsReallyUsedMulti();
2381       ret.insert(ret.end(),tmp.begin(),tmp.end());
2382     }
2383   return ret;
2384 }
2385
2386 std::vector<std::string> MEDFileFieldPerMesh::getLocsReallyUsed() const
2387 {
2388   std::vector<std::string> ret;
2389   std::set<std::string> ret2;
2390   for(std::vector< MCAuto< MEDFileFieldPerMeshPerTypeCommon > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++)
2391     {
2392       std::vector<std::string> tmp=(*it)->getLocsReallyUsed();
2393       for(std::vector<std::string>::const_iterator it2=tmp.begin();it2!=tmp.end();it2++)
2394         if(ret2.find(*it2)==ret2.end())
2395           {
2396             ret.push_back(*it2);
2397             ret2.insert(*it2);
2398           }
2399     }
2400   return ret;
2401 }
2402
2403 std::vector<std::string> MEDFileFieldPerMesh::getLocsReallyUsedMulti() const
2404 {
2405   std::vector<std::string> ret;
2406   for(std::vector< MCAuto< MEDFileFieldPerMeshPerTypeCommon > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++)
2407     {
2408       std::vector<std::string> tmp=(*it)->getLocsReallyUsedMulti();
2409       ret.insert(ret.end(),tmp.begin(),tmp.end());
2410     }
2411   return ret;
2412 }
2413
2414 bool MEDFileFieldPerMesh::changeMeshNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
2415 {
2416   for(std::vector< std::pair<std::string,std::string> >::const_iterator it=modifTab.begin();it!=modifTab.end();it++)
2417     {
2418       if((*it).first==getMeshName())
2419         {
2420           setMeshName((*it).second);
2421           return true;
2422         }
2423     }
2424   return false;
2425 }
2426
2427 void MEDFileFieldPerMesh::convertMedBallIntoClassic()
2428 {
2429   if(_field_pm_pt.size()!=1)
2430     throw INTERP_KERNEL::Exception("MEDFileFieldPerMesh::convertMedBallIntoClassic : Only managed for single mesh !");
2431   if(_field_pm_pt[0].isNull())
2432     throw INTERP_KERNEL::Exception("MEDFileFieldPerMesh::convertMedBallIntoClassic : null pointer !");
2433   MEDFileFieldPerMeshPerTypeDyn *pt(dynamic_cast<MEDFileFieldPerMeshPerTypeDyn *>((MEDFileFieldPerMeshPerTypeCommon *)_field_pm_pt[0]));
2434   if(!pt)
2435     throw INTERP_KERNEL::Exception("MEDFileFieldPerMesh::convertMedBallIntoClassic : this is expected to be marked as structure element !");
2436   if(pt->getNumberOfLoc()!=1)
2437     throw INTERP_KERNEL::Exception("MEDFileFieldPerMesh::convertMedBallIntoClassic : only one loc managed !");
2438   const MEDFileFieldPerMeshPerTypePerDisc *disc(pt->getLeafGivenLocId(0));
2439   if(!disc)
2440     throw INTERP_KERNEL::Exception("MEDFileFieldPerMesh::convertMedBallIntoClassic : internal error !");
2441   MCAuto<MEDFileFieldPerMeshPerTypePerDisc> disc2(MEDFileFieldPerMeshPerTypePerDisc::New(*disc));
2442   disc2->setType(ON_NODES);
2443   MCAuto<MEDFileFieldPerMeshPerType> pt2(MEDFileFieldPerMeshPerType::New(this,INTERP_KERNEL::NORM_ERROR));
2444   disc2->setFather(pt2);
2445   pt2->setFather(this);
2446   pt2->pushDiscretization(disc2);
2447   _field_pm_pt[0]=DynamicCast<MEDFileFieldPerMeshPerType,MEDFileFieldPerMeshPerTypeCommon>(pt2);
2448 }
2449
2450 bool MEDFileFieldPerMesh::renumberEntitiesLyingOnMesh(const std::string& meshName, const std::vector<int>& oldCode, const std::vector<int>& newCode, const DataArrayInt *renumO2N,
2451                                                       MEDFileFieldGlobsReal& glob)
2452 {
2453   if(getMeshName()!=meshName)
2454     return false;
2455   std::set<INTERP_KERNEL::NormalizedCellType> typesToKeep;
2456   for(std::size_t i=0;i<oldCode.size()/3;i++) typesToKeep.insert((INTERP_KERNEL::NormalizedCellType)oldCode[3*i]);
2457   std::vector< std::pair<std::pair<INTERP_KERNEL::NormalizedCellType,int>,std::pair<int,int> > > entries;
2458   std::vector< const MEDFileFieldPerMeshPerTypePerDisc *> entriesKept;
2459   std::vector< const MEDFileFieldPerMeshPerTypePerDisc *> otherEntries;
2460   getUndergroundDataArrayExt(entries);
2461   DataArray *arr0(getOrCreateAndGetArray());//tony
2462   if(!arr0)
2463     throw INTERP_KERNEL::Exception("MEDFileFieldPerMesh::renumberEntitiesLyingOnMesh : DataArray storing values of field is null !");
2464   DataArrayDouble *arr(dynamic_cast<DataArrayDouble *>(arr0));//tony
2465   if(!arr0)
2466     throw INTERP_KERNEL::Exception("MEDFileFieldPerMesh::renumberEntitiesLyingOnMesh : DataArray storing values is double ! Not managed for the moment !");
2467   int sz=0;
2468   if(!arr)
2469     throw INTERP_KERNEL::Exception("MEDFileFieldPerMesh::renumberEntitiesLyingOnMesh : DataArrayDouble storing values of field is null !");
2470   for(std::vector< std::pair<std::pair<INTERP_KERNEL::NormalizedCellType,int>,std::pair<int,int> > >::const_iterator it=entries.begin();it!=entries.end();it++)
2471     {
2472       if(typesToKeep.find((*it).first.first)!=typesToKeep.end())
2473         {
2474           entriesKept.push_back(getLeafGivenTypeAndLocId((*it).first.first,(*it).first.second));
2475           sz+=(*it).second.second-(*it).second.first;
2476         }
2477       else
2478         otherEntries.push_back(getLeafGivenTypeAndLocId((*it).first.first,(*it).first.second));
2479     }
2480   MCAuto<DataArrayInt> renumDefrag=DataArrayInt::New(); renumDefrag->alloc(arr->getNumberOfTuples(),1); renumDefrag->fillWithZero();
2481   ////////////////////
2482   MCAuto<DataArrayInt> explicitIdsOldInMesh=DataArrayInt::New(); explicitIdsOldInMesh->alloc(sz,1);//sz is a majorant of the real size. A realloc will be done after
2483   int *workI2=explicitIdsOldInMesh->getPointer();
2484   int sz1=0,sz2=0,sid=1;
2485   std::vector< std::vector< const MEDFileFieldPerMeshPerTypePerDisc *> > entriesKeptML=MEDFileFieldPerMeshPerTypePerDisc::SplitPerDiscretization(entriesKept);
2486   // std::vector<int> tupleIdOfStartOfNewChuncksV(entriesKeptML.size());
2487   for(std::vector< std::vector< const MEDFileFieldPerMeshPerTypePerDisc *> >::const_iterator itL1=entriesKeptML.begin();itL1!=entriesKeptML.end();itL1++,sid++)
2488     {
2489       //  tupleIdOfStartOfNewChuncksV[sid-1]=sz2;
2490       MCAuto<DataArrayInt> explicitIdsOldInArr=DataArrayInt::New(); explicitIdsOldInArr->alloc(sz,1);
2491       int *workI=explicitIdsOldInArr->getPointer();
2492       for(std::vector< const MEDFileFieldPerMeshPerTypePerDisc *>::const_iterator itL2=(*itL1).begin();itL2!=(*itL1).end();itL2++)
2493         {
2494           int delta1=(*itL2)->fillTupleIds(workI); workI+=delta1; sz1+=delta1;
2495           (*itL2)->setLocId(sz2);
2496           (*itL2)->_tmp_work1=(*itL2)->getStart();
2497           int delta2=(*itL2)->fillEltIdsFromCode(sz2,oldCode,glob,workI2); workI2+=delta2; sz2+=delta2;
2498         }
2499       renumDefrag->setPartOfValuesSimple3(sid,explicitIdsOldInArr->begin(),explicitIdsOldInArr->end(),0,1,1);
2500     }
2501   explicitIdsOldInMesh->reAlloc(sz2);
2502   int tupleIdOfStartOfNewChuncks=arr->getNumberOfTuples()-sz2;
2503   ////////////////////
2504   MCAuto<DataArrayInt> permArrDefrag=renumDefrag->buildPermArrPerLevel(); renumDefrag=0;
2505   // perform redispatching of non concerned MEDFileFieldPerMeshPerTypePerDisc
2506   std::vector< MCAuto<MEDFileFieldPerMeshPerTypePerDisc> > otherEntriesNew;
2507   for(std::vector< const MEDFileFieldPerMeshPerTypePerDisc *>::const_iterator it=otherEntries.begin();it!=otherEntries.end();it++)
2508     {
2509       otherEntriesNew.push_back(MEDFileFieldPerMeshPerTypePerDisc::New(*(*it)));
2510       otherEntriesNew.back()->setNewStart(permArrDefrag->getIJ((*it)->getStart(),0));
2511       otherEntriesNew.back()->setLocId((*it)->getGeoType());
2512     }
2513   std::vector< MCAuto<MEDFileFieldPerMeshPerTypePerDisc> > entriesKeptNew;
2514   std::vector< const MEDFileFieldPerMeshPerTypePerDisc *> entriesKeptNew2;
2515   for(std::vector< const MEDFileFieldPerMeshPerTypePerDisc *>::const_iterator it=entriesKept.begin();it!=entriesKept.end();it++)
2516     {
2517       MCAuto<MEDFileFieldPerMeshPerTypePerDisc> elt=MEDFileFieldPerMeshPerTypePerDisc::New(*(*it));
2518       int newStart=elt->getLocId();
2519       elt->setLocId((*it)->getGeoType());
2520       elt->setNewStart(newStart);
2521       elt->_tmp_work1=permArrDefrag->getIJ(elt->_tmp_work1,0);
2522       entriesKeptNew.push_back(elt);
2523       entriesKeptNew2.push_back(elt);
2524     }
2525   MCAuto<DataArrayDouble> arr2=arr->renumber(permArrDefrag->getConstPointer());
2526   // perform redispatching of concerned MEDFileFieldPerMeshPerTypePerDisc -> values are in arr2
2527   MCAuto<DataArrayInt> explicitIdsNewInMesh=renumO2N->selectByTupleId(explicitIdsOldInMesh->begin(),explicitIdsOldInMesh->end());
2528   std::vector< std::vector< const MEDFileFieldPerMeshPerTypePerDisc *> > entriesKeptPerDisc=MEDFileFieldPerMeshPerTypePerDisc::SplitPerDiscretization(entriesKeptNew2);
2529   bool ret=false;
2530   for(std::vector< std::vector< const MEDFileFieldPerMeshPerTypePerDisc *> >::const_iterator it4=entriesKeptPerDisc.begin();it4!=entriesKeptPerDisc.end();it4++)
2531     {
2532       sid=0;
2533       /*for(std::vector< const MEDFileFieldPerMeshPerTypePerDisc *>::const_iterator itL2=(*it4).begin();itL2!=(*it4).end();itL2++)
2534         {
2535           MEDFileFieldPerMeshPerTypePerDisc *curNC=const_cast<MEDFileFieldPerMeshPerTypePerDisc *>(*itL2);
2536           curNC->setNewStart(permArrDefrag->getIJ((*itL2)->getStart(),0)-tupleIdOfStartOfNewChuncks+tupleIdOfStartOfNewChuncksV[sid]);
2537           }*/
2538       ret=MEDFileFieldPerMeshPerTypePerDisc::RenumberChunks(tupleIdOfStartOfNewChuncks,*it4,explicitIdsNewInMesh,newCode,
2539                                                             glob,arr2,otherEntriesNew) || ret;
2540     }
2541   if(!ret)
2542     return false;
2543   // Assign new dispatching
2544   assignNewLeaves(otherEntriesNew);
2545   arr->deepCopyFrom(*arr2);
2546   return true;
2547 }
2548
2549 /*!
2550  * \param [in,out] globalNum a global numbering counter for the renumbering.
2551  * \param [out] its - list of pair (start,stop) kept
2552  */
2553 void MEDFileFieldPerMesh::keepOnlySpatialDiscretization(TypeOfField tof, int &globalNum, std::vector< std::pair<int,int> >& its)
2554 {
2555   std::vector< MCAuto< MEDFileFieldPerMeshPerTypeCommon > > ret;
2556   for(std::vector< MCAuto< MEDFileFieldPerMeshPerTypeCommon > >::iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++)
2557     {
2558       std::vector< std::pair<int,int> > its2;
2559       if((*it)->keepOnlySpatialDiscretization(tof,globalNum,its2))
2560         {
2561           ret.push_back(*it);
2562           its.insert(its.end(),its2.begin(),its2.end());
2563         }
2564     }
2565   _field_pm_pt=ret;
2566 }
2567
2568 /*!
2569  * \param [in,out] globalNum a global numbering counter for the renumbering.
2570  * \param [out] its - list of pair (start,stop) kept
2571  */
2572 void MEDFileFieldPerMesh::keepOnlyGaussDiscretization(std::size_t idOfDisc, int &globalNum, std::vector< std::pair<int,int> >& its)
2573 {
2574   std::vector< MCAuto< MEDFileFieldPerMeshPerTypeCommon > > ret;
2575   for(std::vector< MCAuto< MEDFileFieldPerMeshPerTypeCommon > >::iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++)
2576     {
2577       std::vector< std::pair<int,int> > its2;
2578       if((*it)->keepOnlyGaussDiscretization(idOfDisc,globalNum,its2))
2579         {
2580           ret.push_back(*it);
2581           its.insert(its.end(),its2.begin(),its2.end());
2582         }
2583     }
2584   _field_pm_pt=ret;
2585 }
2586
2587 void MEDFileFieldPerMesh::assignNewLeaves(const std::vector< MCAuto< MEDFileFieldPerMeshPerTypePerDisc > >& leaves)
2588 {
2589   std::map<INTERP_KERNEL::NormalizedCellType,std::vector< MCAuto< MEDFileFieldPerMeshPerTypePerDisc> > > types;
2590   for( std::vector< MCAuto< MEDFileFieldPerMeshPerTypePerDisc > >::const_iterator it=leaves.begin();it!=leaves.end();it++)
2591     types[(INTERP_KERNEL::NormalizedCellType)(*it)->getLocId()].push_back(*it);
2592   //
2593   std::vector< MCAuto< MEDFileFieldPerMeshPerTypeCommon > > fieldPmPt(types.size());
2594   std::map<INTERP_KERNEL::NormalizedCellType,std::vector< MCAuto< MEDFileFieldPerMeshPerTypePerDisc> > >::const_iterator it1=types.begin();
2595   std::vector< MCAuto< MEDFileFieldPerMeshPerTypeCommon > >::iterator it2=fieldPmPt.begin();
2596   for(;it1!=types.end();it1++,it2++)
2597     {
2598       MCAuto<MEDFileFieldPerMeshPerType> elt=MEDFileFieldPerMeshPerType::New(this,(INTERP_KERNEL::NormalizedCellType)((*it1).second[0]->getLocId()));
2599       elt->setLeaves((*it1).second);
2600       MCAuto<MEDFileFieldPerMeshPerTypeCommon> elt2(DynamicCast<MEDFileFieldPerMeshPerType,MEDFileFieldPerMeshPerTypeCommon>(elt));
2601       *it2=elt2;
2602     }
2603   _field_pm_pt=fieldPmPt;
2604 }
2605
2606 void MEDFileFieldPerMesh::changePflsRefsNamesGen(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif)
2607 {
2608   for(std::vector< MCAuto< MEDFileFieldPerMeshPerTypeCommon > >::iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++)
2609     (*it)->changePflsRefsNamesGen(mapOfModif);
2610 }
2611
2612 void MEDFileFieldPerMesh::changeLocsRefsNamesGen(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif)
2613 {
2614   for(std::vector< MCAuto< MEDFileFieldPerMeshPerTypeCommon > >::iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++)
2615     (*it)->changeLocsRefsNamesGen(mapOfModif);
2616 }
2617
2618 /*!
2619  * \param [in] mesh is the whole mesh
2620  */
2621 MEDCouplingFieldDouble *MEDFileFieldPerMesh::getFieldOnMeshAtLevel(TypeOfField type, const MEDFileFieldGlobsReal *glob, const MEDCouplingMesh *mesh, bool& isPfl, MCAuto<DataArray>& arrOut, const MEDFileFieldNameScope& nasc) const
2622 {
2623   if(_field_pm_pt.empty())
2624     throw INTERP_KERNEL::Exception("MEDFileFieldPerMesh::getFieldOnMeshAtLevel : no types field set !");
2625   //
2626   std::vector< std::pair<int,int> > dads;
2627   std::vector<const DataArrayInt *> pfls;
2628   std::vector<DataArrayInt *> notNullPflsPerGeoType;
2629   std::vector<int> locs,code;
2630   std::vector<INTERP_KERNEL::NormalizedCellType> geoTypes;
2631   for(std::vector< MCAuto< MEDFileFieldPerMeshPerTypeCommon > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++)
2632     (*it)->getFieldAtLevel(mesh->getMeshDimension(),type,glob,dads,pfls,locs,geoTypes);
2633   // Sort by types
2634   SortArraysPerType(glob,type,geoTypes,dads,pfls,locs,code,notNullPflsPerGeoType);
2635   if(code.empty())
2636     {
2637       std::ostringstream oss; oss << "MEDFileFieldPerMesh::getFieldOnMeshAtLevel : " << "The field \"" << nasc.getName() << "\" exists but not with such spatial discretization or such dimension specified !";
2638       throw INTERP_KERNEL::Exception(oss.str());
2639     }
2640   //
2641   std::vector< MCAuto<DataArrayInt> > notNullPflsPerGeoType2(notNullPflsPerGeoType.begin(),notNullPflsPerGeoType.end());
2642   std::vector< const DataArrayInt *> notNullPflsPerGeoType3(notNullPflsPerGeoType.begin(),notNullPflsPerGeoType.end());
2643   if(type!=ON_NODES)
2644     {
2645       DataArrayInt *arr=mesh->checkTypeConsistencyAndContig(code,notNullPflsPerGeoType3);
2646       if(!arr)
2647         return finishField(type,glob,dads,locs,mesh,isPfl,arrOut,nasc);
2648       else
2649         {
2650           MCAuto<DataArrayInt> arr2(arr);
2651           return finishField2(type,glob,dads,locs,geoTypes,mesh,arr,isPfl,arrOut,nasc);
2652         }
2653     }
2654   else
2655     {
2656       if(code.size()!=3)
2657         throw INTERP_KERNEL::Exception("MEDFileFieldPerMesh::getFieldOnMeshAtLevel : internal error #1 !");
2658       int nb=code[1];
2659       if(code[2]==-1)
2660         {
2661           if(nb!=mesh->getNumberOfNodes())
2662             {
2663               std::ostringstream oss; oss << "MEDFileFieldPerMesh::getFieldOnMeshAtLevel : There is a problem there is " << nb << " nodes in field whereas there is " << mesh->getNumberOfNodes();
2664               oss << " nodes in mesh !";
2665               throw INTERP_KERNEL::Exception(oss.str());
2666             }
2667           return finishField(type,glob,dads,locs,mesh,isPfl,arrOut,nasc);
2668         }
2669       else
2670         return finishFieldNode2(glob,dads,locs,mesh,notNullPflsPerGeoType3[0],isPfl,arrOut,nasc);
2671     }
2672 }
2673
2674 DataArray *MEDFileFieldPerMesh::getFieldOnMeshAtLevelWithPfl(TypeOfField type, const MEDCouplingMesh *mesh, DataArrayInt *&pfl, const MEDFileFieldGlobsReal *glob, const MEDFileFieldNameScope& nasc) const
2675 {
2676   if(_field_pm_pt.empty())
2677     throw INTERP_KERNEL::Exception("MEDFileFieldPerMesh::getFieldOnMeshAtLevel : no types field set !");
2678   //
2679   std::vector<std::pair<int,int> > dads;
2680   std::vector<const DataArrayInt *> pfls;
2681   std::vector<DataArrayInt *> notNullPflsPerGeoType;
2682   std::vector<int> locs,code;
2683   std::vector<INTERP_KERNEL::NormalizedCellType> geoTypes;
2684   for(std::vector< MCAuto< MEDFileFieldPerMeshPerTypeCommon > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++)
2685     (*it)->getFieldAtLevel(mesh->getMeshDimension(),type,glob,dads,pfls,locs,geoTypes);
2686   // Sort by types
2687   SortArraysPerType(glob,type,geoTypes,dads,pfls,locs,code,notNullPflsPerGeoType);
2688   if(code.empty())
2689     {
2690       std::ostringstream oss; oss << "MEDFileFieldPerMesh::getFieldOnMeshAtLevelWithPfl : " << "The field \"" << nasc.getName() << "\" exists but not with such spatial discretization or such dimension specified !";
2691       throw INTERP_KERNEL::Exception(oss.str());
2692     }
2693   std::vector< MCAuto<DataArrayInt> > notNullPflsPerGeoType2(notNullPflsPerGeoType.begin(),notNullPflsPerGeoType.end());
2694   std::vector< const DataArrayInt *> notNullPflsPerGeoType3(notNullPflsPerGeoType.begin(),notNullPflsPerGeoType.end());
2695   if(type!=ON_NODES)
2696     {
2697       MCAuto<DataArrayInt> arr=mesh->checkTypeConsistencyAndContig(code,notNullPflsPerGeoType3);
2698       return finishField4(dads,arr,mesh->getNumberOfCells(),pfl);
2699     }
2700   else
2701     {
2702       if(code.size()!=3)
2703         throw INTERP_KERNEL::Exception("MEDFileFieldPerMesh::getFieldOnMeshAtLevel : internal error #1 !");
2704       int nb=code[1];
2705       if(code[2]==-1)
2706         {
2707           if(nb!=mesh->getNumberOfNodes())
2708             {
2709               std::ostringstream oss; oss << "MEDFileFieldPerMesh::getFieldOnMeshAtLevel : There is a problem there is " << nb << " nodes in field whereas there is " << mesh->getNumberOfNodes();
2710               oss << " nodes in mesh !";
2711               throw INTERP_KERNEL::Exception(oss.str());
2712             }
2713         }
2714       return finishField4(dads,code[2]==-1?0:notNullPflsPerGeoType3[0],mesh->getNumberOfNodes(),pfl);
2715     }
2716   //
2717   return 0;
2718 }
2719
2720 void MEDFileFieldPerMesh::accept(MEDFileFieldVisitor& visitor) const
2721 {
2722   for(std::vector< MCAuto< MEDFileFieldPerMeshPerTypeCommon > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++)
2723     if((*it).isNotNull())
2724       {
2725         visitor.newPerMeshPerTypeEntry(*it);
2726         (*it)->accept(visitor);
2727         visitor.endPerMeshPerTypeEntry(*it);
2728       }
2729 }
2730
2731 void MEDFileFieldPerMesh::getUndergroundDataArrayExt(std::vector< std::pair<std::pair<INTERP_KERNEL::NormalizedCellType,int>,std::pair<int,int> > >& entries) const
2732 {
2733   int globalSz=0;
2734   int nbOfEntries=0;
2735   for(std::vector< MCAuto< MEDFileFieldPerMeshPerTypeCommon > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++)
2736     {
2737       (*it)->getSizes(globalSz,nbOfEntries);
2738     }
2739   entries.resize(nbOfEntries);
2740   nbOfEntries=0;
2741   for(std::vector< MCAuto< MEDFileFieldPerMeshPerTypeCommon > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++)
2742     {
2743       (*it)->fillValues(nbOfEntries,entries);
2744     }
2745 }
2746
2747 MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMesh::getLeafGivenTypeAndLocId(INTERP_KERNEL::NormalizedCellType typ, int locId)
2748 {
2749   for(std::vector< MCAuto< MEDFileFieldPerMeshPerTypeCommon > >::iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++)
2750     {
2751       if((*it)->getGeoType()==typ)
2752         return (*it)->getLeafGivenLocId(locId);
2753     }
2754   const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(typ);
2755   std::ostringstream oss; oss << "MEDFileFieldPerMesh::getLeafGivenTypeAndLocId : no such geometric type \"" << cm.getRepr() << "\" in this !" << std::endl;
2756   oss << "Possibilities are : ";
2757   for(std::vector< MCAuto< MEDFileFieldPerMeshPerTypeCommon > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++)
2758     {
2759       const INTERP_KERNEL::CellModel& cm2=INTERP_KERNEL::CellModel::GetCellModel((*it)->getGeoType());
2760       oss << "\"" << cm2.getRepr() << "\", ";
2761     }
2762   throw INTERP_KERNEL::Exception(oss.str());
2763 }
2764
2765 const MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMesh::getLeafGivenTypeAndLocId(INTERP_KERNEL::NormalizedCellType typ, int locId) const
2766 {
2767   for(std::vector< MCAuto< MEDFileFieldPerMeshPerTypeCommon > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++)
2768     {
2769       if((*it)->getGeoType()==typ)
2770         return (*it)->getLeafGivenLocId(locId);
2771     }
2772   const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(typ);
2773   std::ostringstream oss; oss << "MEDFileFieldPerMesh::getLeafGivenTypeAndLocId : no such geometric type \"" << cm.getRepr() << "\" in this !" << std::endl;
2774   oss << "Possibilities are : ";
2775   for(std::vector< MCAuto< MEDFileFieldPerMeshPerTypeCommon > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++)
2776     {
2777       const INTERP_KERNEL::CellModel& cm2=INTERP_KERNEL::CellModel::GetCellModel((*it)->getGeoType());
2778       oss << "\"" << cm2.getRepr() << "\", ";
2779     }
2780   throw INTERP_KERNEL::Exception(oss.str());
2781 }
2782
2783 /*!
2784  * \param [in,out] start - Integer that gives the current position in the final aggregated array
2785  * \param [in] pms - list of elements to aggregate. integer gives the mesh id
2786  * \param [in] dts - (Distribution of types) = level 1 : meshes to aggregate. Level 2 : all geo type. Level 3 pair specifying geo type and number of elem in geotype.
2787  * \param [out] extractInfo - Gives information about the where the data comes from. It is a vector of triplet. First element in the triplet the mesh pos. The 2nd one the start pos. The 3rd the end pos.
2788  */
2789 MCAuto<MEDFileFieldPerMeshPerTypePerDisc> MEDFileFieldPerMeshPerTypePerDisc::Aggregate(int &start, const std::vector< std::pair<int,const MEDFileFieldPerMeshPerTypePerDisc *> >& pms, const std::vector< std::vector< std::pair<int,int> > >& dts, TypeOfField tof, MEDFileFieldPerMeshPerType *father, std::vector<std::pair< int, std::pair<int,int> > >& extractInfo)
2790 {
2791   MCAuto<MEDFileFieldPerMeshPerTypePerDisc> ret(new MEDFileFieldPerMeshPerTypePerDisc(father,tof));
2792   if(pms.empty())
2793     throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::Aggregate : empty input vector !");
2794   for(std::vector<std::pair<int,const MEDFileFieldPerMeshPerTypePerDisc *> >::const_iterator it=pms.begin();it!=pms.end();it++)
2795     {
2796       if(!(*it).second)
2797         throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::Aggregate : presence of null pointer !");
2798       if(!(*it).second->getProfile().empty())
2799         throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::Aggregate : not implemented yet for profiles !");
2800       if(!(*it).second->getLocalization().empty())
2801         throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::Aggregate : not implemented yet for gauss pts !");
2802     }
2803   INTERP_KERNEL::NormalizedCellType gt(pms[0].second->getGeoType());
2804   std::size_t i(0);
2805   std::vector< std::pair<int,int> > filteredDTS;
2806   for(std::vector< std::vector< std::pair<int,int> > >::const_iterator it=dts.begin();it!=dts.end();it++,i++)
2807     for(std::vector< std::pair<int,int> >::const_iterator it2=(*it).begin();it2!=(*it).end();it2++)
2808       if((*it2).first==gt)
2809         filteredDTS.push_back(std::pair<int,int>(i,(*it2).second));
2810   if(pms.size()!=filteredDTS.size())
2811     throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::Aggregate : not implemented yet for generated profiles !");
2812   std::vector<std::pair<int,const MEDFileFieldPerMeshPerTypePerDisc *> >::const_iterator it1(pms.begin());
2813   std::vector< std::pair<int,int> >::const_iterator it2(filteredDTS.begin());
2814   int zeStart(start),nval(0);
2815   for(;it1!=pms.end();it1++,it2++)
2816     {
2817       if((*it1).first!=(*it2).first)
2818         throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::Aggregate : not implemented yet for generated profiles 2 !");
2819       int s1((*it1).second->getStart()),e1((*it1).second->getEnd());
2820       extractInfo.push_back(std::pair<int, std::pair<int,int> >((*it1).first,std::pair<int,int>(s1,e1)));
2821       start+=e1-s1;
2822       nval+=((*it1).second)->getNumberOfVals();
2823     }
2824   ret->_start=zeStart; ret->_end=start; ret->_nval=nval;
2825   return ret;
2826 }
2827
2828 MCAuto<MEDFileFieldPerMesh> MEDFileFieldPerMesh::Aggregate(int &start, const std::vector<const MEDFileFieldPerMesh *>& pms, const std::vector< std::vector< std::pair<int,int> > >& dts, MEDFileAnyTypeField1TSWithoutSDA *father, std::vector<std::pair< int, std::pair<int,int> > >& extractInfo)
2829 {
2830   MCAuto<MEDFileFieldPerMesh> ret(new MEDFileFieldPerMesh(father,pms[0]->getMeshName(),pms[0]->getMeshIteration(),pms[0]->getMeshOrder()));
2831   std::map<INTERP_KERNEL::NormalizedCellType, std::vector< std::pair<int,const MEDFileFieldPerMeshPerType *> > > m;
2832   std::size_t i(0);
2833   for(std::vector<const MEDFileFieldPerMesh *>::const_iterator it=pms.begin();it!=pms.end();it++,i++)
2834     {
2835       const std::vector< MCAuto< MEDFileFieldPerMeshPerTypeCommon > >& v((*it)->_field_pm_pt);
2836       for(std::vector< MCAuto< MEDFileFieldPerMeshPerTypeCommon > >::const_iterator it2=v.begin();it2!=v.end();it2++)
2837         {
2838           INTERP_KERNEL::NormalizedCellType gt((*it2)->getGeoType());
2839           const MEDFileFieldPerMeshPerType *elt(dynamic_cast<const MEDFileFieldPerMeshPerType *>((const MEDFileFieldPerMeshPerTypeCommon *)(*it2)));
2840           if(!elt)
2841             throw INTERP_KERNEL::Exception("MEDFileFieldPerMesh::Aggregate : not managed for structelement !");
2842           m[gt].push_back(std::pair<int,const MEDFileFieldPerMeshPerType *>(i,elt));
2843         }
2844     }
2845   for(std::map<INTERP_KERNEL::NormalizedCellType, std::vector< std::pair<int,const MEDFileFieldPerMeshPerType *> > >::const_iterator it=m.begin();it!=m.end();it++)
2846     {
2847       MCAuto<MEDFileFieldPerMeshPerType> agg(MEDFileFieldPerMeshPerType::Aggregate(start,(*it).second,dts,(*it).first,ret,extractInfo));
2848       MCAuto<MEDFileFieldPerMeshPerTypeCommon> agg2(DynamicCast<MEDFileFieldPerMeshPerType,MEDFileFieldPerMeshPerTypeCommon>(agg));
2849       ret->_field_pm_pt.push_back(agg2);
2850     }
2851   return ret;
2852 }
2853
2854 int MEDFileFieldPerMesh::addNewEntryIfNecessary(INTERP_KERNEL::NormalizedCellType type)
2855 {
2856   int i=0;
2857   int pos=std::distance(typmai2,std::find(typmai2,typmai2+MED_N_CELL_FIXED_GEO,type));
2858   std::vector< MCAuto< MEDFileFieldPerMeshPerTypeCommon > >::iterator it2=_field_pm_pt.begin();
2859   for(std::vector< MCAuto< MEDFileFieldPerMeshPerTypeCommon > >::iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++,i++)
2860     {
2861       INTERP_KERNEL::NormalizedCellType curType=(*it)->getGeoType();
2862       if(type==curType)
2863         return i;
2864       else
2865         {
2866           int pos2=std::distance(typmai2,std::find(typmai2,typmai2+MED_N_CELL_FIXED_GEO,curType));
2867           if(pos>pos2)
2868             it2=it+1;
2869         }
2870     }
2871   int ret=std::distance(_field_pm_pt.begin(),it2);
2872   _field_pm_pt.insert(it2,MEDFileFieldPerMeshPerType::New(this,type));
2873   return ret;
2874 }
2875
2876 /*!
2877  * 'dads' and 'locs' input parameters have the same number of elements
2878  * \param [in] mesh is \b NOT the global mesh, but the possibly reduced mesh. \a mesh parameter will be directly aggregated in the returned field
2879  */
2880 MEDCouplingFieldDouble *MEDFileFieldPerMesh::finishField(TypeOfField type, const MEDFileFieldGlobsReal *glob,
2881                                                          const std::vector< std::pair<int,int> >& dads, const std::vector<int>& locs,
2882                                                          const MEDCouplingMesh *mesh, bool& isPfl, MCAuto<DataArray>& arrOut, const MEDFileFieldNameScope& nasc) const
2883 {
2884   isPfl=false;
2885   MCAuto<MEDCouplingFieldDouble> ret=MEDCouplingFieldDouble::New(type,ONE_TIME);
2886   ret->setMesh(mesh); ret->setName(nasc.getName().c_str()); ret->setTime(getTime(),getIteration(),getOrder()); ret->setTimeUnit(nasc.getDtUnit().c_str());
2887   MCAuto<DataArray> da=getOrCreateAndGetArray()->selectByTupleRanges(dads);
2888   const std::vector<std::string>& infos=getInfo();
2889   da->setInfoOnComponents(infos);
2890   da->setName("");
2891   if(type==ON_GAUSS_PT)
2892     {
2893       int offset=0;
2894       int nbOfArrs=dads.size();
2895       for(int i=0;i<nbOfArrs;i++)
2896         {
2897           std::vector<std::pair<int,int> > dads2(1,dads[i]); const std::vector<int> locs2(1,locs[i]);
2898           const std::vector<INTERP_KERNEL::NormalizedCellType> geoTypes2(1,INTERP_KERNEL::NORM_ERROR);
2899           int nbOfElems=ComputeNbOfElems(glob,type,geoTypes2,dads2,locs2);
2900           MCAuto<DataArrayInt> di=DataArrayInt::New();
2901           di->alloc(nbOfElems,1);
2902           di->iota(offset);
2903           const MEDFileFieldLoc& fl=glob->getLocalizationFromId(locs[i]);
2904           ret->setGaussLocalizationOnCells(di->getConstPointer(),di->getConstPointer()+nbOfElems,fl.getRefCoords(),fl.getGaussCoords(),fl.getGaussWeights());
2905           offset+=nbOfElems;
2906         }
2907     }
2908   arrOut=da;
2909   return ret.retn();
2910 }
2911
2912 /*!
2913  * This method is an extension of MEDFileFieldPerMesh::finishField method. It deals with profiles. This method should be called when type is different from ON_NODES.
2914  * 'dads', 'locs' and 'geoTypes' input parameters have the same number of elements.
2915  * No check of this is performed. 'da' array contains an array in old2New style to be applied to mesh to obtain the right support.
2916  * The order of cells in the returned field is those imposed by the profile.
2917  * \param [in] mesh is the global mesh.
2918  */
2919 MEDCouplingFieldDouble *MEDFileFieldPerMesh::finishField2(TypeOfField type, const MEDFileFieldGlobsReal *glob,
2920                                                           const std::vector<std::pair<int,int> >& dads, const std::vector<int>& locs,
2921                                                           const std::vector<INTERP_KERNEL::NormalizedCellType>& geoTypes,
2922                                                           const MEDCouplingMesh *mesh, const DataArrayInt *da, bool& isPfl, MCAuto<DataArray>& arrOut, const MEDFileFieldNameScope& nasc) const
2923 {
2924   if(da->isIota(mesh->getNumberOfCells()))
2925     return finishField(type,glob,dads,locs,mesh,isPfl,arrOut,nasc);
2926   MCAuto<MEDCouplingMesh> m2=mesh->buildPart(da->getConstPointer(),da->getConstPointer()+da->getNbOfElems());
2927   m2->setName(mesh->getName().c_str());
2928   MCAuto<MEDCouplingFieldDouble> ret=finishField(type,glob,dads,locs,m2,isPfl,arrOut,nasc);
2929   isPfl=true;
2930   return ret.retn();
2931 }
2932
2933 /*!
2934  * This method is the complement of MEDFileFieldPerMesh::finishField2 method except that this method works for node profiles.
2935  */
2936 MEDCouplingFieldDouble *MEDFileFieldPerMesh::finishFieldNode2(const MEDFileFieldGlobsReal *glob,
2937                                                               const std::vector<std::pair<int,int> >& dads, const std::vector<int>& locs,
2938                                                               const MEDCouplingMesh *mesh, const DataArrayInt *da, bool& isPfl, MCAuto<DataArray>& arrOut, const MEDFileFieldNameScope& nasc) const
2939 {
2940   if(da->isIota(mesh->getNumberOfNodes()))
2941     return finishField(ON_NODES,glob,dads,locs,mesh,isPfl,arrOut,nasc);
2942   // Treatment of particular case where nodal field on pfl is requested with a meshDimRelToMax=1.
2943   const MEDCouplingUMesh *meshu=dynamic_cast<const MEDCouplingUMesh *>(mesh);
2944   if(meshu)
2945     {
2946       if(meshu->getNodalConnectivity()==0)
2947         {
2948           MCAuto<MEDCouplingFieldDouble> ret=finishField(ON_CELLS,glob,dads,locs,mesh,isPfl,arrOut,nasc);
2949           int nb=da->getNbOfElems();
2950           const int *ptr=da->getConstPointer();
2951           MEDCouplingUMesh *meshuc=const_cast<MEDCouplingUMesh *>(meshu);
2952           meshuc->allocateCells(nb);
2953           for(int i=0;i<nb;i++)
2954             meshuc->insertNextCell(INTERP_KERNEL::NORM_POINT1,1,ptr+i);
2955           meshuc->finishInsertingCells();
2956           ret->setMesh(meshuc);
2957           const MEDCouplingFieldDiscretization *disc=ret->getDiscretization();
2958           if(!disc) throw INTERP_KERNEL::Exception("MEDFileFieldPerMesh::finishFieldNode2 : internal error, no discretization on field !");
2959           disc->checkCoherencyBetween(meshuc,arrOut);
2960           return ret.retn();
2961         }
2962     }
2963   //
2964   MCAuto<MEDCouplingFieldDouble> ret=finishField(ON_NODES,glob,dads,locs,mesh,isPfl,arrOut,nasc);
2965   isPfl=true;
2966   DataArrayInt *arr2=0;
2967   MCAuto<DataArrayInt> cellIds=mesh->getCellIdsFullyIncludedInNodeIds(da->getConstPointer(),da->getConstPointer()+da->getNbOfElems());
2968   MCAuto<MEDCouplingMesh> mesh2=mesh->buildPartAndReduceNodes(cellIds->getConstPointer(),cellIds->getConstPointer()+cellIds->getNbOfElems(),arr2);
2969   MCAuto<DataArrayInt> arr3(arr2);
2970   int nnodes=mesh2->getNumberOfNodes();
2971   if(nnodes==(int)da->getNbOfElems())
2972     {
2973       MCAuto<DataArrayInt> da3=da->transformWithIndArrR(arr2->begin(),arr2->end());
2974       arrOut->renumberInPlace(da3->getConstPointer());
2975       mesh2->setName(mesh->getName().c_str());
2976       ret->setMesh(mesh2);
2977       return ret.retn();
2978     }
2979   else
2980     {
2981       std::ostringstream oss; oss << "MEDFileFieldPerMesh::finishFieldNode2 : The field on nodes lies on a node profile so that it is impossible to find a submesh having exactly the same nodes of that profile !!!";
2982       oss << "So it is impossible to return a well defined MEDCouplingFieldDouble instance on specified mesh on a specified meshDim !" << std::endl;
2983       oss << "To retrieve correctly such a field you have 3 possibilities :" << std::endl;
2984       oss << " - use an another meshDim compatible with the field on nodes (MED file does not have such information)" << std::endl;
2985       oss << " - use an another a meshDimRelToMax equal to 1 -> it will return a mesh with artificial cell POINT1 containing the profile !" << std::endl;
2986       oss << " - if definitely the node profile has no link with mesh connectivity use MEDFileField1TS::getFieldWithProfile or MEDFileFieldMultiTS::getFieldWithProfile methods instead !";
2987       throw INTERP_KERNEL::Exception(oss.str());
2988     }
2989   return 0;
2990 }
2991
2992 /*!
2993  * This method is the most light method of field retrieving.
2994  */
2995 DataArray *MEDFileFieldPerMesh::finishField4(const std::vector<std::pair<int,int> >& dads, const DataArrayInt *pflIn, int nbOfElems, DataArrayInt *&pflOut) const
2996 {
2997   if(!pflIn)
2998     {
2999       pflOut=DataArrayInt::New();
3000       pflOut->alloc(nbOfElems,1);
3001       pflOut->iota(0);
3002     }
3003   else
3004     {
3005       pflOut=const_cast<DataArrayInt*>(pflIn);
3006       pflOut->incrRef();
3007     }
3008   MCAuto<DataArrayInt> safePfl(pflOut);
3009   MCAuto<DataArray> da=getOrCreateAndGetArray()->selectByTupleRanges(dads);
3010   const std::vector<std::string>& infos=getInfo();
3011   int nbOfComp=infos.size();
3012   for(int i=0;i<nbOfComp;i++)
3013     da->setInfoOnComponent(i,infos[i].c_str());
3014   safePfl->incrRef();
3015   return da.retn();
3016 }
3017
3018
3019 /// @cond INTERNAL
3020
3021 class MFFPMIter
3022 {
3023 public:
3024   static MFFPMIter *NewCell(const MEDFileEntities *entities);
3025   static bool IsPresenceOfNode(const MEDFileEntities *entities);
3026   virtual ~MFFPMIter() { }
3027   virtual void begin() = 0;
3028   virtual bool finished() const = 0;
3029   virtual void next() = 0;
3030   virtual int current() const = 0;
3031 };
3032
3033 class MFFPMIterSimple : public MFFPMIter
3034 {
3035 public:
3036   MFFPMIterSimple():_pos(0) { }
3037   void begin() { _pos=0; }
3038   bool finished() const { return _pos>=MED_N_CELL_FIXED_GEO; }
3039   void next() { _pos++; }
3040   int current() const { return _pos; }
3041 private:
3042   int _pos;
3043 };
3044
3045 class MFFPMIter2 : public MFFPMIter
3046 {
3047 public:
3048   MFFPMIter2(const std::vector<INTERP_KERNEL::NormalizedCellType>& cts);
3049   void begin() { _it=_ids.begin(); }
3050   bool finished() const { return _it==_ids.end(); }
3051   void next() { _it++; }
3052   int current() const { return *_it; }
3053 private:
3054   std::vector<int> _ids;
3055   std::vector<int>::const_iterator _it;
3056 };
3057
3058 MFFPMIter *MFFPMIter::NewCell(const MEDFileEntities *entities)
3059 {
3060   if(!entities)
3061     return new MFFPMIterSimple;
3062   else
3063     {
3064       const MEDFileStaticEntities *entities2(dynamic_cast<const MEDFileStaticEntities *>(entities));
3065       if(entities2)
3066         {
3067           std::vector<INTERP_KERNEL::NormalizedCellType> tmp;
3068           const std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> >& myEnt(entities2->getEntries());
3069           for(std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> >::const_iterator it=myEnt.begin();it!=myEnt.end();it++)
3070             {
3071               if((*it).first==ON_CELLS || (*it).first==ON_GAUSS_NE || (*it).first==ON_GAUSS_PT)
3072                 tmp.push_back((*it).second);
3073             }
3074           return new MFFPMIter2(tmp);
3075         }
3076       return new MFFPMIterSimple;// for MEDFileAllStaticEntites and MEDFileAllStaticEntitiesPlusDyn cells are in
3077     }
3078 }
3079
3080 bool MFFPMIter::IsPresenceOfNode(const MEDFileEntities *entities)
3081 {
3082   if(!entities)
3083     return true;
3084   else
3085     {
3086       const MEDFileStaticEntities *entities2(dynamic_cast<const MEDFileStaticEntities *>(entities));
3087       if(entities2)
3088         {
3089           const std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> >& myEnt(entities2->getEntries());
3090           for(std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> >::const_iterator it=myEnt.begin();it!=myEnt.end();it++)
3091             if((*it).first==ON_NODES)
3092               return true;
3093           return false;
3094         }
3095       return true;// for MEDFileAllStaticEntites and MEDFileAllStaticEntitiesPlusDyn nodes are in
3096     }
3097 }
3098
3099 MFFPMIter2::MFFPMIter2(const std::vector<INTERP_KERNEL::NormalizedCellType>& cts)
3100 {
3101   std::size_t sz(cts.size());
3102   _ids.resize(sz);
3103   for(std::size_t i=0;i<sz;i++)
3104     {
3105       INTERP_KERNEL::NormalizedCellType *loc(std::find(typmai2,typmai2+MED_N_CELL_FIXED_GEO,cts[i]));
3106       if(loc!=typmai2+MED_N_CELL_FIXED_GEO)
3107         _ids[i]=(int)std::distance(typmai2,loc);
3108       else
3109         throw INTERP_KERNEL::Exception("MFFPMIter2 : The specified geo type does not exists !");
3110     }
3111 }
3112
3113 /// @endcond
3114
3115 MEDFileFieldPerMesh::MEDFileFieldPerMesh(med_idt fid, MEDFileAnyTypeField1TSWithoutSDA *fath, int meshCsit, int meshIteration, int meshOrder, const MEDFileFieldNameScope& nasc, const MEDFileMesh *mm, const MEDFileEntities *entities):_mesh_iteration(meshIteration),_mesh_order(meshOrder),
3116     _father(fath)
3117 {
3118   INTERP_KERNEL::AutoPtr<char> meshName(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE));
3119   INTERP_KERNEL::AutoPtr<char> pflName(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE));
3120   INTERP_KERNEL::AutoPtr<char> locName(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE));
3121   const MEDFileUMesh *mmu(dynamic_cast<const MEDFileUMesh *>(mm));
3122   INTERP_KERNEL::AutoCppPtr<MFFPMIter> iter0(MFFPMIter::NewCell(entities));
3123   for(iter0->begin();!iter0->finished();iter0->next())
3124     {
3125       int nbProfile (MEDfield23nProfile(fid,nasc.getName().c_str(),getIteration(),getOrder(),MED_CELL        ,typmai[iter0->current()],meshCsit+1,meshName,pflName,locName));
3126       std::string name0(MEDLoaderBase::buildStringFromFortran(meshName,MED_NAME_SIZE+1));
3127       int nbProfile2(MEDfield23nProfile(fid,nasc.getName().c_str(),getIteration(),getOrder(),MED_NODE_ELEMENT,typmai[iter0->current()],meshCsit+1,meshName,pflName,locName));
3128       std::string name1(MEDLoaderBase::buildStringFromFortran(meshName,MED_NAME_SIZE+1));
3129       if(nbProfile>0 || nbProfile2>0)
3130         {
3131           const PartDefinition *pd(0);
3132           if(mmu)
3133             pd=mmu->getPartDefAtLevel(mmu->getRelativeLevOnGeoType(typmai2[iter0->current()]),typmai2[iter0->current()]);
3134           _field_pm_pt.push_back(MEDFileFieldPerMeshPerType::NewOnRead(fid,this,ON_CELLS,typmai2[iter0->current()],nasc,pd));
3135           if(nbProfile>0)
3136             setMeshName(name0);
3137           else
3138             setMeshName(name1);
3139         }
3140     }
3141   if(MFFPMIter::IsPresenceOfNode(entities))
3142     {
3143       int nbProfile(MEDfield23nProfile(fid,nasc.getName().c_str(),getIteration(),getOrder(),MED_NODE,MED_NONE,meshCsit+1,meshName,pflName,locName));
3144       if(nbProfile>0)
3145         {
3146           const PartDefinition *pd(0);
3147           if(mmu)
3148             pd=mmu->getPartDefAtLevel(1,INTERP_KERNEL::NORM_ERROR);
3149           _field_pm_pt.push_back(MEDFileFieldPerMeshPerType::NewOnRead(fid,this,ON_NODES,INTERP_KERNEL::NORM_ERROR,nasc,pd));
3150           setMeshName(MEDLoaderBase::buildStringFromFortran(meshName,MED_NAME_SIZE));
3151         }
3152     }
3153   if(!entities)
3154     return ;
3155   std::vector<int> dynGT(entities->getDynGTAvail());
3156   for(std::vector<int>::const_iterator it=dynGT.begin();it!=dynGT.end();it++)
3157     {
3158       int nbPfl(MEDfieldnProfile(fid,nasc.getName().c_str(),getIteration(),getOrder(),MED_STRUCT_ELEMENT,*it,pflName,locName));
3159       if(nbPfl>0)
3160         {
3161           _field_pm_pt.push_back(MEDFileFieldPerMeshPerTypeDyn::NewOnRead(fid,this,entities,*it,nasc));
3162           setMeshName(MEDLoaderBase::buildStringFromFortran(meshName,MED_NAME_SIZE));
3163         }
3164     }
3165   if(!_field_pm_pt.empty())
3166     return;
3167   //for vicious users using MED_ARETE MED_FACE in fields. the last try. For Others not overhead to pay.
3168   iter0=MFFPMIter::NewCell(entities);
3169   for(iter0->begin();!iter0->finished();iter0->next())
3170     {
3171       int nbProfile (MEDfield23nProfile(fid,nasc.getName().c_str(),getIteration(),getOrder(),MED_DESCENDING_FACE,typmai[iter0->current()],meshCsit+1,meshName,pflName,locName));
3172       std::string name0(MEDLoaderBase::buildStringFromFortran(meshName,MED_NAME_SIZE+1));
3173       int nbProfile2(MEDfield23nProfile(fid,nasc.getName().c_str(),getIteration(),getOrder(),MED_DESCENDING_EDGE,typmai[iter0->current()],meshCsit+1,meshName,pflName,locName));
3174       std::string name1(MEDLoaderBase::buildStringFromFortran(meshName,MED_NAME_SIZE+1));
3175       if(nbProfile>0 || nbProfile2>0)
3176         {
3177           _field_pm_pt.push_back(MEDFileFieldPerMeshPerType::NewOnRead(fid,this,ON_CELLS,typmai2[iter0->current()],nasc,NULL));
3178           if(nbProfile>0)
3179             setMeshName(name0);
3180           else
3181             setMeshName(name1);
3182         }
3183     }
3184 }
3185
3186 MEDFileFieldPerMesh::MEDFileFieldPerMesh(MEDFileAnyTypeField1TSWithoutSDA *fath, const MEDCouplingMesh *mesh):_father(fath)
3187 {
3188   copyTinyInfoFrom(mesh);
3189 }