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