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