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