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