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