Salome HOME
Moving *all* CMake detection files to common CONFIGURATION repo.
[modules/paravis.git] / src / Plugins / MEDReader / IO / MEDFileFieldRepresentationTree.cxx
1 // Copyright (C) 2010-2016  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
20
21 #include "MEDTimeReq.hxx"
22 #include "MEDUtilities.hxx"
23
24 #include "MEDFileFieldRepresentationTree.hxx"
25 #include "MEDCouplingFieldDiscretization.hxx"
26 #include "MEDCouplingFieldDouble.hxx"
27 #include "InterpKernelGaussCoords.hxx"
28 #include "MEDFileData.hxx"
29 #include "SauvReader.hxx"
30
31 #ifdef MEDREADER_USE_MPI
32   #include "ParaMEDFileMesh.hxx"
33 #endif
34
35 #include "vtkXMLUnstructuredGridWriter.h"//
36
37 #include "vtkUnstructuredGrid.h"
38 #include "vtkRectilinearGrid.h"
39 #include "vtkStructuredGrid.h"
40 #include "vtkUnsignedCharArray.h"
41 #include "vtkQuadratureSchemeDefinition.h"
42 #include "vtkInformationQuadratureSchemeDefinitionVectorKey.h"
43 #include "vtkInformationIntegerKey.h"
44 #include "vtkInformation.h"
45 #include "vtkDataArrayTemplate.h"
46 #include "vtkIdTypeArray.h"
47 #include "vtkDoubleArray.h"
48 #include "vtkIntArray.h"
49 #include "vtkCellArray.h"
50 #include "vtkPointData.h"
51 #include "vtkFieldData.h"
52 #include "vtkCellData.h"
53
54 #include "vtkMutableDirectedGraph.h"
55
56 using namespace MEDCoupling;
57
58 const char MEDFileFieldRepresentationLeavesArrays::ZE_SEP[]="@@][@@";
59
60 const char MEDFileFieldRepresentationLeavesArrays::TS_STR[]="TS";
61
62 const char MEDFileFieldRepresentationLeavesArrays::COM_SUP_STR[]="ComSup";
63
64 const char MEDFileFieldRepresentationLeavesArrays::FAMILY_ID_CELL_NAME[]="FamilyIdCell";
65
66 const char MEDFileFieldRepresentationLeavesArrays::NUM_ID_CELL_NAME[]="NumIdCell";
67
68 const char MEDFileFieldRepresentationLeavesArrays::FAMILY_ID_NODE_NAME[]="FamilyIdNode";
69
70 const char MEDFileFieldRepresentationLeavesArrays::NUM_ID_NODE_NAME[]="NumIdNode";
71
72 const char MEDFileFieldRepresentationLeavesArrays::GLOBAL_NODE_ID_NAME[]="GlobalNodeIds";// WARNING DO NOT CHANGE IT BEFORE HAVING CHECKED IN PV SOURCES !
73
74 const char MEDFileFieldRepresentationTree::ROOT_OF_GRPS_IN_TREE[]="zeGrps";
75
76 const char MEDFileFieldRepresentationTree::ROOT_OF_FAM_IDS_IN_TREE[]="zeFamIds";
77
78 const char MEDFileFieldRepresentationTree::COMPO_STR_TO_LOCATE_MESH_DA[]="-@?|*_";
79
80 vtkIdTypeArray *ELGACmp::findOrCreate(const MEDCoupling::MEDFileFieldGlobsReal *globs, const std::vector<std::string>& locsReallyUsed, vtkDoubleArray *vtkd, vtkDataSet *ds, bool& isNew) const
81 {
82   vtkIdTypeArray *try0(isExisting(locsReallyUsed,vtkd));
83   if(try0)
84     {
85       isNew=false;
86       return try0;
87     }
88   else
89     {
90       isNew=true;
91       return createNew(globs,locsReallyUsed,vtkd,ds);
92     }
93 }
94
95 vtkIdTypeArray *ELGACmp::isExisting(const std::vector<std::string>& locsReallyUsed, vtkDoubleArray *vtkd) const
96 {
97   std::vector< std::vector<std::string> >::iterator it(std::find(_loc_names.begin(),_loc_names.end(),locsReallyUsed));
98   if(it==_loc_names.end())
99     return 0;
100   std::size_t pos(std::distance(_loc_names.begin(),it));
101   vtkIdTypeArray *ret(_elgas[pos]);
102   vtkInformationQuadratureSchemeDefinitionVectorKey *key(vtkQuadratureSchemeDefinition::DICTIONARY());
103   for(std::vector<std::pair< vtkQuadratureSchemeDefinition *, unsigned char > >::const_iterator it=_defs[pos].begin();it!=_defs[pos].end();it++)
104     {
105       key->Set(vtkd->GetInformation(),(*it).first,(*it).second);
106     }
107   vtkd->GetInformation()->Set(vtkQuadratureSchemeDefinition::QUADRATURE_OFFSET_ARRAY_NAME(),ret->GetName());
108   return ret;
109 }
110
111 vtkIdTypeArray *ELGACmp::createNew(const MEDCoupling::MEDFileFieldGlobsReal *globs, const std::vector<std::string>& locsReallyUsed, vtkDoubleArray *vtkd, vtkDataSet *ds) const
112 {
113   const int VTK_DATA_ARRAY_DELETE=vtkDataArrayTemplate<double>::VTK_DATA_ARRAY_DELETE;
114   std::vector< std::vector<std::string> > locNames(_loc_names);
115   std::vector<vtkIdTypeArray *> elgas(_elgas);
116   std::vector< std::pair< vtkQuadratureSchemeDefinition *, unsigned char > > defs;
117   //
118   std::vector< std::vector<std::string> >::const_iterator it(std::find(locNames.begin(),locNames.end(),locsReallyUsed));
119   if(it!=locNames.end())
120     throw INTERP_KERNEL::Exception("ELGACmp::createNew : Method is expected to be called after isExisting call ! Entry already exists !");
121   locNames.push_back(locsReallyUsed);
122   vtkIdTypeArray *elga(vtkIdTypeArray::New());
123   elga->SetNumberOfComponents(1);
124   vtkInformationQuadratureSchemeDefinitionVectorKey *key(vtkQuadratureSchemeDefinition::DICTIONARY());
125   std::map<unsigned char,int> m;
126   for(std::vector<std::string>::const_iterator it=locsReallyUsed.begin();it!=locsReallyUsed.end();it++)
127     {
128       vtkQuadratureSchemeDefinition *def(vtkQuadratureSchemeDefinition::New());
129       const MEDFileFieldLoc& loc(globs->getLocalization((*it).c_str()));
130       INTERP_KERNEL::NormalizedCellType ct(loc.getGeoType());
131       const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(ct));
132       int nbGaussPt(loc.getNbOfGaussPtPerCell()),nbPtsPerCell((int)cm.getNumberOfNodes()),dimLoc(loc.getDimension());
133       // WARNING : these 2 lines are a workaround, due to users that write a ref element with dimension not equal to dimension of the geometric element.
134       std::vector<double> gsCoods2(INTERP_KERNEL::GaussInfo::NormalizeCoordinatesIfNecessary(ct,dimLoc,loc.getGaussCoords()));
135       std::vector<double> refCoods2(INTERP_KERNEL::GaussInfo::NormalizeCoordinatesIfNecessary(ct,dimLoc,loc.getRefCoords()));
136       double *shape(new double[nbPtsPerCell*nbGaussPt]);
137       INTERP_KERNEL::GaussInfo calculator(ct,gsCoods2,nbGaussPt,refCoods2,nbPtsPerCell);
138       calculator.initLocalInfo();
139       const std::vector<double>& wgths(loc.getGaussWeights());
140       for(int i=0;i<nbGaussPt;i++)
141         {
142           const double *pt0(calculator.getFunctionValues(i));
143           if(ct!=INTERP_KERNEL::NORM_HEXA27)
144             std::copy(pt0,pt0+nbPtsPerCell,shape+nbPtsPerCell*i);
145           else
146             {
147               for(int j=0;j<27;j++)
148                 shape[nbPtsPerCell*i+j]=pt0[MEDMeshMultiLev::HEXA27_PERM_ARRAY[j]];
149             }
150         }
151       unsigned char vtkType(MEDMeshMultiLev::PARAMEDMEM_2_VTKTYPE[ct]);
152       m[vtkType]=nbGaussPt;
153       def->Initialize(vtkType,nbPtsPerCell,nbGaussPt,shape,const_cast<double *>(&wgths[0]));
154       delete [] shape;
155       key->Set(elga->GetInformation(),def,vtkType);
156       key->Set(vtkd->GetInformation(),def,vtkType);
157       defs.push_back(std::pair< vtkQuadratureSchemeDefinition *, unsigned char >(def,vtkType));
158     }
159   //
160   vtkIdType ncell(ds->GetNumberOfCells());
161   int *pt(new int[ncell]),offset(0);
162   for(vtkIdType cellId=0;cellId<ncell;cellId++)
163     {
164       vtkCell *cell(ds->GetCell(cellId));
165       int delta(m[cell->GetCellType()]);
166       pt[cellId]=offset;
167       offset+=delta;
168     }
169   elga->GetInformation()->Set(MEDUtilities::ELGA(),1);
170   elga->SetVoidArray(pt,ncell,0,VTK_DATA_ARRAY_DELETE);
171   std::ostringstream oss; oss << "ELGA" << "@" << _loc_names.size();
172   std::string ossStr(oss.str());
173   elga->SetName(ossStr.c_str());
174   elga->GetInformation()->Set(vtkAbstractArray::GUI_HIDE(),1);
175   vtkd->GetInformation()->Set(vtkQuadratureSchemeDefinition::QUADRATURE_OFFSET_ARRAY_NAME(),elga->GetName());
176   elgas.push_back(elga);
177   //
178   _loc_names=locNames;
179   _elgas=elgas;
180   _defs.push_back(defs);
181   return elga;
182 }
183
184 void ELGACmp::appendELGAIfAny(vtkDataSet *ds) const
185 {
186   for(std::vector<vtkIdTypeArray *>::const_iterator it=_elgas.begin();it!=_elgas.end();it++)
187     ds->GetCellData()->AddArray(*it);
188 }
189
190 ELGACmp::~ELGACmp()
191 {
192   for(std::vector<vtkIdTypeArray *>::const_iterator it=_elgas.begin();it!=_elgas.end();it++)
193     (*it)->Delete();
194   for(std::vector< std::vector< std::pair< vtkQuadratureSchemeDefinition *, unsigned char > > >::const_iterator it0=_defs.begin();it0!=_defs.end();it0++)
195     for(std::vector< std::pair< vtkQuadratureSchemeDefinition *, unsigned char > >::const_iterator it1=(*it0).begin();it1!=(*it0).end();it1++)
196       (*it1).first->Delete();
197 }
198
199 //=
200
201 template<class T>
202 class MEDFileVTKTraits
203 {
204 public:
205   typedef void VtkType;
206   typedef void MCType;
207 };
208
209 template<>
210 class MEDFileVTKTraits<int>
211 {
212 public:
213   typedef vtkIntArray VtkType;
214   typedef MEDCoupling::DataArrayInt MCType;
215 };
216
217 template<>
218 class MEDFileVTKTraits<double>
219 {
220 public:
221   typedef vtkDoubleArray VtkType;
222   typedef MEDCoupling::DataArrayDouble MCType;
223 };
224
225 template<class T>
226 void AssignDataPointerToVTK(typename MEDFileVTKTraits<T>::VtkType *vtkTab, typename MEDFileVTKTraits<T>::MCType *mcTab, bool noCpyNumNodes)
227 {
228   if(noCpyNumNodes)
229     vtkTab->SetArray(mcTab->getPointer(),mcTab->getNbOfElems(),1,vtkDataArrayTemplate<T>::VTK_DATA_ARRAY_FREE);
230  else
231    { vtkTab->SetArray(mcTab->getPointer(),mcTab->getNbOfElems(),0,vtkDataArrayTemplate<T>::VTK_DATA_ARRAY_FREE); mcTab->accessToMemArray().setSpecificDeallocator(0); }
232 }
233
234 // here copy is always assumed.
235 template<class VTKT, class MCT>
236 void AssignDataPointerOther(VTKT *vtkTab, MCT *mcTab, int nbElems)
237 {
238   vtkTab->SetVoidArray(reinterpret_cast<unsigned char *>(mcTab->getPointer()),nbElems,0,VTKT::VTK_DATA_ARRAY_FREE);
239   mcTab->accessToMemArray().setSpecificDeallocator(0);
240 }
241
242 //=
243
244 MEDFileFieldRepresentationLeavesArrays::MEDFileFieldRepresentationLeavesArrays():_id(-1)
245 {
246 }
247
248 MEDFileFieldRepresentationLeavesArrays::MEDFileFieldRepresentationLeavesArrays(const MEDCoupling::MCAuto<MEDCoupling::MEDFileAnyTypeFieldMultiTS>& arr):MEDCoupling::MCAuto<MEDCoupling::MEDFileAnyTypeFieldMultiTS>(arr),_activated(false),_id(-1)
249 {
250   std::vector< std::vector<MEDCoupling::TypeOfField> > typs((operator->())->getTypesOfFieldAvailable());
251   if(typs.size()<1)
252     throw INTERP_KERNEL::Exception("There is a big internal problem in MEDLoader ! The field time spitting has failed ! A CRASH will occur soon !");
253   if(typs[0].size()!=1)
254     throw INTERP_KERNEL::Exception("There is a big internal problem in MEDLoader ! The field spitting by spatial discretization has failed ! A CRASH will occur soon !");
255   MEDCoupling::MCAuto<MEDCoupling::MEDCouplingFieldDiscretization> fd(MEDCouplingFieldDiscretization::New(typs[0][0]));
256   std::ostringstream oss2; oss2 << (operator->())->getName() << ZE_SEP << fd->getRepr();
257   _ze_name=oss2.str();
258 }
259
260 MEDFileFieldRepresentationLeavesArrays& MEDFileFieldRepresentationLeavesArrays::operator=(const MEDFileFieldRepresentationLeavesArrays& other)
261 {
262   MEDCoupling::MCAuto<MEDCoupling::MEDFileAnyTypeFieldMultiTS>::operator=(other);
263   _id=-1;
264   _activated=false;
265   _ze_name=other._ze_name;
266   _ze_full_name.clear();
267   return *this;
268 }
269
270 void MEDFileFieldRepresentationLeavesArrays::setId(int& id) const
271 {
272   _id=id++;
273 }
274
275 int MEDFileFieldRepresentationLeavesArrays::getId() const
276 {
277   return _id;
278 }
279
280 std::string MEDFileFieldRepresentationLeavesArrays::getZeName() const
281 {
282   return _ze_full_name;
283 }
284
285 const char *MEDFileFieldRepresentationLeavesArrays::getZeNameC() const
286 {
287   return _ze_full_name.c_str();
288 }
289
290 void MEDFileFieldRepresentationLeavesArrays::feedSIL(vtkMutableDirectedGraph* sil, vtkIdType root, vtkVariantArray *edge, std::vector<std::string>& names) const
291 {
292   vtkIdType refId(sil->AddChild(root,edge));
293   names.push_back(_ze_name);
294   //
295   if(MEDFileFieldRepresentationTree::IsFieldMeshRegardingInfo(((operator->())->getInfo())))
296     {
297       sil->AddChild(refId,edge);
298       names.push_back(std::string());
299     }
300 }
301
302 void MEDFileFieldRepresentationLeavesArrays::computeFullNameInLeaves(const std::string& tsName, const std::string& meshName, const std::string& comSupStr) const
303 {
304   std::ostringstream oss3; oss3 << tsName << "/" << meshName << "/" << comSupStr << "/" << _ze_name;
305   _ze_full_name=oss3.str();
306 }
307
308 bool MEDFileFieldRepresentationLeavesArrays::getStatus() const
309 {
310   return _activated;
311 }
312
313 bool MEDFileFieldRepresentationLeavesArrays::setStatus(bool status) const
314 {
315   bool ret(_activated!=status);
316   _activated=status;
317   return ret;
318 }
319
320 void MEDFileFieldRepresentationLeavesArrays::appendFields(const MEDTimeReq *tr, const MEDCoupling::MEDFileFieldGlobsReal *globs, const MEDCoupling::MEDMeshMultiLev *mml, const MEDCoupling::MEDFileMeshStruct *mst, vtkDataSet *ds) const
321 {
322   const int VTK_DATA_ARRAY_DELETE=vtkDataArrayTemplate<double>::VTK_DATA_ARRAY_DELETE;
323   tr->setNumberOfTS((operator->())->getNumberOfTS());
324   tr->initIterator();
325   for(int timeStepId=0;timeStepId<tr->size();timeStepId++,++(*tr))
326     {
327       MCAuto<MEDFileAnyTypeField1TS> f1ts((operator->())->getTimeStepAtPos(tr->getCurrent()));
328       MEDFileAnyTypeField1TS *f1tsPtr(f1ts);
329       MEDFileField1TS *f1tsPtrDbl(dynamic_cast<MEDFileField1TS *>(f1tsPtr));
330       MEDFileIntField1TS *f1tsPtrInt(dynamic_cast<MEDFileIntField1TS *>(f1tsPtr));
331       DataArray *crudeArr(0),*postProcessedArr(0);
332       if(f1tsPtrDbl)
333         crudeArr=f1tsPtrDbl->getUndergroundDataArray();
334       else if(f1tsPtrInt)
335         crudeArr=f1tsPtrInt->getUndergroundDataArray();
336       else
337         throw INTERP_KERNEL::Exception("MEDFileFieldRepresentationLeavesArrays::appendFields : only FLOAT64 and INT32 fields are dealt for the moment !");
338       MEDFileField1TSStructItem fsst(MEDFileField1TSStructItem::BuildItemFrom(f1ts,mst));
339       f1ts->loadArraysIfNecessary();
340       MCAuto<DataArray> v(mml->buildDataArray(fsst,globs,crudeArr));
341       postProcessedArr=v;
342       //
343       std::vector<TypeOfField> discs(f1ts->getTypesOfFieldAvailable());
344       if(discs.size()!=1)
345         throw INTERP_KERNEL::Exception("MEDFileFieldRepresentationLeavesArrays::appendFields : internal error ! Number of spatial discretizations must be equal to one !");
346       vtkFieldData *att(0);
347       switch(discs[0])
348         {
349         case ON_CELLS:
350           {
351             att=ds->GetCellData();
352             break;
353           }
354         case ON_NODES:
355           {
356             att=ds->GetPointData();
357             break;
358           }
359         case ON_GAUSS_NE:
360           {
361             att=ds->GetFieldData();
362             break;
363           }
364         case ON_GAUSS_PT:
365           {
366             att=ds->GetFieldData();
367             break;
368           }
369         default:
370           throw INTERP_KERNEL::Exception("MEDFileFieldRepresentationLeavesArrays::appendFields : only CELL and NODE, GAUSS_NE and GAUSS fields are available for the moment !");
371         }
372       if(f1tsPtrDbl)
373         {
374           DataArray *vPtr(v); DataArrayDouble *vd(static_cast<DataArrayDouble *>(vPtr));
375           vtkDoubleArray *vtkd(vtkDoubleArray::New());
376           vtkd->SetNumberOfComponents(vd->getNumberOfComponents());
377           for(int i=0;i<vd->getNumberOfComponents();i++)
378             vtkd->SetComponentName(i,vd->getInfoOnComponent(i).c_str());
379           AssignDataPointerToVTK<double>(vtkd,vd,postProcessedArr==crudeArr);
380           std::string name(tr->buildName(f1ts->getName()));
381           vtkd->SetName(name.c_str());
382           att->AddArray(vtkd);
383           vtkd->Delete();
384           if(discs[0]==ON_GAUSS_PT)
385             {
386               bool tmp;
387               _elga_cmp.findOrCreate(globs,f1ts->getLocsReallyUsed(),vtkd,ds,tmp);
388             }
389           if(discs[0]==ON_GAUSS_NE)
390             {
391               vtkIdTypeArray *elno(vtkIdTypeArray::New());
392               elno->SetNumberOfComponents(1);
393               vtkIdType ncell(ds->GetNumberOfCells());
394               int *pt(new int[ncell]),offset(0);
395               std::set<int> cellTypes;
396               for(vtkIdType cellId=0;cellId<ncell;cellId++)
397                 {
398                   vtkCell *cell(ds->GetCell(cellId));
399                   int delta(cell->GetNumberOfPoints());
400                   cellTypes.insert(cell->GetCellType());
401                   pt[cellId]=offset;
402                   offset+=delta;
403                 }
404               elno->GetInformation()->Set(MEDUtilities::ELNO(),1);
405               elno->SetVoidArray(pt,ncell,0,VTK_DATA_ARRAY_DELETE);
406               std::string nameElno("ELNO"); nameElno+="@"; nameElno+=name;
407               elno->SetName(nameElno.c_str());
408               ds->GetCellData()->AddArray(elno);
409               vtkd->GetInformation()->Set(vtkQuadratureSchemeDefinition::QUADRATURE_OFFSET_ARRAY_NAME(),elno->GetName());
410               elno->GetInformation()->Set(vtkAbstractArray::GUI_HIDE(),1);
411               //
412               vtkInformationQuadratureSchemeDefinitionVectorKey *key(vtkQuadratureSchemeDefinition::DICTIONARY());
413               for(std::set<int>::const_iterator it=cellTypes.begin();it!=cellTypes.end();it++)
414                 {
415                   const unsigned char *pos(std::find(MEDMeshMultiLev::PARAMEDMEM_2_VTKTYPE,MEDMeshMultiLev::PARAMEDMEM_2_VTKTYPE+MEDMeshMultiLev::PARAMEDMEM_2_VTKTYPE_LGTH,*it));
416                   if(pos==MEDMeshMultiLev::PARAMEDMEM_2_VTKTYPE+MEDMeshMultiLev::PARAMEDMEM_2_VTKTYPE_LGTH)
417                     continue;
418                   INTERP_KERNEL::NormalizedCellType ct((INTERP_KERNEL::NormalizedCellType)std::distance(MEDMeshMultiLev::PARAMEDMEM_2_VTKTYPE,pos));
419                   const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(ct));
420                   int nbGaussPt(cm.getNumberOfNodes()),dim(cm.getDimension());
421                   vtkQuadratureSchemeDefinition *def(vtkQuadratureSchemeDefinition::New());
422                   double *shape(new double[nbGaussPt*nbGaussPt]);
423                   std::size_t dummy;
424                   const double *gsCoords(MEDCouplingFieldDiscretizationGaussNE::GetRefCoordsFromGeometricType(ct,dummy));//GetLocsFromGeometricType
425                   const double *refCoords(MEDCouplingFieldDiscretizationGaussNE::GetRefCoordsFromGeometricType(ct,dummy));
426                   const double *weights(MEDCouplingFieldDiscretizationGaussNE::GetWeightArrayFromGeometricType(ct,dummy));
427                   std::vector<double> gsCoords2(gsCoords,gsCoords+nbGaussPt*dim),refCoords2(refCoords,refCoords+nbGaussPt*dim);
428                   INTERP_KERNEL::GaussInfo calculator(ct,gsCoords2,nbGaussPt,refCoords2,nbGaussPt);
429                   calculator.initLocalInfo();
430                   for(int i=0;i<nbGaussPt;i++)
431                     {
432                       const double *pt0(calculator.getFunctionValues(i));
433                       std::copy(pt0,pt0+nbGaussPt,shape+nbGaussPt*i);
434                     }
435                   def->Initialize(*it,nbGaussPt,nbGaussPt,shape,const_cast<double *>(weights));
436                   delete [] shape;
437                   key->Set(elno->GetInformation(),def,*it);
438                   key->Set(vtkd->GetInformation(),def,*it);
439                   def->Delete();
440                 }
441               //
442               elno->Delete();
443             }
444         }
445       else if(f1tsPtrInt)
446         {
447           DataArray *vPtr(v); DataArrayInt *vi(static_cast<DataArrayInt *>(vPtr));
448           vtkIntArray *vtkd(vtkIntArray::New());
449           vtkd->SetNumberOfComponents(vi->getNumberOfComponents());
450           for(int i=0;i<vi->getNumberOfComponents();i++)
451             vtkd->SetComponentName(i,vi->getVarOnComponent(i).c_str());
452           AssignDataPointerToVTK<int>(vtkd,vi,postProcessedArr==crudeArr);
453           std::string name(tr->buildName(f1ts->getName()));
454           vtkd->SetName(name.c_str());
455           att->AddArray(vtkd);
456           vtkd->Delete();
457         }
458       else
459         throw INTERP_KERNEL::Exception("MEDFileFieldRepresentationLeavesArrays::appendFields : only FLOAT64 and INT32 fields are dealt for the moment ! Internal Error !");
460     }
461 }
462
463 void MEDFileFieldRepresentationLeavesArrays::appendELGAIfAny(vtkDataSet *ds) const
464 {
465   _elga_cmp.appendELGAIfAny(ds);
466 }
467
468 ////////////////////
469
470 MEDFileFieldRepresentationLeaves::MEDFileFieldRepresentationLeaves():_cached_ds(0)
471 {
472 }
473
474 MEDFileFieldRepresentationLeaves::MEDFileFieldRepresentationLeaves(const std::vector< MEDCoupling::MCAuto<MEDCoupling::MEDFileAnyTypeFieldMultiTS> >& arr,
475                                                                    const MEDCoupling::MCAuto<MEDCoupling::MEDFileFastCellSupportComparator>& fsp):_arrays(arr.size()),_fsp(fsp),_cached_ds(0)
476 {
477   for(std::size_t i=0;i<arr.size();i++)
478     _arrays[i]=MEDFileFieldRepresentationLeavesArrays(arr[i]);
479 }
480
481 MEDFileFieldRepresentationLeaves::~MEDFileFieldRepresentationLeaves()
482 {
483   if(_cached_ds)
484     _cached_ds->Delete();
485 }
486
487 bool MEDFileFieldRepresentationLeaves::empty() const
488 {
489   const MEDFileFastCellSupportComparator *fcscp(_fsp);
490   return fcscp==0 || _arrays.empty();
491 }
492
493 void MEDFileFieldRepresentationLeaves::setId(int& id) const
494 {
495   for(std::vector<MEDFileFieldRepresentationLeavesArrays>::const_iterator it=_arrays.begin();it!=_arrays.end();it++)
496     (*it).setId(id);
497 }
498
499 std::string MEDFileFieldRepresentationLeaves::getMeshName() const
500 {
501   return _arrays[0]->getMeshName();
502 }
503
504 int MEDFileFieldRepresentationLeaves::getNumberOfArrays() const
505 {
506   return (int)_arrays.size();
507 }
508
509 int MEDFileFieldRepresentationLeaves::getNumberOfTS() const
510 {
511   return _arrays[0]->getNumberOfTS();
512 }
513
514 void MEDFileFieldRepresentationLeaves::computeFullNameInLeaves(const std::string& tsName, const std::string& meshName, const std::string& comSupStr) const
515 {
516   for(std::vector<MEDFileFieldRepresentationLeavesArrays>::const_iterator it=_arrays.begin();it!=_arrays.end();it++)
517     (*it).computeFullNameInLeaves(tsName,meshName,comSupStr);
518 }
519
520 /*!
521  * \param [in] ms is the meshes pointer. It can be used only for information of geometric types. No special processing will be requested on ms.
522  */
523 void MEDFileFieldRepresentationLeaves::feedSIL(const MEDCoupling::MEDFileMeshes *ms, const std::string& meshName, vtkMutableDirectedGraph* sil, vtkIdType root, vtkVariantArray *edge, std::vector<std::string>& names) const
524 {
525   vtkIdType root2(sil->AddChild(root,edge));
526   names.push_back(std::string("Arrs"));
527   for(std::vector<MEDFileFieldRepresentationLeavesArrays>::const_iterator it=_arrays.begin();it!=_arrays.end();it++)
528     (*it).feedSIL(sil,root2,edge,names);
529   //
530   vtkIdType root3(sil->AddChild(root,edge));
531   names.push_back(std::string("InfoOnGeoType"));
532   const MEDCoupling::MEDFileMesh *m(0);
533   if(ms)
534     m=ms->getMeshWithName(meshName);
535   const MEDCoupling::MEDFileFastCellSupportComparator *fsp(_fsp);
536   if(!fsp || fsp->getNumberOfTS()==0)
537     return ;
538   std::vector< INTERP_KERNEL::NormalizedCellType > gts(fsp->getGeoTypesAt(0,m));
539   for(std::vector< INTERP_KERNEL::NormalizedCellType >::const_iterator it2=gts.begin();it2!=gts.end();it2++)
540     {
541       const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(*it2));
542       std::string cmStr(cm.getRepr()); cmStr=cmStr.substr(5);//skip "NORM_"
543       sil->AddChild(root3,edge);
544       names.push_back(cmStr);
545     }
546 }
547
548 bool MEDFileFieldRepresentationLeaves::containId(int id) const
549 {
550   for(std::vector<MEDFileFieldRepresentationLeavesArrays>::const_iterator it=_arrays.begin();it!=_arrays.end();it++)
551     if((*it).getId()==id)
552       return true;
553   return false;
554 }
555
556 bool MEDFileFieldRepresentationLeaves::containZeName(const char *name, int& id) const
557 {
558   for(std::vector<MEDFileFieldRepresentationLeavesArrays>::const_iterator it=_arrays.begin();it!=_arrays.end();it++)
559     if((*it).getZeName()==name)
560       {
561         id=(*it).getId();
562         return true;
563       }
564   return false;
565 }
566
567 void MEDFileFieldRepresentationLeaves::dumpState(std::map<std::string,bool>& status) const
568 {
569   for(std::vector<MEDFileFieldRepresentationLeavesArrays>::const_iterator it=_arrays.begin();it!=_arrays.end();it++)
570     status[(*it).getZeName()]=(*it).getStatus();
571 }
572
573 bool MEDFileFieldRepresentationLeaves::isActivated() const
574 {
575   for(std::vector<MEDFileFieldRepresentationLeavesArrays>::const_iterator it=_arrays.begin();it!=_arrays.end();it++)
576     if((*it).getStatus())
577       return true;
578   return false;
579 }
580
581 void MEDFileFieldRepresentationLeaves::printMySelf(std::ostream& os) const
582 {
583   for(std::vector<MEDFileFieldRepresentationLeavesArrays>::const_iterator it0=_arrays.begin();it0!=_arrays.end();it0++)
584     {
585       os << "         - " << (*it0).getZeName() << " (";
586       if((*it0).getStatus())
587         os << "X";
588       else
589         os << " ";
590       os << ")" << std::endl;
591     }
592 }
593
594 void MEDFileFieldRepresentationLeaves::activateAllArrays() const
595 {
596   for(std::vector<MEDFileFieldRepresentationLeavesArrays>::const_iterator it=_arrays.begin();it!=_arrays.end();it++)
597     (*it).setStatus(true);
598 }
599
600 const MEDFileFieldRepresentationLeavesArrays& MEDFileFieldRepresentationLeaves::getLeafArr(int id) const
601 {
602   for(std::vector<MEDFileFieldRepresentationLeavesArrays>::const_iterator it=_arrays.begin();it!=_arrays.end();it++)
603     if((*it).getId()==id)
604       return *it;
605   throw INTERP_KERNEL::Exception("MEDFileFieldRepresentationLeaves::getLeafArr ! No such id !");
606 }
607
608 std::vector<double> MEDFileFieldRepresentationLeaves::getTimeSteps(const TimeKeeper& tk) const
609 {
610   if(_arrays.size()<1)
611     throw INTERP_KERNEL::Exception("MEDFileFieldRepresentationLeaves::getTimeSteps : the array size must be at least of size one !");
612   std::vector<double> ret;
613   std::vector< std::pair<int,int> > dtits(_arrays[0]->getTimeSteps(ret));
614   return tk.getTimeStepsRegardingPolicy(dtits,ret);
615 }
616
617 std::vector< std::pair<int,int> > MEDFileFieldRepresentationLeaves::getTimeStepsInCoarseMEDFileFormat(std::vector<double>& ts) const
618 {
619   if(!_arrays.empty())
620     return _arrays[0]->getTimeSteps(ts);
621   else
622     {
623       ts.clear();
624       return std::vector< std::pair<int,int> >();
625     }
626 }
627
628 std::string MEDFileFieldRepresentationLeaves::getHumanReadableOverviewOfTS() const
629 {
630   std::ostringstream oss;
631   oss << _arrays[0]->getNumberOfTS() << " time steps [" << _arrays[0]->getDtUnit() << "]\n(";
632   std::vector<double> ret1;
633   std::vector< std::pair<int,int> > ret2(getTimeStepsInCoarseMEDFileFormat(ret1));
634   std::size_t sz(ret1.size());
635   for(std::size_t i=0;i<sz;i++)
636     {
637       oss << ret1[i] << " (" << ret2[i].first << "," << ret2[i].second << ")";
638       if(i!=sz-1)
639         oss << ", ";
640       std::string tmp(oss.str());
641       if(tmp.size()>200 && i!=sz-1)
642         {
643           oss << "...";
644           break;
645         }
646     }
647   oss << ")";
648   return oss.str();
649 }
650
651 void MEDFileFieldRepresentationLeaves::appendFields(const MEDTimeReq *tr, const MEDCoupling::MEDFileFieldGlobsReal *globs, const MEDCoupling::MEDMeshMultiLev *mml, const MEDCoupling::MEDFileMeshes *meshes, vtkDataSet *ds) const
652 {
653   if(_arrays.size()<1)
654     throw INTERP_KERNEL::Exception("MEDFileFieldRepresentationLeaves::appendFields : internal error !");
655   MCAuto<MEDFileMeshStruct> mst(MEDFileMeshStruct::New(meshes->getMeshWithName(_arrays[0]->getMeshName().c_str())));
656   for(std::vector<MEDFileFieldRepresentationLeavesArrays>::const_iterator it=_arrays.begin();it!=_arrays.end();it++)
657     if((*it).getStatus())
658       {
659         (*it).appendFields(tr,globs,mml,mst,ds);
660         (*it).appendELGAIfAny(ds);
661       }
662 }
663
664 vtkUnstructuredGrid *MEDFileFieldRepresentationLeaves::buildVTKInstanceNoTimeInterpolationUnstructured(MEDUMeshMultiLev *mm) const
665 {
666   DataArrayDouble *coordsMC(0);
667   DataArrayByte *typesMC(0);
668   DataArrayInt *cellLocationsMC(0),*cellsMC(0),*faceLocationsMC(0),*facesMC(0);
669   bool statusOfCoords(mm->buildVTUArrays(coordsMC,typesMC,cellLocationsMC,cellsMC,faceLocationsMC,facesMC));
670   MCAuto<DataArrayDouble> coordsSafe(coordsMC);
671   MCAuto<DataArrayByte> typesSafe(typesMC);
672   MCAuto<DataArrayInt> cellLocationsSafe(cellLocationsMC),cellsSafe(cellsMC),faceLocationsSafe(faceLocationsMC),facesSafe(facesMC);
673   //
674   int nbOfCells(typesSafe->getNbOfElems());
675   vtkUnstructuredGrid *ret(vtkUnstructuredGrid::New());
676   vtkUnsignedCharArray *cellTypes(vtkUnsignedCharArray::New());
677   AssignDataPointerOther<vtkUnsignedCharArray,DataArrayByte>(cellTypes,typesSafe,nbOfCells);
678   vtkIdTypeArray *cellLocations(vtkIdTypeArray::New());
679   AssignDataPointerOther<vtkIdTypeArray,DataArrayInt>(cellLocations,cellLocationsSafe,nbOfCells);
680   vtkCellArray *cells(vtkCellArray::New());
681   vtkIdTypeArray *cells2(vtkIdTypeArray::New());
682   AssignDataPointerOther<vtkIdTypeArray,DataArrayInt>(cells2,cellsSafe,cellsSafe->getNbOfElems());
683   cells->SetCells(nbOfCells,cells2);
684   cells2->Delete();
685   if(faceLocationsMC!=0 && facesMC!=0)
686     {
687       vtkIdTypeArray *faces(vtkIdTypeArray::New());
688       AssignDataPointerOther<vtkIdTypeArray,DataArrayInt>(faces,facesSafe,facesSafe->getNbOfElems());
689       vtkIdTypeArray *faceLocations(vtkIdTypeArray::New());
690       AssignDataPointerOther<vtkIdTypeArray,DataArrayInt>(faceLocations,faceLocationsSafe,faceLocationsSafe->getNbOfElems());
691       ret->SetCells(cellTypes,cellLocations,cells,faceLocations,faces);
692       faceLocations->Delete();
693       faces->Delete();
694     }
695   else
696     ret->SetCells(cellTypes,cellLocations,cells);
697   cellTypes->Delete();
698   cellLocations->Delete();
699   cells->Delete();
700   vtkPoints *pts(vtkPoints::New());
701   vtkDoubleArray *pts2(vtkDoubleArray::New());
702   pts2->SetNumberOfComponents(3);
703   AssignDataPointerToVTK<double>(pts2,coordsSafe,statusOfCoords);
704   pts->SetData(pts2);
705   pts2->Delete();
706   ret->SetPoints(pts);
707   pts->Delete();
708   //
709   return ret;
710 }
711
712 vtkRectilinearGrid *MEDFileFieldRepresentationLeaves::buildVTKInstanceNoTimeInterpolationCartesian(MEDCoupling::MEDCMeshMultiLev *mm) const
713 {
714   bool isInternal;
715   std::vector< DataArrayDouble * > arrs(mm->buildVTUArrays(isInternal));
716   vtkDoubleArray *vtkTmp(0);
717   vtkRectilinearGrid *ret(vtkRectilinearGrid::New());
718   std::size_t dim(arrs.size());
719   if(dim<1 || dim>3)
720     throw INTERP_KERNEL::Exception("buildVTKInstanceNoTimeInterpolationCartesian : dimension must be in [1,3] !");
721   int sizePerAxe[3]={1,1,1};
722   sizePerAxe[0]=arrs[0]->getNbOfElems();
723   if(dim>=2)
724     sizePerAxe[1]=arrs[1]->getNbOfElems();
725   if(dim==3)
726     sizePerAxe[2]=arrs[2]->getNbOfElems();
727   ret->SetDimensions(sizePerAxe[0],sizePerAxe[1],sizePerAxe[2]);
728   vtkTmp=vtkDoubleArray::New();
729   vtkTmp->SetNumberOfComponents(1);
730   AssignDataPointerToVTK<double>(vtkTmp,arrs[0],isInternal);
731   ret->SetXCoordinates(vtkTmp);
732   vtkTmp->Delete();
733   arrs[0]->decrRef();
734   if(dim>=2)
735     {
736       vtkTmp=vtkDoubleArray::New();
737       vtkTmp->SetNumberOfComponents(1);
738       AssignDataPointerToVTK<double>(vtkTmp,arrs[1],isInternal);
739       ret->SetYCoordinates(vtkTmp);
740       vtkTmp->Delete();
741       arrs[1]->decrRef();
742     }
743   if(dim==3)
744     {
745       vtkTmp=vtkDoubleArray::New();
746       vtkTmp->SetNumberOfComponents(1);
747       AssignDataPointerToVTK<double>(vtkTmp,arrs[2],isInternal);
748       ret->SetZCoordinates(vtkTmp);
749       vtkTmp->Delete();
750       arrs[2]->decrRef();
751     }
752   return ret;
753 }
754
755 vtkStructuredGrid *MEDFileFieldRepresentationLeaves::buildVTKInstanceNoTimeInterpolationCurveLinear(MEDCoupling::MEDCurveLinearMeshMultiLev *mm) const
756 {
757   int meshStr[3]={1,1,1};
758   DataArrayDouble *coords(0);
759   std::vector<int> nodeStrct;
760   bool isInternal;
761   mm->buildVTUArrays(coords,nodeStrct,isInternal);
762   std::size_t dim(nodeStrct.size());
763   if(dim<1 || dim>3)
764     throw INTERP_KERNEL::Exception("buildVTKInstanceNoTimeInterpolationCurveLinear : dimension must be in [1,3] !");
765   meshStr[0]=nodeStrct[0];
766   if(dim>=2)
767     meshStr[1]=nodeStrct[1];
768   if(dim==3)
769     meshStr[2]=nodeStrct[2];
770   vtkStructuredGrid *ret(vtkStructuredGrid::New());
771   ret->SetDimensions(meshStr[0],meshStr[1],meshStr[2]);
772   vtkDoubleArray *da(vtkDoubleArray::New());
773   da->SetNumberOfComponents(3);
774   if(coords->getNumberOfComponents()==3)
775     AssignDataPointerToVTK<double>(da,coords,isInternal);//if isIntenal==True VTK has not the ownership of double * because MEDLoader main struct has it !
776   else
777     {
778       MCAuto<DataArrayDouble> coords2(coords->changeNbOfComponents(3,0.));
779       AssignDataPointerToVTK<double>(da,coords2,false);//let VTK deal with double *
780     }
781   coords->decrRef();
782   vtkPoints *points=vtkPoints::New();
783   ret->SetPoints(points);
784   points->SetData(da);
785   points->Delete();
786   da->Delete();
787   return ret;
788 }
789  
790 vtkDataSet *MEDFileFieldRepresentationLeaves::buildVTKInstanceNoTimeInterpolation(const MEDTimeReq *tr, const MEDFileFieldGlobsReal *globs, const MEDCoupling::MEDFileMeshes *meshes) const
791 {
792   vtkDataSet *ret(0);
793   //_fsp->isDataSetSupportEqualToThePreviousOne(i,globs);
794   MCAuto<MEDMeshMultiLev> mml(_fsp->buildFromScratchDataSetSupport(0,globs));//0=timestep Id. Make the hypothesis that support does not change 
795   MCAuto<MEDMeshMultiLev> mml2(mml->prepare());
796   MEDMeshMultiLev *ptMML2(mml2);
797   if(!_cached_ds)
798     {
799       MEDUMeshMultiLev *ptUMML2(dynamic_cast<MEDUMeshMultiLev *>(ptMML2));
800       MEDCMeshMultiLev *ptCMML2(dynamic_cast<MEDCMeshMultiLev *>(ptMML2));
801       MEDCurveLinearMeshMultiLev *ptCLMML2(dynamic_cast<MEDCurveLinearMeshMultiLev *>(ptMML2));
802       
803       if(ptUMML2)
804         {
805           ret=buildVTKInstanceNoTimeInterpolationUnstructured(ptUMML2);
806         }
807       else if(ptCMML2)
808         {
809           ret=buildVTKInstanceNoTimeInterpolationCartesian(ptCMML2);
810         }
811       else if(ptCLMML2)
812         {
813           ret=buildVTKInstanceNoTimeInterpolationCurveLinear(ptCLMML2);
814         }
815       else
816         throw INTERP_KERNEL::Exception("MEDFileFieldRepresentationLeaves::buildVTKInstanceNoTimeInterpolation : unrecognized mesh ! Supported for the moment unstructured, cartesian, curvelinear !");
817       _cached_ds=ret->NewInstance();
818       _cached_ds->ShallowCopy(ret);
819     }
820   else
821     {
822       ret=_cached_ds->NewInstance();
823       ret->ShallowCopy(_cached_ds);
824     }
825   //
826   appendFields(tr,globs,mml,meshes,ret);
827   // The arrays links to mesh
828   DataArrayInt *famCells(0),*numCells(0);
829   bool noCpyFamCells(false),noCpyNumCells(false);
830   ptMML2->retrieveFamilyIdsOnCells(famCells,noCpyFamCells);
831   if(famCells)
832     {
833       vtkIntArray *vtkTab(vtkIntArray::New());
834       vtkTab->SetNumberOfComponents(1);
835       vtkTab->SetName(MEDFileFieldRepresentationLeavesArrays::FAMILY_ID_CELL_NAME);
836       AssignDataPointerToVTK<int>(vtkTab,famCells,noCpyFamCells);
837       ret->GetCellData()->AddArray(vtkTab);
838       vtkTab->Delete();
839       famCells->decrRef();
840     }
841   ptMML2->retrieveNumberIdsOnCells(numCells,noCpyNumCells);
842   if(numCells)
843     {
844       vtkIntArray *vtkTab(vtkIntArray::New());
845       vtkTab->SetNumberOfComponents(1);
846       vtkTab->SetName(MEDFileFieldRepresentationLeavesArrays::NUM_ID_CELL_NAME);
847       AssignDataPointerToVTK<int>(vtkTab,numCells,noCpyNumCells);
848       ret->GetCellData()->AddArray(vtkTab);
849       vtkTab->Delete();
850       numCells->decrRef();
851     }
852   // The arrays links to mesh
853   DataArrayInt *famNodes(0),*numNodes(0);
854   bool noCpyFamNodes(false),noCpyNumNodes(false);
855   ptMML2->retrieveFamilyIdsOnNodes(famNodes,noCpyFamNodes);
856   if(famNodes)
857     {
858       vtkIntArray *vtkTab(vtkIntArray::New());
859       vtkTab->SetNumberOfComponents(1);
860       vtkTab->SetName(MEDFileFieldRepresentationLeavesArrays::FAMILY_ID_NODE_NAME);
861       AssignDataPointerToVTK<int>(vtkTab,famNodes,noCpyFamNodes);
862       ret->GetPointData()->AddArray(vtkTab);
863       vtkTab->Delete();
864       famNodes->decrRef();
865     }
866   ptMML2->retrieveNumberIdsOnNodes(numNodes,noCpyNumNodes);
867   if(numNodes)
868     {
869       vtkIntArray *vtkTab(vtkIntArray::New());
870       vtkTab->SetNumberOfComponents(1);
871       vtkTab->SetName(MEDFileFieldRepresentationLeavesArrays::NUM_ID_NODE_NAME);
872       AssignDataPointerToVTK<int>(vtkTab,numNodes,noCpyNumNodes);
873       ret->GetPointData()->AddArray(vtkTab);
874       vtkTab->Delete();
875       numNodes->decrRef();
876     }
877   // Global Node Ids if any ! (In // mode)
878   DataArrayInt *gni(ptMML2->retrieveGlobalNodeIdsIfAny());
879   if(gni)
880     {
881       vtkIntArray *vtkTab(vtkIntArray::New());
882       vtkTab->SetNumberOfComponents(1);
883       vtkTab->SetName(MEDFileFieldRepresentationLeavesArrays::GLOBAL_NODE_ID_NAME);
884       AssignDataPointerToVTK<int>(vtkTab,gni,false);
885       ret->GetPointData()->AddArray(vtkTab);
886       vtkTab->Delete();
887       gni->decrRef();
888     }
889   return ret;
890 }
891
892 //////////////////////
893
894 MEDFileFieldRepresentationTree::MEDFileFieldRepresentationTree()
895 {
896 }
897
898 int MEDFileFieldRepresentationTree::getNumberOfLeavesArrays() const
899 {
900   int ret(0);
901   for(std::vector< std::vector< std::vector< MEDFileFieldRepresentationLeaves > > >::const_iterator it0=_data_structure.begin();it0!=_data_structure.end();it0++)
902     for(std::vector< std::vector< MEDFileFieldRepresentationLeaves > >::const_iterator it1=(*it0).begin();it1!=(*it0).end();it1++)
903       for(std::vector< MEDFileFieldRepresentationLeaves >::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
904         ret+=(*it2).getNumberOfArrays();
905   return ret;
906 }
907
908 void MEDFileFieldRepresentationTree::assignIds() const
909 {
910   int zeId(0);
911   for(std::vector< std::vector< std::vector< MEDFileFieldRepresentationLeaves > > >::const_iterator it0=_data_structure.begin();it0!=_data_structure.end();it0++)
912     for(std::vector< std::vector< MEDFileFieldRepresentationLeaves > >::const_iterator it1=(*it0).begin();it1!=(*it0).end();it1++)
913       for(std::vector< MEDFileFieldRepresentationLeaves >::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
914         (*it2).setId(zeId);
915 }
916
917 void MEDFileFieldRepresentationTree::computeFullNameInLeaves() const
918 {
919    std::size_t it0Cnt(0);
920    for(std::vector< std::vector< std::vector< MEDFileFieldRepresentationLeaves > > >::const_iterator it0=_data_structure.begin();it0!=_data_structure.end();it0++,it0Cnt++)
921      {
922        std::ostringstream oss; oss << MEDFileFieldRepresentationLeavesArrays::TS_STR << it0Cnt;
923        std::string tsName(oss.str());
924        for(std::vector< std::vector< MEDFileFieldRepresentationLeaves > >::const_iterator it1=(*it0).begin();it1!=(*it0).end();it1++)
925          {
926            std::string meshName((*it1)[0].getMeshName());
927            std::size_t it2Cnt(0);
928            for(std::vector< MEDFileFieldRepresentationLeaves >::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++,it2Cnt++)
929              {
930                std::ostringstream oss2; oss2 << MEDFileFieldRepresentationLeavesArrays::COM_SUP_STR << it2Cnt;
931                std::string comSupStr(oss2.str());
932                (*it2).computeFullNameInLeaves(tsName,meshName,comSupStr);
933              }
934          }
935      }
936 }
937
938 void MEDFileFieldRepresentationTree::activateTheFirst() const
939 {
940   for(std::vector< std::vector< std::vector< MEDFileFieldRepresentationLeaves > > >::const_iterator it0=_data_structure.begin();it0!=_data_structure.end();it0++)
941     for(std::vector< std::vector< MEDFileFieldRepresentationLeaves > >::const_iterator it1=(*it0).begin();it1!=(*it0).end();it1++)
942       for(std::vector< MEDFileFieldRepresentationLeaves >::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
943         {
944           (*it2).activateAllArrays();
945           return ;
946         }
947 }
948
949 void MEDFileFieldRepresentationTree::feedSIL(vtkMutableDirectedGraph* sil, vtkIdType root, vtkVariantArray *edge, std::vector<std::string>& names) const
950 {
951   std::size_t it0Cnt(0);
952   for(std::vector< std::vector< std::vector< MEDFileFieldRepresentationLeaves > > >::const_iterator it0=_data_structure.begin();it0!=_data_structure.end();it0++,it0Cnt++)
953     {
954       vtkIdType InfoOnTSId(sil->AddChild(root,edge));
955       names.push_back((*it0)[0][0].getHumanReadableOverviewOfTS());
956       //
957       vtkIdType NbOfTSId(sil->AddChild(InfoOnTSId,edge));
958       std::vector<double> ts;
959       std::vector< std::pair<int,int> > dtits((*it0)[0][0].getTimeStepsInCoarseMEDFileFormat(ts));
960       std::size_t nbOfTS(dtits.size());
961       std::ostringstream oss3; oss3 << nbOfTS;
962       names.push_back(oss3.str());
963       for(std::size_t i=0;i<nbOfTS;i++)
964         {
965           std::ostringstream oss4; oss4 << dtits[i].first;
966           vtkIdType DtId(sil->AddChild(NbOfTSId,edge));
967           names.push_back(oss4.str());
968           std::ostringstream oss5; oss5 << dtits[i].second;
969           vtkIdType ItId(sil->AddChild(DtId,edge));
970           names.push_back(oss5.str());
971           std::ostringstream oss6; oss6 << ts[i];
972           sil->AddChild(ItId,edge);
973           names.push_back(oss6.str());
974         }
975       //
976       std::ostringstream oss; oss << MEDFileFieldRepresentationLeavesArrays::TS_STR << it0Cnt;
977       std::string tsName(oss.str());
978       vtkIdType typeId0(sil->AddChild(root,edge));
979       names.push_back(tsName);
980       for(std::vector< std::vector< MEDFileFieldRepresentationLeaves > >::const_iterator it1=(*it0).begin();it1!=(*it0).end();it1++)
981         {
982           std::string meshName((*it1)[0].getMeshName());
983           vtkIdType typeId1(sil->AddChild(typeId0,edge));
984           names.push_back(meshName);
985           std::size_t it2Cnt(0);
986           for(std::vector< MEDFileFieldRepresentationLeaves >::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++,it2Cnt++)
987             {
988               std::ostringstream oss2; oss2 << MEDFileFieldRepresentationLeavesArrays::COM_SUP_STR << it2Cnt;
989               std::string comSupStr(oss2.str());
990               vtkIdType typeId2(sil->AddChild(typeId1,edge));
991               names.push_back(comSupStr);
992               (*it2).feedSIL(_ms,meshName,sil,typeId2,edge,names);
993             } 
994         }
995     }
996 }
997
998 std::string MEDFileFieldRepresentationTree::getActiveMeshName() const
999 {
1000   int dummy0(0),dummy1(0),dummy2(0);
1001   const MEDFileFieldRepresentationLeaves& leaf(getTheSingleActivated(dummy0,dummy1,dummy2));
1002   return leaf.getMeshName();
1003 }
1004
1005 std::string MEDFileFieldRepresentationTree::feedSILForFamsAndGrps(vtkMutableDirectedGraph* sil, vtkIdType root, vtkVariantArray *edge, std::vector<std::string>& names) const
1006 {
1007   int dummy0(0),dummy1(0),dummy2(0);
1008   const MEDFileFieldRepresentationLeaves& leaf(getTheSingleActivated(dummy0,dummy1,dummy2));
1009   std::string ret(leaf.getMeshName());
1010   int i(0);
1011   MEDFileMesh *m(0);
1012   for(;i<_ms->getNumberOfMeshes();i++)
1013     {
1014       m=_ms->getMeshAtPos(i);
1015       if(m->getName()==ret)
1016         break;
1017     }
1018   if(i==_ms->getNumberOfMeshes())
1019     throw INTERP_KERNEL::Exception("MEDFileFieldRepresentationTree::feedSILForFamsAndGrps : internal error #0 !");
1020   vtkIdType typeId0(sil->AddChild(root,edge));
1021   names.push_back(m->getName());
1022   //
1023   vtkIdType typeId1(sil->AddChild(typeId0,edge));
1024   names.push_back(std::string(ROOT_OF_GRPS_IN_TREE));
1025   std::vector<std::string> grps(m->getGroupsNames());
1026   for(std::vector<std::string>::const_iterator it0=grps.begin();it0!=grps.end();it0++)
1027     {
1028       vtkIdType typeId2(sil->AddChild(typeId1,edge));
1029       names.push_back(*it0);
1030       std::vector<std::string> famsOnGrp(m->getFamiliesOnGroup((*it0).c_str()));
1031       for(std::vector<std::string>::const_iterator it1=famsOnGrp.begin();it1!=famsOnGrp.end();it1++)
1032         {
1033           sil->AddChild(typeId2,edge);
1034           names.push_back((*it1).c_str());
1035         }
1036     }
1037   //
1038   vtkIdType typeId11(sil->AddChild(typeId0,edge));
1039   names.push_back(std::string(ROOT_OF_FAM_IDS_IN_TREE));
1040   std::vector<std::string> fams(m->getFamiliesNames());
1041   for(std::vector<std::string>::const_iterator it00=fams.begin();it00!=fams.end();it00++)
1042     {
1043       sil->AddChild(typeId11,edge);
1044       int famId(m->getFamilyId((*it00).c_str()));
1045       std::ostringstream oss; oss << (*it00) << MEDFileFieldRepresentationLeavesArrays::ZE_SEP << famId;
1046       names.push_back(oss.str());
1047     }
1048   return ret;
1049 }
1050
1051 const MEDFileFieldRepresentationLeavesArrays& MEDFileFieldRepresentationTree::getLeafArr(int id) const
1052 {
1053   for(std::vector< std::vector< std::vector< MEDFileFieldRepresentationLeaves > > >::const_iterator it0=_data_structure.begin();it0!=_data_structure.end();it0++)
1054     for(std::vector< std::vector< MEDFileFieldRepresentationLeaves > >::const_iterator it1=(*it0).begin();it1!=(*it0).end();it1++)
1055       for(std::vector< MEDFileFieldRepresentationLeaves >::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
1056         if((*it2).containId(id))
1057           return (*it2).getLeafArr(id);
1058   throw INTERP_KERNEL::Exception("Internal error in MEDFileFieldRepresentationTree::getLeafArr !");
1059 }
1060
1061 std::string MEDFileFieldRepresentationTree::getNameOf(int id) const
1062 {
1063   const MEDFileFieldRepresentationLeavesArrays& elt(getLeafArr(id));
1064   return elt.getZeName();
1065 }
1066
1067 const char *MEDFileFieldRepresentationTree::getNameOfC(int id) const
1068 {
1069   const MEDFileFieldRepresentationLeavesArrays& elt(getLeafArr(id));
1070   return elt.getZeNameC();
1071 }
1072
1073 bool MEDFileFieldRepresentationTree::getStatusOf(int id) const
1074 {
1075   const MEDFileFieldRepresentationLeavesArrays& elt(getLeafArr(id));
1076   return elt.getStatus();
1077 }
1078
1079 int MEDFileFieldRepresentationTree::getIdHavingZeName(const char *name) const
1080 {
1081   int ret(-1);
1082   for(std::vector< std::vector< std::vector< MEDFileFieldRepresentationLeaves > > >::const_iterator it0=_data_structure.begin();it0!=_data_structure.end();it0++)
1083     for(std::vector< std::vector< MEDFileFieldRepresentationLeaves > >::const_iterator it1=(*it0).begin();it1!=(*it0).end();it1++)
1084       for(std::vector< MEDFileFieldRepresentationLeaves >::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
1085         if((*it2).containZeName(name,ret))
1086           return ret;
1087   std::ostringstream msg; msg << "MEDFileFieldRepresentationTree::getIdHavingZeName : No such a name \"" << name << "\" !";
1088   throw INTERP_KERNEL::Exception(msg.str().c_str());
1089 }
1090
1091 bool MEDFileFieldRepresentationTree::changeStatusOfAndUpdateToHaveCoherentVTKDataSet(int id, bool status) const
1092 {
1093   const MEDFileFieldRepresentationLeavesArrays& elt(getLeafArr(id));
1094   bool ret(elt.setStatus(status));//to be implemented
1095   return ret;
1096 }
1097
1098 int MEDFileFieldRepresentationTree::getMaxNumberOfTimeSteps() const
1099 {
1100   int ret(0);
1101   for(std::vector< std::vector< std::vector< MEDFileFieldRepresentationLeaves > > >::const_iterator it0=_data_structure.begin();it0!=_data_structure.end();it0++)
1102     for(std::vector< std::vector< MEDFileFieldRepresentationLeaves > >::const_iterator it1=(*it0).begin();it1!=(*it0).end();it1++)
1103       for(std::vector< MEDFileFieldRepresentationLeaves >::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
1104         ret=std::max(ret,(*it2).getNumberOfTS());
1105   return ret;
1106 }
1107
1108 /*!
1109  * 
1110  */
1111 void MEDFileFieldRepresentationTree::loadMainStructureOfFile(const char *fileName, bool isMEDOrSauv, int iPart, int nbOfParts)
1112 {
1113   if(isMEDOrSauv)
1114     {
1115       if((iPart==-1 && nbOfParts==-1) || (iPart==0 && nbOfParts==1))
1116         {
1117           _ms=MEDFileMeshes::New(fileName);
1118           _fields=MEDFileFields::New(fileName,false);//false is important to not read the values
1119         }
1120       else
1121         {
1122 #ifdef MEDREADER_USE_MPI
1123           _ms=ParaMEDFileMeshes::New(iPart,nbOfParts,fileName);
1124           int nbMeshes(_ms->getNumberOfMeshes());
1125           for(int i=0;i<nbMeshes;i++)
1126             {
1127               MEDCoupling::MEDFileMesh *tmp(_ms->getMeshAtPos(i));
1128               MEDCoupling::MEDFileUMesh *tmp2(dynamic_cast<MEDCoupling::MEDFileUMesh *>(tmp));
1129               if(tmp2)
1130                 MCAuto<DataArrayInt> tmp3(tmp2->zipCoords());
1131             }
1132           _fields=MEDFileFields::LoadPartOf(fileName,false,_ms);//false is important to not read the values
1133 #else
1134           std::ostringstream oss; oss << "MEDFileFieldRepresentationTree::loadMainStructureOfFile : request for iPart/nbOfParts=" << iPart << "/" << nbOfParts << " whereas Plugin not compiled with MPI !";
1135           throw INTERP_KERNEL::Exception(oss.str().c_str());
1136 #endif
1137         }
1138     }
1139   else
1140     {
1141       MCAuto<MEDCoupling::SauvReader> sr(MEDCoupling::SauvReader::New(fileName));
1142       MCAuto<MEDCoupling::MEDFileData> mfd(sr->loadInMEDFileDS());
1143       _ms=mfd->getMeshes(); _ms->incrRef();
1144       int nbMeshes(_ms->getNumberOfMeshes());
1145       for(int i=0;i<nbMeshes;i++)
1146         {
1147           MEDCoupling::MEDFileMesh *tmp(_ms->getMeshAtPos(i));
1148           MEDCoupling::MEDFileUMesh *tmp2(dynamic_cast<MEDCoupling::MEDFileUMesh *>(tmp));
1149           if(tmp2)
1150             tmp2->forceComputationOfParts();
1151         }
1152       _fields=mfd->getFields();
1153       if((MEDCoupling::MEDFileFields *)_fields)
1154         _fields->incrRef();
1155     }
1156   if(!((MEDCoupling::MEDFileFields *)_fields))
1157     {
1158       _fields=BuildFieldFromMeshes(_ms);
1159     }
1160   else
1161     {
1162       AppendFieldFromMeshes(_ms,_fields);
1163     }
1164   _ms->cartesianizeMe();
1165   _fields->removeFieldsWithoutAnyTimeStep();
1166   std::vector<std::string> meshNames(_ms->getMeshesNames());
1167   std::vector< MCAuto<MEDFileFields> > fields_per_mesh(meshNames.size());
1168   for(std::size_t i=0;i<meshNames.size();i++)
1169     {
1170       fields_per_mesh[i]=_fields->partOfThisLyingOnSpecifiedMeshName(meshNames[i].c_str());
1171     }
1172   std::vector< MCAuto<MEDFileAnyTypeFieldMultiTS > > allFMTSLeavesToDisplaySafe;
1173   std::size_t k(0);
1174   for(std::vector< MCAuto<MEDFileFields> >::const_iterator fields=fields_per_mesh.begin();fields!=fields_per_mesh.end();fields++)
1175     {
1176       for(int j=0;j<(*fields)->getNumberOfFields();j++)
1177         {
1178           MCAuto<MEDFileAnyTypeFieldMultiTS> fmts((*fields)->getFieldAtPos((int)j));
1179           std::vector< MCAuto< MEDFileAnyTypeFieldMultiTS > > tmp(fmts->splitDiscretizations());
1180           // EDF 8655
1181           for(std::vector< MCAuto< MEDFileAnyTypeFieldMultiTS > >::const_iterator it=tmp.begin();it!=tmp.end();it++)
1182             {
1183               if(!(*it)->presenceOfMultiDiscPerGeoType())
1184                 allFMTSLeavesToDisplaySafe.push_back(*it);
1185               else
1186                 {// The case of some parts of field have more than one discretization per geo type.
1187                   std::vector< MCAuto< MEDFileAnyTypeFieldMultiTS > > subTmp((*it)->splitMultiDiscrPerGeoTypes());
1188                   std::size_t it0Cnt(0);
1189                   for(std::vector< MCAuto< MEDFileAnyTypeFieldMultiTS > >::iterator it0=subTmp.begin();it0!=subTmp.end();it0++,it0Cnt++)//not const because setName
1190                     {
1191                       std::ostringstream oss; oss << (*it0)->getName() << "_" << std::setfill('M') << std::setw(3) << it0Cnt;
1192                       (*it0)->setName(oss.str());
1193                       allFMTSLeavesToDisplaySafe.push_back(*it0);
1194                     }
1195                 }
1196             }
1197          // end EDF 8655
1198         }
1199     }
1200   std::vector< MEDFileAnyTypeFieldMultiTS *> allFMTSLeavesToDisplay(allFMTSLeavesToDisplaySafe.size());
1201   for(std::size_t i=0;i<allFMTSLeavesToDisplaySafe.size();i++)
1202     {
1203       allFMTSLeavesToDisplay[i]=allFMTSLeavesToDisplaySafe[i];
1204     }
1205   std::vector< std::vector<MEDFileAnyTypeFieldMultiTS *> > allFMTSLeavesPerTimeSeries(MEDFileAnyTypeFieldMultiTS::SplitIntoCommonTimeSeries(allFMTSLeavesToDisplay));
1206   // memory safety part
1207   std::vector< std::vector< MCAuto<MEDFileAnyTypeFieldMultiTS> > > allFMTSLeavesPerTimeSeriesSafe(allFMTSLeavesPerTimeSeries.size());
1208   for(std::size_t j=0;j<allFMTSLeavesPerTimeSeries.size();j++)
1209     {
1210       allFMTSLeavesPerTimeSeriesSafe[j].resize(allFMTSLeavesPerTimeSeries[j].size());
1211       for(std::size_t k=0;k<allFMTSLeavesPerTimeSeries[j].size();k++)
1212         {
1213           allFMTSLeavesPerTimeSeries[j][k]->incrRef();//because MEDFileAnyTypeFieldMultiTS::SplitIntoCommonTimeSeries do not increments the counter
1214           allFMTSLeavesPerTimeSeriesSafe[j][k]=allFMTSLeavesPerTimeSeries[j][k];
1215         }
1216     }
1217   // end of memory safety part
1218   // 1st : timesteps, 2nd : meshName, 3rd : common support
1219   this->_data_structure.resize(allFMTSLeavesPerTimeSeriesSafe.size());
1220   for(std::size_t i=0;i<allFMTSLeavesPerTimeSeriesSafe.size();i++)
1221     {
1222       std::vector< std::string > meshNamesLoc;
1223       std::vector< std::vector< MCAuto<MEDFileAnyTypeFieldMultiTS> > > splitByMeshName;
1224       for(std::size_t j=0;j<allFMTSLeavesPerTimeSeriesSafe[i].size();j++)
1225         {
1226           std::string meshName(allFMTSLeavesPerTimeSeriesSafe[i][j]->getMeshName());
1227           std::vector< std::string >::iterator it(std::find(meshNamesLoc.begin(),meshNamesLoc.end(),meshName));
1228           if(it==meshNamesLoc.end())
1229             {
1230               meshNamesLoc.push_back(meshName);
1231               splitByMeshName.resize(splitByMeshName.size()+1);
1232               splitByMeshName.back().push_back(allFMTSLeavesPerTimeSeriesSafe[i][j]);
1233             }
1234           else
1235             splitByMeshName[std::distance(meshNamesLoc.begin(),it)].push_back(allFMTSLeavesPerTimeSeriesSafe[i][j]);
1236         }
1237       _data_structure[i].resize(meshNamesLoc.size());
1238       for(std::size_t j=0;j<splitByMeshName.size();j++)
1239         {
1240           std::vector< MCAuto<MEDFileFastCellSupportComparator> > fsp;
1241           std::vector< MEDFileAnyTypeFieldMultiTS *> sbmn(splitByMeshName[j].size());
1242           for(std::size_t k=0;k<splitByMeshName[j].size();k++)
1243             sbmn[k]=splitByMeshName[j][k];
1244           //getMeshWithName does not return a newly allocated object ! It is a true get* method !
1245           std::vector< std::vector<MEDFileAnyTypeFieldMultiTS *> > commonSupSplit(MEDFileAnyTypeFieldMultiTS::SplitPerCommonSupport(sbmn,_ms->getMeshWithName(meshNamesLoc[j].c_str()),fsp));
1246           std::vector< std::vector< MCAuto<MEDFileAnyTypeFieldMultiTS> > > commonSupSplitSafe(commonSupSplit.size());
1247           this->_data_structure[i][j].resize(commonSupSplit.size());
1248           for(std::size_t k=0;k<commonSupSplit.size();k++)
1249             {
1250               commonSupSplitSafe[k].resize(commonSupSplit[k].size());
1251               for(std::size_t l=0;l<commonSupSplit[k].size();l++)
1252                 {
1253                   commonSupSplit[k][l]->incrRef();//because MEDFileAnyTypeFieldMultiTS::SplitPerCommonSupport does not increment pointers !
1254                   commonSupSplitSafe[k][l]=commonSupSplit[k][l];
1255                 }
1256             }
1257           for(std::size_t k=0;k<commonSupSplit.size();k++)
1258             this->_data_structure[i][j][k]=MEDFileFieldRepresentationLeaves(commonSupSplitSafe[k],fsp[k]);
1259         }
1260     }
1261   this->removeEmptyLeaves();
1262   this->assignIds();
1263   this->computeFullNameInLeaves();
1264 }
1265
1266 void MEDFileFieldRepresentationTree::removeEmptyLeaves()
1267 {
1268   std::vector< std::vector< std::vector< MEDFileFieldRepresentationLeaves > > > newSD;
1269   for(std::vector< std::vector< std::vector< MEDFileFieldRepresentationLeaves > > >::const_iterator it0=_data_structure.begin();it0!=_data_structure.end();it0++)
1270     {
1271       std::vector< std::vector< MEDFileFieldRepresentationLeaves > > newSD0;
1272       for(std::vector< std::vector< MEDFileFieldRepresentationLeaves > >::const_iterator it1=(*it0).begin();it1!=(*it0).end();it1++)
1273         {
1274           std::vector< MEDFileFieldRepresentationLeaves > newSD1;
1275           for(std::vector< MEDFileFieldRepresentationLeaves >::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
1276             if(!(*it2).empty())
1277               newSD1.push_back(*it2);
1278           if(!newSD1.empty())
1279             newSD0.push_back(newSD1);
1280         }
1281       if(!newSD0.empty())
1282         newSD.push_back(newSD0);
1283     }
1284 }
1285
1286 bool MEDFileFieldRepresentationTree::IsFieldMeshRegardingInfo(const std::vector<std::string>& compInfos)
1287 {
1288   if(compInfos.size()!=1)
1289     return false;
1290   return compInfos[0]==COMPO_STR_TO_LOCATE_MESH_DA;
1291 }
1292
1293 std::string MEDFileFieldRepresentationTree::getDftMeshName() const
1294 {
1295   return _data_structure[0][0][0].getMeshName();
1296 }
1297
1298 std::vector<double> MEDFileFieldRepresentationTree::getTimeSteps(int& lev0, const TimeKeeper& tk) const
1299 {
1300   int lev1,lev2;
1301   const MEDFileFieldRepresentationLeaves& leaf(getTheSingleActivated(lev0,lev1,lev2));
1302   return leaf.getTimeSteps(tk);
1303 }
1304
1305 vtkDataSet *MEDFileFieldRepresentationTree::buildVTKInstance(bool isStdOrMode, double timeReq, std::string& meshName, const TimeKeeper& tk) const
1306 {
1307   int lev0,lev1,lev2;
1308   const MEDFileFieldRepresentationLeaves& leaf(getTheSingleActivated(lev0,lev1,lev2));
1309   meshName=leaf.getMeshName();
1310   std::vector<double> ts(leaf.getTimeSteps(tk));
1311   std::size_t zeTimeId(0);
1312   if(ts.size()!=1)
1313     {
1314       std::vector<double> ts2(ts.size());
1315       std::transform(ts.begin(),ts.end(),ts2.begin(),std::bind2nd(std::plus<double>(),-timeReq));
1316       std::transform(ts2.begin(),ts2.end(),ts2.begin(),std::ptr_fun<double,double>(fabs));
1317       zeTimeId=std::distance(ts2.begin(),std::find_if(ts2.begin(),ts2.end(),std::bind2nd(std::less<double>(),1e-14)));
1318     }
1319   //2nd chance
1320   if(zeTimeId==(int)ts.size())
1321     zeTimeId=std::distance(ts.begin(),std::find(ts.begin(),ts.end(),timeReq));
1322   if(zeTimeId==(int)ts.size())
1323     {//OK the time requested does not fit time series given to ParaView. It is typically the case if more than one MEDReader instance are created or TimeInspector in real time mode.
1324       //In this case the default behaviour is taken. Keep the highest time step in this lower than timeReq.
1325       int pos(-1);
1326       double valAttachedToPos(-std::numeric_limits<double>::max());
1327       for(std::size_t i=0;i<ts.size();i++)
1328         {
1329           if(ts[i]<timeReq)
1330             {
1331               if(ts[i]>valAttachedToPos)
1332                 {
1333                   pos=i;
1334                   valAttachedToPos=ts[i];
1335                 }
1336             }
1337         }
1338       if(pos==-1)
1339         {// timeReq is lower than all time steps (ts). So let's keep the lowest time step greater than timeReq.
1340           valAttachedToPos=std::numeric_limits<double>::max();
1341           for(std::size_t i=0;i<ts.size();i++)
1342             {
1343               if(ts[i]<valAttachedToPos)
1344                 {
1345                   pos=i;
1346                   valAttachedToPos=ts[i];
1347                 }
1348             }
1349         }
1350       zeTimeId=pos;
1351       std::ostringstream oss; oss.precision(15); oss << "request for time " << timeReq << " but not in ";
1352       std::copy(ts.begin(),ts.end(),std::ostream_iterator<double>(oss,","));
1353       oss << " ! Keep time " << valAttachedToPos << " at pos #" << zeTimeId;
1354       std::cerr << oss.str() << std::endl;
1355     }
1356   MEDTimeReq *tr(0);
1357   if(!isStdOrMode)
1358     tr=new MEDStdTimeReq((int)zeTimeId);
1359   else
1360     tr=new MEDModeTimeReq(tk.getTheVectOfBool(),tk.getPostProcessedTime());
1361   vtkDataSet *ret(leaf.buildVTKInstanceNoTimeInterpolation(tr,_fields,_ms));
1362   delete tr;
1363   return ret;
1364 }
1365
1366 const MEDFileFieldRepresentationLeaves& MEDFileFieldRepresentationTree::getTheSingleActivated(int& lev0, int& lev1, int& lev2) const
1367 {
1368   int nbOfActivated(0);
1369   for(std::vector< std::vector< std::vector< MEDFileFieldRepresentationLeaves > > >::const_iterator it0=_data_structure.begin();it0!=_data_structure.end();it0++)
1370     for(std::vector< std::vector< MEDFileFieldRepresentationLeaves > >::const_iterator it1=(*it0).begin();it1!=(*it0).end();it1++)
1371       for(std::vector< MEDFileFieldRepresentationLeaves >::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
1372         if((*it2).isActivated())
1373           nbOfActivated++;
1374   if(nbOfActivated!=1)
1375     {
1376       std::ostringstream oss; oss << "MEDFileFieldRepresentationTree::getTheSingleActivated : Only one leaf must be activated ! Having " << nbOfActivated << " !";
1377       throw INTERP_KERNEL::Exception(oss.str().c_str());
1378     }
1379   int i0(0),i1(0),i2(0);
1380   for(std::vector< std::vector< std::vector< MEDFileFieldRepresentationLeaves > > >::const_iterator it0=_data_structure.begin();it0!=_data_structure.end();it0++,i0++)
1381     for(std::vector< std::vector< MEDFileFieldRepresentationLeaves > >::const_iterator it1=(*it0).begin();it1!=(*it0).end();it1++,i1++)
1382       for(std::vector< MEDFileFieldRepresentationLeaves >::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++,i2++)
1383         if((*it2).isActivated())
1384           {
1385             lev0=i0; lev1=i1; lev2=i2;
1386             return *it2;
1387           }
1388   throw INTERP_KERNEL::Exception("MEDFileFieldRepresentationTree::getTheSingleActivated : Internal error !");
1389 }
1390
1391 void MEDFileFieldRepresentationTree::printMySelf(std::ostream& os) const
1392 {
1393   int i(0);
1394   os << "#############################################" << std::endl;
1395   for(std::vector< std::vector< std::vector< MEDFileFieldRepresentationLeaves > > >::const_iterator it0=_data_structure.begin();it0!=_data_structure.end();it0++,i++)
1396     {
1397       int j(0);
1398       os << "TS" << i << std::endl;
1399       for(std::vector< std::vector< MEDFileFieldRepresentationLeaves > >::const_iterator it1=(*it0).begin();it1!=(*it0).end();it1++,j++)
1400         {
1401           int k(0);
1402           for(std::vector< MEDFileFieldRepresentationLeaves >::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++,k++)
1403             {
1404               if(k==0)
1405                 os << "   " << (*it2).getMeshName() << std::endl;
1406               os << "      Comp" << k  << std::endl;
1407               (*it2).printMySelf(os);
1408             }
1409         }
1410     }
1411     os << "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$" << std::endl;
1412 }
1413
1414 std::map<std::string,bool> MEDFileFieldRepresentationTree::dumpState() const
1415 {
1416   std::map<std::string,bool> ret;
1417   for(std::vector< std::vector< std::vector< MEDFileFieldRepresentationLeaves > > >::const_iterator it0=_data_structure.begin();it0!=_data_structure.end();it0++)
1418     for(std::vector< std::vector< MEDFileFieldRepresentationLeaves > >::const_iterator it1=(*it0).begin();it1!=(*it0).end();it1++)
1419       for(std::vector< MEDFileFieldRepresentationLeaves >::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
1420         (*it2).dumpState(ret);
1421   return ret;
1422 }
1423
1424 void MEDFileFieldRepresentationTree::AppendFieldFromMeshes(const MEDCoupling::MEDFileMeshes *ms, MEDCoupling::MEDFileFields *ret)
1425 {
1426   if(!ret)
1427     throw INTERP_KERNEL::Exception("MEDFileFieldRepresentationTree::AppendFieldFromMeshes : internal error ! NULL ret !");
1428   for(int i=0;i<ms->getNumberOfMeshes();i++)
1429     {
1430       MEDFileMesh *mm(ms->getMeshAtPos(i));
1431       std::vector<int> levs(mm->getNonEmptyLevels());
1432       MEDCoupling::MCAuto<MEDCoupling::MEDFileField1TS> f1tsMultiLev(MEDCoupling::MEDFileField1TS::New());
1433       MEDFileUMesh *mmu(dynamic_cast<MEDFileUMesh *>(mm));
1434       if(mmu)
1435         {
1436           for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
1437             {
1438               std::vector<INTERP_KERNEL::NormalizedCellType> gts(mmu->getGeoTypesAtLevel(*it));
1439               for(std::vector<INTERP_KERNEL::NormalizedCellType>::const_iterator gt=gts.begin();gt!=gts.end();gt++)
1440                 {
1441                   MEDCoupling::MEDCouplingMesh *m(mmu->getDirectUndergroundSingleGeoTypeMesh(*gt));
1442                   MEDCoupling::MCAuto<MEDCoupling::MEDCouplingFieldDouble> f(MEDCoupling::MEDCouplingFieldDouble::New(MEDCoupling::ON_CELLS));
1443                   f->setMesh(m);
1444                   MEDCoupling::MCAuto<MEDCoupling::DataArrayDouble> arr(MEDCoupling::DataArrayDouble::New()); arr->alloc(f->getNumberOfTuplesExpected());
1445                   arr->setInfoOnComponent(0,std::string(COMPO_STR_TO_LOCATE_MESH_DA));
1446                   arr->iota();
1447                   f->setArray(arr);
1448                   f->setName(BuildAUniqueArrayNameForMesh(mm->getName(),ret));
1449                   f1tsMultiLev->setFieldNoProfileSBT(f);
1450                 }
1451             }
1452           if(levs.empty())
1453             {
1454               std::vector<int> levsExt(mm->getNonEmptyLevelsExt());
1455               if(levsExt.size()==levs.size()+1)
1456                 {
1457                   MEDCoupling::MCAuto<MEDCoupling::MEDCouplingMesh> m(mm->getMeshAtLevel(1));
1458                   MEDCoupling::MCAuto<MEDCoupling::MEDCouplingFieldDouble> f(MEDCoupling::MEDCouplingFieldDouble::New(MEDCoupling::ON_NODES));
1459                   f->setMesh(m);
1460                   MEDCoupling::MCAuto<MEDCoupling::DataArrayDouble> arr(MEDCoupling::DataArrayDouble::New()); arr->alloc(m->getNumberOfNodes());
1461                   arr->setInfoOnComponent(0,std::string(COMPO_STR_TO_LOCATE_MESH_DA));
1462                   arr->iota(); f->setArray(arr);
1463                   f->setName(BuildAUniqueArrayNameForMesh(mm->getName(),ret));
1464                   f1tsMultiLev->setFieldNoProfileSBT(f);
1465                 }
1466               else
1467                 continue;
1468             }
1469         }
1470       else
1471         {
1472           MEDCoupling::MCAuto<MEDCoupling::MEDCouplingMesh> m(mm->getMeshAtLevel(0));
1473           MEDCoupling::MCAuto<MEDCoupling::MEDCouplingFieldDouble> f(MEDCoupling::MEDCouplingFieldDouble::New(MEDCoupling::ON_CELLS));
1474           f->setMesh(m);
1475           MEDCoupling::MCAuto<MEDCoupling::DataArrayDouble> arr(MEDCoupling::DataArrayDouble::New()); arr->alloc(f->getNumberOfTuplesExpected());
1476           arr->setInfoOnComponent(0,std::string(COMPO_STR_TO_LOCATE_MESH_DA));
1477           arr->iota();
1478           f->setArray(arr);
1479           f->setName(BuildAUniqueArrayNameForMesh(mm->getName(),ret));
1480           f1tsMultiLev->setFieldNoProfileSBT(f);
1481         }
1482       //
1483       MEDCoupling::MCAuto<MEDCoupling::MEDFileFieldMultiTS> fmtsMultiLev(MEDCoupling::MEDFileFieldMultiTS::New());
1484       fmtsMultiLev->pushBackTimeStep(f1tsMultiLev);
1485       ret->pushField(fmtsMultiLev);
1486     }
1487 }
1488
1489 std::string MEDFileFieldRepresentationTree::BuildAUniqueArrayNameForMesh(const std::string& meshName, const MEDCoupling::MEDFileFields *ret)
1490 {
1491   const char KEY_STR_TO_AVOID_COLLIDE[]="MESH@";
1492   if(!ret)
1493     throw INTERP_KERNEL::Exception("MEDFileFieldRepresentationTree::BuildAUniqueArrayNameForMesh : internal error ! NULL ret !");
1494   std::vector<std::string> fieldNamesAlreadyExisting(ret->getFieldsNames());
1495   if(std::find(fieldNamesAlreadyExisting.begin(),fieldNamesAlreadyExisting.end(),meshName)==fieldNamesAlreadyExisting.end())
1496     return meshName;
1497   std::string tmpName(KEY_STR_TO_AVOID_COLLIDE); tmpName+=meshName;
1498   while(std::find(fieldNamesAlreadyExisting.begin(),fieldNamesAlreadyExisting.end(),tmpName)!=fieldNamesAlreadyExisting.end())
1499     tmpName=std::string(KEY_STR_TO_AVOID_COLLIDE)+tmpName;
1500   return tmpName;
1501 }
1502
1503 MEDCoupling::MEDFileFields *MEDFileFieldRepresentationTree::BuildFieldFromMeshes(const MEDCoupling::MEDFileMeshes *ms)
1504 {
1505   MEDCoupling::MCAuto<MEDCoupling::MEDFileFields> ret(MEDCoupling::MEDFileFields::New());
1506   AppendFieldFromMeshes(ms,ret);
1507   return ret.retn();
1508 }
1509
1510 std::vector<std::string> MEDFileFieldRepresentationTree::SplitFieldNameIntoParts(const std::string& fullFieldName, char sep)
1511 {
1512   std::vector<std::string> ret;
1513   std::size_t pos(0);
1514   while(pos!=std::string::npos)
1515     {
1516       std::size_t curPos(fullFieldName.find_first_of(sep,pos));
1517       std::string elt(fullFieldName.substr(pos,curPos!=std::string::npos?curPos-pos:std::string::npos));
1518       ret.push_back(elt);
1519       pos=fullFieldName.find_first_not_of(sep,curPos);
1520     }
1521   return ret;
1522 }
1523
1524 /*!
1525  * Here the non regression tests.
1526  * const char inp0[]="";
1527  * const char exp0[]="";
1528  * const char inp1[]="field";
1529  * const char exp1[]="field";
1530  * const char inp2[]="_________";
1531  * const char exp2[]="_________";
1532  * const char inp3[]="field_p";
1533  * const char exp3[]="field_p";
1534  * const char inp4[]="field__p";
1535  * const char exp4[]="field_p";
1536  * const char inp5[]="field_p__";
1537  * const char exp5[]="field_p";
1538  * const char inp6[]="field_p_";
1539  * const char exp6[]="field_p";
1540  * const char inp7[]="field_____EDFGEG//sdkjf_____PP_______________";
1541  * const char exp7[]="field_EDFGEG//sdkjf_PP";
1542  * const char inp8[]="field_____EDFGEG//sdkjf_____PP";
1543  * const char exp8[]="field_EDFGEG//sdkjf_PP";
1544  * const char inp9[]="_field_____EDFGEG//sdkjf_____PP_______________";
1545  * const char exp9[]="field_EDFGEG//sdkjf_PP";
1546  * const char inp10[]="___field_____EDFGEG//sdkjf_____PP_______________";
1547  * const char exp10[]="field_EDFGEG//sdkjf_PP";
1548 */
1549 std::string MEDFileFieldRepresentationTree::PostProcessFieldName(const std::string& fullFieldName)
1550 {
1551   const char SEP('_');
1552   std::vector<std::string> v(SplitFieldNameIntoParts(fullFieldName,SEP));
1553   if(v.empty())
1554     return fullFieldName;//should never happen
1555   if(v.size()==1)
1556     {
1557       if(v[0].empty())
1558         return fullFieldName;
1559       else
1560         return v[0];
1561     }
1562   std::string ret(v[0]);
1563   for(std::size_t i=1;i<v.size();i++)
1564     {
1565       if(!v[i].empty())
1566         {
1567           if(!ret.empty())
1568             { ret+=SEP; ret+=v[i]; }
1569           else
1570             ret=v[i];
1571         }
1572     }
1573   if(ret.empty())
1574     return fullFieldName;
1575   return ret;
1576 }
1577
1578 ///////////
1579
1580 TimeKeeper::TimeKeeper(int policy):_policy(policy)
1581 {
1582 }
1583
1584 std::vector<double> TimeKeeper::getTimeStepsRegardingPolicy(const std::vector< std::pair<int,int> >& tsPairs, const std::vector<double>& ts) const
1585 {
1586   switch(_policy)
1587     {
1588     case 0:
1589       return getTimeStepsRegardingPolicy0(tsPairs,ts);
1590     case 1:
1591       return getTimeStepsRegardingPolicy0(tsPairs,ts);
1592     default:
1593       throw INTERP_KERNEL::Exception("TimeKeeper::getTimeStepsRegardingPolicy : only policy 0 and 1 supported presently !");
1594     }
1595 }
1596
1597 /*!
1598  * policy = 0 :
1599  * if all of ts are in -1e299,1e299 and different each other pairs are ignored ts taken directly.
1600  * if all of ts are in -1e299,1e299 but some are not different each other ts are ignored pairs used
1601  * if some of ts are out of -1e299,1e299 ts are ignored pairs used
1602  */
1603 std::vector<double> TimeKeeper::getTimeStepsRegardingPolicy0(const std::vector< std::pair<int,int> >& tsPairs, const std::vector<double>& ts) const
1604 {
1605   std::size_t sz(ts.size());
1606   bool isInHumanRange(true);
1607   std::set<double> s;
1608   for(std::size_t i=0;i<sz;i++)
1609     {
1610       s.insert(ts[i]);
1611       if(ts[i]<=-1e299 || ts[i]>=1e299)
1612         isInHumanRange=false;
1613     }
1614   if(!isInHumanRange)
1615     return processedUsingPairOfIds(tsPairs);
1616   if(s.size()!=sz)
1617     return processedUsingPairOfIds(tsPairs);
1618   _postprocessed_time=ts;
1619   return getPostProcessedTime();
1620 }
1621
1622 /*!
1623  * policy = 1 :
1624  * idem than 0, except that ts is preaccumulated before invoking policy 0.
1625  */
1626 std::vector<double> TimeKeeper::getTimeStepsRegardingPolicy1(const std::vector< std::pair<int,int> >& tsPairs, const std::vector<double>& ts) const
1627 {
1628   std::size_t sz(ts.size());
1629   std::vector<double> ts2(sz);
1630   double acc(0.);
1631   for(std::size_t i=0;i<sz;i++)
1632     {
1633       ts2[i]=acc;
1634       acc+=ts[i];
1635     }
1636   return getTimeStepsRegardingPolicy0(tsPairs,ts2);
1637 }
1638
1639 int TimeKeeper::getTimeStepIdFrom(double timeReq) const
1640 {
1641   std::size_t pos(std::distance(_postprocessed_time.begin(),std::find(_postprocessed_time.begin(),_postprocessed_time.end(),timeReq)));
1642   return (int)pos;
1643 }
1644
1645 void TimeKeeper::printSelf(std::ostream& oss) const
1646 {
1647   std::size_t sz(_activated_ts.size());
1648   for(std::size_t i=0;i<sz;i++)
1649     {
1650       oss << "(" << i << "," << _activated_ts[i].first << "), ";
1651     }
1652 }
1653
1654 std::vector<bool> TimeKeeper::getTheVectOfBool() const
1655 {
1656   std::size_t sz(_activated_ts.size());
1657   std::vector<bool> ret(sz);
1658   for(std::size_t i=0;i<sz;i++)
1659     {
1660       ret[i]=_activated_ts[i].first;
1661     }
1662   return ret;
1663 }
1664
1665 std::vector<double> TimeKeeper::processedUsingPairOfIds(const std::vector< std::pair<int,int> >& tsPairs) const
1666 {
1667   std::size_t sz(tsPairs.size());
1668   std::set<int> s0,s1;
1669   for(std::size_t i=0;i<sz;i++)
1670     { s0.insert(tsPairs[i].first); s1.insert(tsPairs[i].second); }
1671   if(s0.size()==sz)
1672     {
1673       _postprocessed_time.resize(sz);
1674       for(std::size_t i=0;i<sz;i++)
1675         _postprocessed_time[i]=(double)tsPairs[i].first;
1676       return getPostProcessedTime();
1677     }
1678   if(s1.size()==sz)
1679     {
1680       _postprocessed_time.resize(sz);
1681       for(std::size_t i=0;i<sz;i++)
1682         _postprocessed_time[i]=(double)tsPairs[i].second;
1683       return getPostProcessedTime();
1684     }
1685   //TimeKeeper::processedUsingPairOfIds : you are not a lucky guy ! All your time steps info in MEDFile are not discriminant taken one by one !
1686   _postprocessed_time.resize(sz);
1687   for(std::size_t i=0;i<sz;i++)
1688     _postprocessed_time[i]=(double)i;
1689   return getPostProcessedTime();
1690 }
1691
1692 void TimeKeeper::setMaxNumberOfTimeSteps(int maxNumberOfTS)
1693 {
1694   _activated_ts.resize(maxNumberOfTS);
1695   for(int i=0;i<maxNumberOfTS;i++)
1696     {
1697       std::ostringstream oss; oss << "000" << i;
1698       _activated_ts[i]=std::pair<bool,std::string>(true,oss.str());
1699     }
1700 }