]> SALOME platform Git repositories - modules/paravis.git/blob - src/Plugins/MEDReader/IO/MEDFileFieldRepresentationTree.cxx
Salome HOME
[PVViewer] Add Catalyst menu
[modules/paravis.git] / src / Plugins / MEDReader / IO / MEDFileFieldRepresentationTree.cxx
1 // Copyright (C) 2010-2015  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 "vtkIdTypeArray.h"
46 #include "vtkDoubleArray.h"
47 #include "vtkIntArray.h"
48 #include "vtkCellArray.h"
49 #include "vtkPointData.h"
50 #include "vtkFieldData.h"
51 #include "vtkCellData.h"
52
53 #include "vtkMutableDirectedGraph.h"
54
55 using namespace MEDCoupling;
56
57 const char MEDFileFieldRepresentationLeavesArrays::ZE_SEP[]="@@][@@";
58
59 const char MEDFileFieldRepresentationLeavesArrays::TS_STR[]="TS";
60
61 const char MEDFileFieldRepresentationLeavesArrays::COM_SUP_STR[]="ComSup";
62
63 const char MEDFileFieldRepresentationLeavesArrays::FAMILY_ID_CELL_NAME[]="FamilyIdCell";
64
65 const char MEDFileFieldRepresentationLeavesArrays::NUM_ID_CELL_NAME[]="NumIdCell";
66
67 const char MEDFileFieldRepresentationLeavesArrays::FAMILY_ID_NODE_NAME[]="FamilyIdNode";
68
69 const char MEDFileFieldRepresentationLeavesArrays::NUM_ID_NODE_NAME[]="NumIdNode";
70
71 const char MEDFileFieldRepresentationLeavesArrays::GLOBAL_NODE_ID_NAME[]="GlobalNodeIds";// WARNING DO NOT CHANGE IT BEFORE HAVING CHECKED IN PV SOURCES !
72
73 const char MEDFileFieldRepresentationTree::ROOT_OF_GRPS_IN_TREE[]="zeGrps";
74
75 const char MEDFileFieldRepresentationTree::ROOT_OF_FAM_IDS_IN_TREE[]="zeFamIds";
76
77 const char MEDFileFieldRepresentationTree::COMPO_STR_TO_LOCATE_MESH_DA[]="-@?|*_";
78
79 vtkIdTypeArray *ELGACmp::findOrCreate(const MEDCoupling::MEDFileFieldGlobsReal *globs, const std::vector<std::string>& locsReallyUsed, vtkDoubleArray *vtkd, vtkDataSet *ds, bool& isNew) const
80 {
81   vtkIdTypeArray *try0(isExisting(locsReallyUsed,vtkd));
82   if(try0)
83     {
84       isNew=false;
85       return try0;
86     }
87   else
88     {
89       isNew=true;
90       return createNew(globs,locsReallyUsed,vtkd,ds);
91     }
92 }
93
94 vtkIdTypeArray *ELGACmp::isExisting(const std::vector<std::string>& locsReallyUsed, vtkDoubleArray *vtkd) const
95 {
96   std::vector< std::vector<std::string> >::iterator it(std::find(_loc_names.begin(),_loc_names.end(),locsReallyUsed));
97   if(it==_loc_names.end())
98     return 0;
99   std::size_t pos(std::distance(_loc_names.begin(),it));
100   vtkIdTypeArray *ret(_elgas[pos]);
101   vtkInformationQuadratureSchemeDefinitionVectorKey *key(vtkQuadratureSchemeDefinition::DICTIONARY());
102   for(std::vector<std::pair< vtkQuadratureSchemeDefinition *, unsigned char > >::const_iterator it=_defs[pos].begin();it!=_defs[pos].end();it++)
103     {
104       key->Set(vtkd->GetInformation(),(*it).first,(*it).second);
105     }
106   vtkd->GetInformation()->Set(vtkQuadratureSchemeDefinition::QUADRATURE_OFFSET_ARRAY_NAME(),ret->GetName());
107   return ret;
108 }
109
110 vtkIdTypeArray *ELGACmp::createNew(const MEDCoupling::MEDFileFieldGlobsReal *globs, const std::vector<std::string>& locsReallyUsed, vtkDoubleArray *vtkd, vtkDataSet *ds) const
111 {
112   const int VTK_DATA_ARRAY_DELETE=vtkDataArrayTemplate<double>::VTK_DATA_ARRAY_DELETE;
113   std::vector< std::vector<std::string> > locNames(_loc_names);
114   std::vector<vtkIdTypeArray *> elgas(_elgas);
115   std::vector< std::pair< vtkQuadratureSchemeDefinition *, unsigned char > > defs;
116   //
117   std::vector< std::vector<std::string> >::const_iterator it(std::find(locNames.begin(),locNames.end(),locsReallyUsed));
118   if(it!=locNames.end())
119     throw INTERP_KERNEL::Exception("ELGACmp::createNew : Method is expected to be called after isExisting call ! Entry already exists !");
120   locNames.push_back(locsReallyUsed);
121   vtkIdTypeArray *elga(vtkIdTypeArray::New());
122   elga->SetNumberOfComponents(1);
123   vtkInformationQuadratureSchemeDefinitionVectorKey *key(vtkQuadratureSchemeDefinition::DICTIONARY());
124   std::map<unsigned char,int> m;
125   for(std::vector<std::string>::const_iterator it=locsReallyUsed.begin();it!=locsReallyUsed.end();it++)
126     {
127       vtkQuadratureSchemeDefinition *def(vtkQuadratureSchemeDefinition::New());
128       const MEDFileFieldLoc& loc(globs->getLocalization((*it).c_str()));
129       INTERP_KERNEL::NormalizedCellType ct(loc.getGeoType());
130       const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(ct));
131       int nbGaussPt(loc.getNbOfGaussPtPerCell()),nbPtsPerCell((int)cm.getNumberOfNodes()),dimLoc(loc.getDimension());
132       // 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.
133       std::vector<double> gsCoods2(INTERP_KERNEL::GaussInfo::NormalizeCoordinatesIfNecessary(ct,dimLoc,loc.getGaussCoords()));
134       std::vector<double> refCoods2(INTERP_KERNEL::GaussInfo::NormalizeCoordinatesIfNecessary(ct,dimLoc,loc.getRefCoords()));
135       double *shape(new double[nbPtsPerCell*nbGaussPt]);
136       INTERP_KERNEL::GaussInfo calculator(ct,gsCoods2,nbGaussPt,refCoods2,nbPtsPerCell);
137       calculator.initLocalInfo();
138       const std::vector<double>& wgths(loc.getGaussWeights());
139       for(int i=0;i<nbGaussPt;i++)
140         {
141           const double *pt0(calculator.getFunctionValues(i));
142           if(ct!=INTERP_KERNEL::NORM_HEXA27)
143             std::copy(pt0,pt0+nbPtsPerCell,shape+nbPtsPerCell*i);
144           else
145             {
146               for(int j=0;j<27;j++)
147                 shape[nbPtsPerCell*i+j]=pt0[MEDMeshMultiLev::HEXA27_PERM_ARRAY[j]];
148             }
149         }
150       unsigned char vtkType(MEDMeshMultiLev::PARAMEDMEM_2_VTKTYPE[ct]);
151       m[vtkType]=nbGaussPt;
152       def->Initialize(vtkType,nbPtsPerCell,nbGaussPt,shape,const_cast<double *>(&wgths[0]));
153       delete [] shape;
154       key->Set(elga->GetInformation(),def,vtkType);
155       key->Set(vtkd->GetInformation(),def,vtkType);
156       defs.push_back(std::pair< vtkQuadratureSchemeDefinition *, unsigned char >(def,vtkType));
157     }
158   //
159   vtkIdType ncell(ds->GetNumberOfCells());
160   int *pt(new int[ncell]),offset(0);
161   for(vtkIdType cellId=0;cellId<ncell;cellId++)
162     {
163       vtkCell *cell(ds->GetCell(cellId));
164       int delta(m[cell->GetCellType()]);
165       pt[cellId]=offset;
166       offset+=delta;
167     }
168   elga->GetInformation()->Set(MEDUtilities::ELGA(),1);
169   elga->SetVoidArray(pt,ncell,0,VTK_DATA_ARRAY_DELETE);
170   std::ostringstream oss; oss << "ELGA" << "@" << _loc_names.size();
171   std::string ossStr(oss.str());
172   elga->SetName(ossStr.c_str());
173   elga->GetInformation()->Set(vtkAbstractArray::GUI_HIDE(),1);
174   vtkd->GetInformation()->Set(vtkQuadratureSchemeDefinition::QUADRATURE_OFFSET_ARRAY_NAME(),elga->GetName());
175   elgas.push_back(elga);
176   //
177   _loc_names=locNames;
178   _elgas=elgas;
179   _defs.push_back(defs);
180   return elga;
181 }
182
183 void ELGACmp::appendELGAIfAny(vtkDataSet *ds) const
184 {
185   for(std::vector<vtkIdTypeArray *>::const_iterator it=_elgas.begin();it!=_elgas.end();it++)
186     ds->GetCellData()->AddArray(*it);
187 }
188
189 ELGACmp::~ELGACmp()
190 {
191   for(std::vector<vtkIdTypeArray *>::const_iterator it=_elgas.begin();it!=_elgas.end();it++)
192     (*it)->Delete();
193   for(std::vector< std::vector< std::pair< vtkQuadratureSchemeDefinition *, unsigned char > > >::const_iterator it0=_defs.begin();it0!=_defs.end();it0++)
194     for(std::vector< std::pair< vtkQuadratureSchemeDefinition *, unsigned char > >::const_iterator it1=(*it0).begin();it1!=(*it0).end();it1++)
195       (*it1).first->Delete();
196 }
197
198 //=
199
200 MEDFileFieldRepresentationLeavesArrays::MEDFileFieldRepresentationLeavesArrays():_id(-1)
201 {
202 }
203
204 MEDFileFieldRepresentationLeavesArrays::MEDFileFieldRepresentationLeavesArrays(const MEDCoupling::MCAuto<MEDCoupling::MEDFileAnyTypeFieldMultiTS>& arr):MEDCoupling::MCAuto<MEDCoupling::MEDFileAnyTypeFieldMultiTS>(arr),_activated(false),_id(-1)
205 {
206   std::vector< std::vector<MEDCoupling::TypeOfField> > typs((operator->())->getTypesOfFieldAvailable());
207   if(typs.size()<1)
208     throw INTERP_KERNEL::Exception("There is a big internal problem in MEDLoader ! The field time spitting has failed ! A CRASH will occur soon !");
209   if(typs[0].size()!=1)
210     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 !");
211   MEDCoupling::MCAuto<MEDCoupling::MEDCouplingFieldDiscretization> fd(MEDCouplingFieldDiscretization::New(typs[0][0]));
212   std::ostringstream oss2; oss2 << (operator->())->getName() << ZE_SEP << fd->getRepr();
213   _ze_name=oss2.str();
214 }
215
216 MEDFileFieldRepresentationLeavesArrays& MEDFileFieldRepresentationLeavesArrays::operator=(const MEDFileFieldRepresentationLeavesArrays& other)
217 {
218   MEDCoupling::MCAuto<MEDCoupling::MEDFileAnyTypeFieldMultiTS>::operator=(other);
219   _id=-1;
220   _activated=false;
221   _ze_name=other._ze_name;
222   _ze_full_name.clear();
223   return *this;
224 }
225
226 void MEDFileFieldRepresentationLeavesArrays::setId(int& id) const
227 {
228   _id=id++;
229 }
230
231 int MEDFileFieldRepresentationLeavesArrays::getId() const
232 {
233   return _id;
234 }
235
236 std::string MEDFileFieldRepresentationLeavesArrays::getZeName() const
237 {
238   return _ze_full_name;
239 }
240
241 const char *MEDFileFieldRepresentationLeavesArrays::getZeNameC() const
242 {
243   return _ze_full_name.c_str();
244 }
245
246 void MEDFileFieldRepresentationLeavesArrays::feedSIL(vtkMutableDirectedGraph* sil, vtkIdType root, vtkVariantArray *edge, std::vector<std::string>& names) const
247 {
248   vtkIdType refId(sil->AddChild(root,edge));
249   names.push_back(_ze_name);
250   //
251   if(MEDFileFieldRepresentationTree::IsFieldMeshRegardingInfo(((operator->())->getInfo())))
252     {
253       sil->AddChild(refId,edge);
254       names.push_back(std::string());
255     }
256 }
257
258 void MEDFileFieldRepresentationLeavesArrays::computeFullNameInLeaves(const std::string& tsName, const std::string& meshName, const std::string& comSupStr) const
259 {
260   std::ostringstream oss3; oss3 << tsName << "/" << meshName << "/" << comSupStr << "/" << _ze_name;
261   _ze_full_name=oss3.str();
262 }
263
264 bool MEDFileFieldRepresentationLeavesArrays::getStatus() const
265 {
266   return _activated;
267 }
268
269 bool MEDFileFieldRepresentationLeavesArrays::setStatus(bool status) const
270 {
271   bool ret(_activated!=status);
272   _activated=status;
273   return ret;
274 }
275
276 void MEDFileFieldRepresentationLeavesArrays::appendFields(const MEDTimeReq *tr, const MEDCoupling::MEDFileFieldGlobsReal *globs, const MEDCoupling::MEDMeshMultiLev *mml, const MEDCoupling::MEDFileMeshStruct *mst, vtkDataSet *ds) const
277 {
278   const int VTK_DATA_ARRAY_FREE=vtkDataArrayTemplate<double>::VTK_DATA_ARRAY_FREE;
279   const int VTK_DATA_ARRAY_DELETE=vtkDataArrayTemplate<double>::VTK_DATA_ARRAY_DELETE;
280   tr->setNumberOfTS((operator->())->getNumberOfTS());
281   tr->initIterator();
282   for(int timeStepId=0;timeStepId<tr->size();timeStepId++,++(*tr))
283     {
284       MCAuto<MEDFileAnyTypeField1TS> f1ts((operator->())->getTimeStepAtPos(tr->getCurrent()));
285       MEDFileAnyTypeField1TS *f1tsPtr(f1ts);
286       MEDFileField1TS *f1tsPtrDbl(dynamic_cast<MEDFileField1TS *>(f1tsPtr));
287       MEDFileIntField1TS *f1tsPtrInt(dynamic_cast<MEDFileIntField1TS *>(f1tsPtr));
288       DataArray *crudeArr(0),*postProcessedArr(0);
289       if(f1tsPtrDbl)
290         crudeArr=f1tsPtrDbl->getUndergroundDataArray();
291       else if(f1tsPtrInt)
292         crudeArr=f1tsPtrInt->getUndergroundDataArray();
293       else
294         throw INTERP_KERNEL::Exception("MEDFileFieldRepresentationLeavesArrays::appendFields : only FLOAT64 and INT32 fields are dealt for the moment !");
295       MEDFileField1TSStructItem fsst(MEDFileField1TSStructItem::BuildItemFrom(f1ts,mst));
296       f1ts->loadArraysIfNecessary();
297       MCAuto<DataArray> v(mml->buildDataArray(fsst,globs,crudeArr));
298       postProcessedArr=v;
299       //
300       std::vector<TypeOfField> discs(f1ts->getTypesOfFieldAvailable());
301       if(discs.size()!=1)
302         throw INTERP_KERNEL::Exception("MEDFileFieldRepresentationLeavesArrays::appendFields : internal error ! Number of spatial discretizations must be equal to one !");
303       vtkFieldData *att(0);
304       switch(discs[0])
305         {
306         case ON_CELLS:
307           {
308             att=ds->GetCellData();
309             break;
310           }
311         case ON_NODES:
312           {
313             att=ds->GetPointData();
314             break;
315           }
316         case ON_GAUSS_NE:
317           {
318             att=ds->GetFieldData();
319             break;
320           }
321         case ON_GAUSS_PT:
322           {
323             att=ds->GetFieldData();
324             break;
325           }
326         default:
327           throw INTERP_KERNEL::Exception("MEDFileFieldRepresentationLeavesArrays::appendFields : only CELL and NODE, GAUSS_NE and GAUSS fields are available for the moment !");
328         }
329       if(f1tsPtrDbl)
330         {
331           DataArray *vPtr(v); DataArrayDouble *vd(static_cast<DataArrayDouble *>(vPtr));
332           vtkDoubleArray *vtkd(vtkDoubleArray::New());
333           vtkd->SetNumberOfComponents(vd->getNumberOfComponents());
334           for(int i=0;i<vd->getNumberOfComponents();i++)
335             vtkd->SetComponentName(i,vd->getInfoOnComponent(i).c_str());
336           if(postProcessedArr!=crudeArr)
337             {
338               vtkd->SetArray(vd->getPointer(),vd->getNbOfElems(),0,VTK_DATA_ARRAY_FREE); vd->accessToMemArray().setSpecificDeallocator(0);
339             }
340           else
341             {
342               vtkd->SetArray(vd->getPointer(),vd->getNbOfElems(),1,VTK_DATA_ARRAY_FREE);
343             }
344           std::string name(tr->buildName(f1ts->getName()));
345           vtkd->SetName(name.c_str());
346           att->AddArray(vtkd);
347           vtkd->Delete();
348           if(discs[0]==ON_GAUSS_PT)
349             {
350               bool tmp;
351               _elga_cmp.findOrCreate(globs,f1ts->getLocsReallyUsed(),vtkd,ds,tmp);
352             }
353           if(discs[0]==ON_GAUSS_NE)
354             {
355               vtkIdTypeArray *elno(vtkIdTypeArray::New());
356               elno->SetNumberOfComponents(1);
357               vtkIdType ncell(ds->GetNumberOfCells());
358               int *pt(new int[ncell]),offset(0);
359               std::set<int> cellTypes;
360               for(vtkIdType cellId=0;cellId<ncell;cellId++)
361                 {
362                   vtkCell *cell(ds->GetCell(cellId));
363                   int delta(cell->GetNumberOfPoints());
364                   cellTypes.insert(cell->GetCellType());
365                   pt[cellId]=offset;
366                   offset+=delta;
367                 }
368               elno->GetInformation()->Set(MEDUtilities::ELNO(),1);
369               elno->SetVoidArray(pt,ncell,0,VTK_DATA_ARRAY_DELETE);
370               std::string nameElno("ELNO"); nameElno+="@"; nameElno+=name;
371               elno->SetName(nameElno.c_str());
372               ds->GetCellData()->AddArray(elno);
373               vtkd->GetInformation()->Set(vtkQuadratureSchemeDefinition::QUADRATURE_OFFSET_ARRAY_NAME(),elno->GetName());
374               elno->GetInformation()->Set(vtkAbstractArray::GUI_HIDE(),1);
375               //
376               vtkInformationQuadratureSchemeDefinitionVectorKey *key(vtkQuadratureSchemeDefinition::DICTIONARY());
377               for(std::set<int>::const_iterator it=cellTypes.begin();it!=cellTypes.end();it++)
378                 {
379                   const unsigned char *pos(std::find(MEDMeshMultiLev::PARAMEDMEM_2_VTKTYPE,MEDMeshMultiLev::PARAMEDMEM_2_VTKTYPE+MEDMeshMultiLev::PARAMEDMEM_2_VTKTYPE_LGTH,*it));
380                   if(pos==MEDMeshMultiLev::PARAMEDMEM_2_VTKTYPE+MEDMeshMultiLev::PARAMEDMEM_2_VTKTYPE_LGTH)
381                     continue;
382                   INTERP_KERNEL::NormalizedCellType ct((INTERP_KERNEL::NormalizedCellType)std::distance(MEDMeshMultiLev::PARAMEDMEM_2_VTKTYPE,pos));
383                   const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(ct));
384                   int nbGaussPt(cm.getNumberOfNodes()),dim(cm.getDimension());
385                   vtkQuadratureSchemeDefinition *def(vtkQuadratureSchemeDefinition::New());
386                   double *shape(new double[nbGaussPt*nbGaussPt]);
387                   std::size_t dummy;
388                   const double *gsCoords(MEDCouplingFieldDiscretizationGaussNE::GetLocsFromGeometricType(ct,dummy));
389                   const double *refCoords(MEDCouplingFieldDiscretizationGaussNE::GetRefCoordsFromGeometricType(ct,dummy));
390                   const double *weights(MEDCouplingFieldDiscretizationGaussNE::GetWeightArrayFromGeometricType(ct,dummy));
391                   std::vector<double> gsCoords2(gsCoords,gsCoords+nbGaussPt*dim),refCoords2(refCoords,refCoords+nbGaussPt*dim);
392                   INTERP_KERNEL::GaussInfo calculator(ct,gsCoords2,nbGaussPt,refCoords2,nbGaussPt);
393                   calculator.initLocalInfo();
394                   for(int i=0;i<nbGaussPt;i++)
395                     {
396                       const double *pt0(calculator.getFunctionValues(i));
397                       std::copy(pt0,pt0+nbGaussPt,shape+nbGaussPt*i);
398                     }
399                   def->Initialize(*it,nbGaussPt,nbGaussPt,shape,const_cast<double *>(weights));
400                   delete [] shape;
401                   key->Set(elno->GetInformation(),def,*it);
402                   key->Set(vtkd->GetInformation(),def,*it);
403                   def->Delete();
404                 }
405               //
406               elno->Delete();
407             }
408         }
409       else if(f1tsPtrInt)
410         {
411           DataArray *vPtr(v); DataArrayInt *vi(static_cast<DataArrayInt *>(vPtr));
412           vtkIntArray *vtkd(vtkIntArray::New());
413           vtkd->SetNumberOfComponents(vi->getNumberOfComponents());
414           for(int i=0;i<vi->getNumberOfComponents();i++)
415             vtkd->SetComponentName(i,vi->getVarOnComponent(i).c_str());
416           if(postProcessedArr!=crudeArr)
417             {
418               vtkd->SetArray(vi->getPointer(),vi->getNbOfElems(),0,VTK_DATA_ARRAY_FREE); vi->accessToMemArray().setSpecificDeallocator(0);
419             }
420           else
421             {
422               vtkd->SetArray(vi->getPointer(),vi->getNbOfElems(),1,VTK_DATA_ARRAY_FREE);
423             }
424           std::string name(tr->buildName(f1ts->getName()));
425           vtkd->SetName(name.c_str());
426           att->AddArray(vtkd);
427           vtkd->Delete();
428         }
429       else
430         throw INTERP_KERNEL::Exception("MEDFileFieldRepresentationLeavesArrays::appendFields : only FLOAT64 and INT32 fields are dealt for the moment ! Internal Error !");
431     }
432 }
433
434 void MEDFileFieldRepresentationLeavesArrays::appendELGAIfAny(vtkDataSet *ds) const
435 {
436   _elga_cmp.appendELGAIfAny(ds);
437 }
438
439 ////////////////////
440
441 MEDFileFieldRepresentationLeaves::MEDFileFieldRepresentationLeaves():_cached_ds(0)
442 {
443 }
444
445 MEDFileFieldRepresentationLeaves::MEDFileFieldRepresentationLeaves(const std::vector< MEDCoupling::MCAuto<MEDCoupling::MEDFileAnyTypeFieldMultiTS> >& arr,
446                                                                    const MEDCoupling::MCAuto<MEDCoupling::MEDFileFastCellSupportComparator>& fsp):_arrays(arr.size()),_fsp(fsp),_cached_ds(0)
447 {
448   for(std::size_t i=0;i<arr.size();i++)
449     _arrays[i]=MEDFileFieldRepresentationLeavesArrays(arr[i]);
450 }
451
452 MEDFileFieldRepresentationLeaves::~MEDFileFieldRepresentationLeaves()
453 {
454   if(_cached_ds)
455     _cached_ds->Delete();
456 }
457
458 bool MEDFileFieldRepresentationLeaves::empty() const
459 {
460   const MEDFileFastCellSupportComparator *fcscp(_fsp);
461   return fcscp==0 || _arrays.empty();
462 }
463
464 void MEDFileFieldRepresentationLeaves::setId(int& id) const
465 {
466   for(std::vector<MEDFileFieldRepresentationLeavesArrays>::const_iterator it=_arrays.begin();it!=_arrays.end();it++)
467     (*it).setId(id);
468 }
469
470 std::string MEDFileFieldRepresentationLeaves::getMeshName() const
471 {
472   return _arrays[0]->getMeshName();
473 }
474
475 int MEDFileFieldRepresentationLeaves::getNumberOfArrays() const
476 {
477   return (int)_arrays.size();
478 }
479
480 int MEDFileFieldRepresentationLeaves::getNumberOfTS() const
481 {
482   return _arrays[0]->getNumberOfTS();
483 }
484
485 void MEDFileFieldRepresentationLeaves::computeFullNameInLeaves(const std::string& tsName, const std::string& meshName, const std::string& comSupStr) const
486 {
487   for(std::vector<MEDFileFieldRepresentationLeavesArrays>::const_iterator it=_arrays.begin();it!=_arrays.end();it++)
488     (*it).computeFullNameInLeaves(tsName,meshName,comSupStr);
489 }
490
491 /*!
492  * \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.
493  */
494 void MEDFileFieldRepresentationLeaves::feedSIL(const MEDCoupling::MEDFileMeshes *ms, const std::string& meshName, vtkMutableDirectedGraph* sil, vtkIdType root, vtkVariantArray *edge, std::vector<std::string>& names) const
495 {
496   vtkIdType root2(sil->AddChild(root,edge));
497   names.push_back(std::string("Arrs"));
498   for(std::vector<MEDFileFieldRepresentationLeavesArrays>::const_iterator it=_arrays.begin();it!=_arrays.end();it++)
499     (*it).feedSIL(sil,root2,edge,names);
500   //
501   vtkIdType root3(sil->AddChild(root,edge));
502   names.push_back(std::string("InfoOnGeoType"));
503   const MEDCoupling::MEDFileMesh *m(0);
504   if(ms)
505     m=ms->getMeshWithName(meshName);
506   const MEDCoupling::MEDFileFastCellSupportComparator *fsp(_fsp);
507   if(!fsp || fsp->getNumberOfTS()==0)
508     return ;
509   std::vector< INTERP_KERNEL::NormalizedCellType > gts(fsp->getGeoTypesAt(0,m));
510   for(std::vector< INTERP_KERNEL::NormalizedCellType >::const_iterator it2=gts.begin();it2!=gts.end();it2++)
511     {
512       const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(*it2));
513       std::string cmStr(cm.getRepr()); cmStr=cmStr.substr(5);//skip "NORM_"
514       sil->AddChild(root3,edge);
515       names.push_back(cmStr);
516     }
517 }
518
519 bool MEDFileFieldRepresentationLeaves::containId(int id) const
520 {
521   for(std::vector<MEDFileFieldRepresentationLeavesArrays>::const_iterator it=_arrays.begin();it!=_arrays.end();it++)
522     if((*it).getId()==id)
523       return true;
524   return false;
525 }
526
527 bool MEDFileFieldRepresentationLeaves::containZeName(const char *name, int& id) const
528 {
529   for(std::vector<MEDFileFieldRepresentationLeavesArrays>::const_iterator it=_arrays.begin();it!=_arrays.end();it++)
530     if((*it).getZeName()==name)
531       {
532         id=(*it).getId();
533         return true;
534       }
535   return false;
536 }
537
538 void MEDFileFieldRepresentationLeaves::dumpState(std::map<std::string,bool>& status) const
539 {
540   for(std::vector<MEDFileFieldRepresentationLeavesArrays>::const_iterator it=_arrays.begin();it!=_arrays.end();it++)
541     status[(*it).getZeName()]=(*it).getStatus();
542 }
543
544 bool MEDFileFieldRepresentationLeaves::isActivated() const
545 {
546   for(std::vector<MEDFileFieldRepresentationLeavesArrays>::const_iterator it=_arrays.begin();it!=_arrays.end();it++)
547     if((*it).getStatus())
548       return true;
549   return false;
550 }
551
552 void MEDFileFieldRepresentationLeaves::printMySelf(std::ostream& os) const
553 {
554   for(std::vector<MEDFileFieldRepresentationLeavesArrays>::const_iterator it0=_arrays.begin();it0!=_arrays.end();it0++)
555     {
556       os << "         - " << (*it0).getZeName() << " (";
557       if((*it0).getStatus())
558         os << "X";
559       else
560         os << " ";
561       os << ")" << std::endl;
562     }
563 }
564
565 void MEDFileFieldRepresentationLeaves::activateAllArrays() const
566 {
567   for(std::vector<MEDFileFieldRepresentationLeavesArrays>::const_iterator it=_arrays.begin();it!=_arrays.end();it++)
568     (*it).setStatus(true);
569 }
570
571 const MEDFileFieldRepresentationLeavesArrays& MEDFileFieldRepresentationLeaves::getLeafArr(int id) const
572 {
573   for(std::vector<MEDFileFieldRepresentationLeavesArrays>::const_iterator it=_arrays.begin();it!=_arrays.end();it++)
574     if((*it).getId()==id)
575       return *it;
576   throw INTERP_KERNEL::Exception("MEDFileFieldRepresentationLeaves::getLeafArr ! No such id !");
577 }
578
579 std::vector<double> MEDFileFieldRepresentationLeaves::getTimeSteps(const TimeKeeper& tk) const
580 {
581   if(_arrays.size()<1)
582     throw INTERP_KERNEL::Exception("MEDFileFieldRepresentationLeaves::getTimeSteps : the array size must be at least of size one !");
583   std::vector<double> ret;
584   std::vector< std::pair<int,int> > dtits(_arrays[0]->getTimeSteps(ret));
585   return tk.getTimeStepsRegardingPolicy(dtits,ret);
586 }
587
588 std::vector< std::pair<int,int> > MEDFileFieldRepresentationLeaves::getTimeStepsInCoarseMEDFileFormat(std::vector<double>& ts) const
589 {
590   if(!_arrays.empty())
591     return _arrays[0]->getTimeSteps(ts);
592   else
593     {
594       ts.clear();
595       return std::vector< std::pair<int,int> >();
596     }
597 }
598
599 std::string MEDFileFieldRepresentationLeaves::getHumanReadableOverviewOfTS() const
600 {
601   std::ostringstream oss;
602   oss << _arrays[0]->getNumberOfTS() << " time steps [" << _arrays[0]->getDtUnit() << "]\n(";
603   std::vector<double> ret1;
604   std::vector< std::pair<int,int> > ret2(getTimeStepsInCoarseMEDFileFormat(ret1));
605   std::size_t sz(ret1.size());
606   for(std::size_t i=0;i<sz;i++)
607     {
608       oss << ret1[i] << " (" << ret2[i].first << "," << ret2[i].second << ")";
609       if(i!=sz-1)
610         oss << ", ";
611       std::string tmp(oss.str());
612       if(tmp.size()>200 && i!=sz-1)
613         {
614           oss << "...";
615           break;
616         }
617     }
618   oss << ")";
619   return oss.str();
620 }
621
622 void MEDFileFieldRepresentationLeaves::appendFields(const MEDTimeReq *tr, const MEDCoupling::MEDFileFieldGlobsReal *globs, const MEDCoupling::MEDMeshMultiLev *mml, const MEDCoupling::MEDFileMeshes *meshes, vtkDataSet *ds) const
623 {
624   if(_arrays.size()<1)
625     throw INTERP_KERNEL::Exception("MEDFileFieldRepresentationLeaves::appendFields : internal error !");
626   MCAuto<MEDFileMeshStruct> mst(MEDFileMeshStruct::New(meshes->getMeshWithName(_arrays[0]->getMeshName().c_str())));
627   for(std::vector<MEDFileFieldRepresentationLeavesArrays>::const_iterator it=_arrays.begin();it!=_arrays.end();it++)
628     if((*it).getStatus())
629       {
630         (*it).appendFields(tr,globs,mml,mst,ds);
631         (*it).appendELGAIfAny(ds);
632       }
633 }
634
635 vtkUnstructuredGrid *MEDFileFieldRepresentationLeaves::buildVTKInstanceNoTimeInterpolationUnstructured(MEDUMeshMultiLev *mm) const
636 {
637   const int VTK_DATA_ARRAY_FREE=vtkDataArrayTemplate<double>::VTK_DATA_ARRAY_FREE;
638   DataArrayDouble *coordsMC(0);
639   DataArrayByte *typesMC(0);
640   DataArrayInt *cellLocationsMC(0),*cellsMC(0),*faceLocationsMC(0),*facesMC(0);
641   bool statusOfCoords(mm->buildVTUArrays(coordsMC,typesMC,cellLocationsMC,cellsMC,faceLocationsMC,facesMC));
642   MCAuto<DataArrayDouble> coordsSafe(coordsMC);
643   MCAuto<DataArrayByte> typesSafe(typesMC);
644   MCAuto<DataArrayInt> cellLocationsSafe(cellLocationsMC),cellsSafe(cellsMC),faceLocationsSafe(faceLocationsMC),facesSafe(facesMC);
645   //
646   int nbOfCells(typesSafe->getNbOfElems());
647   vtkUnstructuredGrid *ret(vtkUnstructuredGrid::New());
648   vtkUnsignedCharArray *cellTypes(vtkUnsignedCharArray::New());
649   cellTypes->SetArray(reinterpret_cast<unsigned char *>(typesSafe->getPointer()),nbOfCells,0,VTK_DATA_ARRAY_FREE); typesSafe->accessToMemArray().setSpecificDeallocator(0);
650   vtkIdTypeArray *cellLocations(vtkIdTypeArray::New());
651   cellLocations->SetVoidArray(cellLocationsSafe->getPointer(),nbOfCells,0,VTK_DATA_ARRAY_FREE); cellLocationsSafe->accessToMemArray().setSpecificDeallocator(0);
652   vtkCellArray *cells(vtkCellArray::New());
653   vtkIdTypeArray *cells2(vtkIdTypeArray::New());
654   cells2->SetVoidArray(cellsSafe->getPointer(),cellsSafe->getNbOfElems(),0,VTK_DATA_ARRAY_FREE); cellsSafe->accessToMemArray().setSpecificDeallocator(0);
655   cells->SetCells(nbOfCells,cells2);
656   cells2->Delete();
657   if(faceLocationsMC!=0 && facesMC!=0)
658     {
659       vtkIdTypeArray *faces(vtkIdTypeArray::New());
660       faces->SetVoidArray(facesSafe->getPointer(),facesSafe->getNbOfElems(),0,VTK_DATA_ARRAY_FREE); facesSafe->accessToMemArray().setSpecificDeallocator(0);
661       vtkIdTypeArray *faceLocations(vtkIdTypeArray::New());
662       faceLocations->SetVoidArray(faceLocationsSafe->getPointer(),faceLocationsSafe->getNbOfElems(),0,VTK_DATA_ARRAY_FREE); faceLocationsSafe->accessToMemArray().setSpecificDeallocator(0);
663       ret->SetCells(cellTypes,cellLocations,cells,faceLocations,faces);
664       faceLocations->Delete();
665       faces->Delete();
666     }
667   else
668     ret->SetCells(cellTypes,cellLocations,cells);
669   cellTypes->Delete();
670   cellLocations->Delete();
671   cells->Delete();
672   vtkPoints *pts(vtkPoints::New());
673   vtkDoubleArray *pts2(vtkDoubleArray::New());
674   pts2->SetNumberOfComponents(3);
675   if(!statusOfCoords)
676     {
677       pts2->SetArray(coordsSafe->getPointer(),coordsSafe->getNbOfElems(),0,VTK_DATA_ARRAY_FREE);
678       coordsSafe->accessToMemArray().setSpecificDeallocator(0);
679     }
680   else
681     pts2->SetArray(coordsSafe->getPointer(),coordsSafe->getNbOfElems(),1,VTK_DATA_ARRAY_FREE);
682   pts->SetData(pts2);
683   pts2->Delete();
684   ret->SetPoints(pts);
685   pts->Delete();
686   //
687   return ret;
688 }
689
690 vtkRectilinearGrid *MEDFileFieldRepresentationLeaves::buildVTKInstanceNoTimeInterpolationCartesian(MEDCoupling::MEDCMeshMultiLev *mm) const
691 {
692   const int VTK_DATA_ARRAY_FREE=vtkDataArrayTemplate<double>::VTK_DATA_ARRAY_FREE;
693   bool isInternal;
694   std::vector< DataArrayDouble * > arrs(mm->buildVTUArrays(isInternal));
695   vtkDoubleArray *vtkTmp(0);
696   vtkRectilinearGrid *ret(vtkRectilinearGrid::New());
697   std::size_t dim(arrs.size());
698   if(dim<1 || dim>3)
699     throw INTERP_KERNEL::Exception("buildVTKInstanceNoTimeInterpolationCartesian : dimension must be in [1,3] !");
700   int sizePerAxe[3]={1,1,1};
701   sizePerAxe[0]=arrs[0]->getNbOfElems();
702   if(dim>=2)
703     sizePerAxe[1]=arrs[1]->getNbOfElems();
704   if(dim==3)
705     sizePerAxe[2]=arrs[2]->getNbOfElems();
706   ret->SetDimensions(sizePerAxe[0],sizePerAxe[1],sizePerAxe[2]);
707   vtkTmp=vtkDoubleArray::New();
708   vtkTmp->SetNumberOfComponents(1);
709   if(isInternal)
710     vtkTmp->SetArray(arrs[0]->getPointer(),arrs[0]->getNbOfElems(),1,VTK_DATA_ARRAY_FREE);
711   else
712     { vtkTmp->SetArray(arrs[0]->getPointer(),arrs[0]->getNbOfElems(),0,VTK_DATA_ARRAY_FREE); arrs[0]->accessToMemArray().setSpecificDeallocator(0); }
713   ret->SetXCoordinates(vtkTmp);
714   vtkTmp->Delete();
715   arrs[0]->decrRef();
716   if(dim>=2)
717     {
718       vtkTmp=vtkDoubleArray::New();
719       vtkTmp->SetNumberOfComponents(1);
720       if(isInternal)
721         vtkTmp->SetArray(arrs[1]->getPointer(),arrs[1]->getNbOfElems(),1,VTK_DATA_ARRAY_FREE);
722       else
723         { vtkTmp->SetArray(arrs[1]->getPointer(),arrs[1]->getNbOfElems(),0,VTK_DATA_ARRAY_FREE); arrs[1]->accessToMemArray().setSpecificDeallocator(0); }
724       ret->SetYCoordinates(vtkTmp);
725       vtkTmp->Delete();
726       arrs[1]->decrRef();
727     }
728   if(dim==3)
729     {
730       vtkTmp=vtkDoubleArray::New();
731       vtkTmp->SetNumberOfComponents(1);
732       if(isInternal)
733         vtkTmp->SetArray(arrs[2]->getPointer(),arrs[2]->getNbOfElems(),1,VTK_DATA_ARRAY_FREE);
734       else
735         { vtkTmp->SetArray(arrs[2]->getPointer(),arrs[2]->getNbOfElems(),0,VTK_DATA_ARRAY_FREE); arrs[2]->accessToMemArray().setSpecificDeallocator(0); }
736       ret->SetZCoordinates(vtkTmp);
737       vtkTmp->Delete();
738       arrs[2]->decrRef();
739     }
740   return ret;
741 }
742
743 vtkStructuredGrid *MEDFileFieldRepresentationLeaves::buildVTKInstanceNoTimeInterpolationCurveLinear(MEDCoupling::MEDCurveLinearMeshMultiLev *mm) const
744 {
745   const int VTK_DATA_ARRAY_FREE=vtkDataArrayTemplate<double>::VTK_DATA_ARRAY_FREE;
746   int meshStr[3]={1,1,1};
747   DataArrayDouble *coords(0);
748   std::vector<int> nodeStrct;
749   bool isInternal;
750   mm->buildVTUArrays(coords,nodeStrct,isInternal);
751   std::size_t dim(nodeStrct.size());
752   if(dim<1 || dim>3)
753     throw INTERP_KERNEL::Exception("buildVTKInstanceNoTimeInterpolationCurveLinear : dimension must be in [1,3] !");
754   meshStr[0]=nodeStrct[0];
755   if(dim>=2)
756     meshStr[1]=nodeStrct[1];
757   if(dim==3)
758     meshStr[2]=nodeStrct[2];
759   vtkStructuredGrid *ret(vtkStructuredGrid::New());
760   ret->SetDimensions(meshStr[0],meshStr[1],meshStr[2]);
761   vtkDoubleArray *da(vtkDoubleArray::New());
762   da->SetNumberOfComponents(3);
763   if(coords->getNumberOfComponents()==3)
764     {
765       if(isInternal)
766         da->SetArray(coords->getPointer(),coords->getNbOfElems(),1,VTK_DATA_ARRAY_FREE);//VTK has not the ownership of double * because MEDLoader main struct has it !
767       else
768         { da->SetArray(coords->getPointer(),coords->getNbOfElems(),0,VTK_DATA_ARRAY_FREE); coords->accessToMemArray().setSpecificDeallocator(0); }
769     }
770   else
771     {
772       MCAuto<DataArrayDouble> coords2(coords->changeNbOfComponents(3,0.));
773       da->SetArray(coords2->getPointer(),coords2->getNbOfElems(),0,VTK_DATA_ARRAY_FREE);//let VTK deal with double *
774       coords2->accessToMemArray().setSpecificDeallocator(0);
775     }
776   coords->decrRef();
777   vtkPoints *points=vtkPoints::New();
778   ret->SetPoints(points);
779   points->SetData(da);
780   points->Delete();
781   da->Delete();
782   return ret;
783 }
784  
785 vtkDataSet *MEDFileFieldRepresentationLeaves::buildVTKInstanceNoTimeInterpolation(const MEDTimeReq *tr, const MEDFileFieldGlobsReal *globs, const MEDCoupling::MEDFileMeshes *meshes) const
786 {
787   const int VTK_DATA_ARRAY_FREE=vtkDataArrayTemplate<double>::VTK_DATA_ARRAY_FREE;
788   vtkDataSet *ret(0);
789   //_fsp->isDataSetSupportEqualToThePreviousOne(i,globs);
790   MCAuto<MEDMeshMultiLev> mml(_fsp->buildFromScratchDataSetSupport(0,globs));//0=timestep Id. Make the hypothesis that support does not change 
791   MCAuto<MEDMeshMultiLev> mml2(mml->prepare());
792   MEDMeshMultiLev *ptMML2(mml2);
793   if(!_cached_ds)
794     {
795       MEDUMeshMultiLev *ptUMML2(dynamic_cast<MEDUMeshMultiLev *>(ptMML2));
796       MEDCMeshMultiLev *ptCMML2(dynamic_cast<MEDCMeshMultiLev *>(ptMML2));
797       MEDCurveLinearMeshMultiLev *ptCLMML2(dynamic_cast<MEDCurveLinearMeshMultiLev *>(ptMML2));
798       
799       if(ptUMML2)
800         {
801           ret=buildVTKInstanceNoTimeInterpolationUnstructured(ptUMML2);
802         }
803       else if(ptCMML2)
804         {
805           ret=buildVTKInstanceNoTimeInterpolationCartesian(ptCMML2);
806         }
807       else if(ptCLMML2)
808         {
809           ret=buildVTKInstanceNoTimeInterpolationCurveLinear(ptCLMML2);
810         }
811       else
812         throw INTERP_KERNEL::Exception("MEDFileFieldRepresentationLeaves::buildVTKInstanceNoTimeInterpolation : unrecognized mesh ! Supported for the moment unstructured, cartesian, curvelinear !");
813       _cached_ds=ret->NewInstance();
814       _cached_ds->ShallowCopy(ret);
815     }
816   else
817     {
818       ret=_cached_ds->NewInstance();
819       ret->ShallowCopy(_cached_ds);
820     }
821   //
822   appendFields(tr,globs,mml,meshes,ret);
823   // The arrays links to mesh
824   DataArrayInt *famCells(0),*numCells(0);
825   bool noCpyFamCells(false),noCpyNumCells(false);
826   ptMML2->retrieveFamilyIdsOnCells(famCells,noCpyFamCells);
827   if(famCells)
828     {
829       vtkIntArray *vtkTab(vtkIntArray::New());
830       vtkTab->SetNumberOfComponents(1);
831       vtkTab->SetName(MEDFileFieldRepresentationLeavesArrays::FAMILY_ID_CELL_NAME);
832       if(noCpyFamCells)
833         vtkTab->SetArray(famCells->getPointer(),famCells->getNbOfElems(),1,VTK_DATA_ARRAY_FREE);
834       else
835         { vtkTab->SetArray(famCells->getPointer(),famCells->getNbOfElems(),0,VTK_DATA_ARRAY_FREE); famCells->accessToMemArray().setSpecificDeallocator(0); }
836       ret->GetCellData()->AddArray(vtkTab);
837       vtkTab->Delete();
838       famCells->decrRef();
839     }
840   ptMML2->retrieveNumberIdsOnCells(numCells,noCpyNumCells);
841   if(numCells)
842     {
843       vtkIntArray *vtkTab(vtkIntArray::New());
844       vtkTab->SetNumberOfComponents(1);
845       vtkTab->SetName(MEDFileFieldRepresentationLeavesArrays::NUM_ID_CELL_NAME);
846       if(noCpyNumCells)
847         vtkTab->SetArray(numCells->getPointer(),numCells->getNbOfElems(),1,VTK_DATA_ARRAY_FREE);
848       else
849         { vtkTab->SetArray(numCells->getPointer(),numCells->getNbOfElems(),0,VTK_DATA_ARRAY_FREE); numCells->accessToMemArray().setSpecificDeallocator(0); }
850       ret->GetCellData()->AddArray(vtkTab);
851       vtkTab->Delete();
852       numCells->decrRef();
853     }
854   // The arrays links to mesh
855   DataArrayInt *famNodes(0),*numNodes(0);
856   bool noCpyFamNodes(false),noCpyNumNodes(false);
857   ptMML2->retrieveFamilyIdsOnNodes(famNodes,noCpyFamNodes);
858   if(famNodes)
859     {
860       vtkIntArray *vtkTab(vtkIntArray::New());
861       vtkTab->SetNumberOfComponents(1);
862       vtkTab->SetName(MEDFileFieldRepresentationLeavesArrays::FAMILY_ID_NODE_NAME);
863       if(noCpyFamNodes)
864         vtkTab->SetArray(famNodes->getPointer(),famNodes->getNbOfElems(),1,VTK_DATA_ARRAY_FREE);
865       else
866         { vtkTab->SetArray(famNodes->getPointer(),famNodes->getNbOfElems(),0,VTK_DATA_ARRAY_FREE); famNodes->accessToMemArray().setSpecificDeallocator(0); }
867       ret->GetPointData()->AddArray(vtkTab);
868       vtkTab->Delete();
869       famNodes->decrRef();
870     }
871   ptMML2->retrieveNumberIdsOnNodes(numNodes,noCpyNumNodes);
872   if(numNodes)
873     {
874       vtkIntArray *vtkTab(vtkIntArray::New());
875       vtkTab->SetNumberOfComponents(1);
876       vtkTab->SetName(MEDFileFieldRepresentationLeavesArrays::NUM_ID_NODE_NAME);
877       if(noCpyNumNodes)
878         vtkTab->SetArray(numNodes->getPointer(),numNodes->getNbOfElems(),1,VTK_DATA_ARRAY_FREE);
879       else
880         { vtkTab->SetArray(numNodes->getPointer(),numNodes->getNbOfElems(),0,VTK_DATA_ARRAY_FREE); numNodes->accessToMemArray().setSpecificDeallocator(0); }
881       ret->GetPointData()->AddArray(vtkTab);
882       vtkTab->Delete();
883       numNodes->decrRef();
884     }
885   // Global Node Ids if any ! (In // mode)
886   DataArrayInt *gni(ptMML2->retrieveGlobalNodeIdsIfAny());
887   if(gni)
888     {
889       vtkIntArray *vtkTab(vtkIntArray::New());
890       vtkTab->SetNumberOfComponents(1);
891       vtkTab->SetName(MEDFileFieldRepresentationLeavesArrays::GLOBAL_NODE_ID_NAME);
892       vtkTab->SetArray(gni->getPointer(),gni->getNbOfElems(),0,VTK_DATA_ARRAY_FREE);
893       gni->accessToMemArray().setSpecificDeallocator(0);
894       gni->decrRef();
895     }
896   return ret;
897 }
898
899 //////////////////////
900
901 MEDFileFieldRepresentationTree::MEDFileFieldRepresentationTree()
902 {
903 }
904
905 int MEDFileFieldRepresentationTree::getNumberOfLeavesArrays() const
906 {
907   int ret(0);
908   for(std::vector< std::vector< std::vector< MEDFileFieldRepresentationLeaves > > >::const_iterator it0=_data_structure.begin();it0!=_data_structure.end();it0++)
909     for(std::vector< std::vector< MEDFileFieldRepresentationLeaves > >::const_iterator it1=(*it0).begin();it1!=(*it0).end();it1++)
910       for(std::vector< MEDFileFieldRepresentationLeaves >::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
911         ret+=(*it2).getNumberOfArrays();
912   return ret;
913 }
914
915 void MEDFileFieldRepresentationTree::assignIds() const
916 {
917   int zeId(0);
918   for(std::vector< std::vector< std::vector< MEDFileFieldRepresentationLeaves > > >::const_iterator it0=_data_structure.begin();it0!=_data_structure.end();it0++)
919     for(std::vector< std::vector< MEDFileFieldRepresentationLeaves > >::const_iterator it1=(*it0).begin();it1!=(*it0).end();it1++)
920       for(std::vector< MEDFileFieldRepresentationLeaves >::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
921         (*it2).setId(zeId);
922 }
923
924 void MEDFileFieldRepresentationTree::computeFullNameInLeaves() const
925 {
926    std::size_t it0Cnt(0);
927    for(std::vector< std::vector< std::vector< MEDFileFieldRepresentationLeaves > > >::const_iterator it0=_data_structure.begin();it0!=_data_structure.end();it0++,it0Cnt++)
928      {
929        std::ostringstream oss; oss << MEDFileFieldRepresentationLeavesArrays::TS_STR << it0Cnt;
930        std::string tsName(oss.str());
931        for(std::vector< std::vector< MEDFileFieldRepresentationLeaves > >::const_iterator it1=(*it0).begin();it1!=(*it0).end();it1++)
932          {
933            std::string meshName((*it1)[0].getMeshName());
934            std::size_t it2Cnt(0);
935            for(std::vector< MEDFileFieldRepresentationLeaves >::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++,it2Cnt++)
936              {
937                std::ostringstream oss2; oss2 << MEDFileFieldRepresentationLeavesArrays::COM_SUP_STR << it2Cnt;
938                std::string comSupStr(oss2.str());
939                (*it2).computeFullNameInLeaves(tsName,meshName,comSupStr);
940              }
941          }
942      }
943 }
944
945 void MEDFileFieldRepresentationTree::activateTheFirst() const
946 {
947   for(std::vector< std::vector< std::vector< MEDFileFieldRepresentationLeaves > > >::const_iterator it0=_data_structure.begin();it0!=_data_structure.end();it0++)
948     for(std::vector< std::vector< MEDFileFieldRepresentationLeaves > >::const_iterator it1=(*it0).begin();it1!=(*it0).end();it1++)
949       for(std::vector< MEDFileFieldRepresentationLeaves >::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
950         {
951           (*it2).activateAllArrays();
952           return ;
953         }
954 }
955
956 void MEDFileFieldRepresentationTree::feedSIL(vtkMutableDirectedGraph* sil, vtkIdType root, vtkVariantArray *edge, std::vector<std::string>& names) const
957 {
958   std::size_t it0Cnt(0);
959   for(std::vector< std::vector< std::vector< MEDFileFieldRepresentationLeaves > > >::const_iterator it0=_data_structure.begin();it0!=_data_structure.end();it0++,it0Cnt++)
960     {
961       vtkIdType InfoOnTSId(sil->AddChild(root,edge));
962       names.push_back((*it0)[0][0].getHumanReadableOverviewOfTS());
963       //
964       vtkIdType NbOfTSId(sil->AddChild(InfoOnTSId,edge));
965       std::vector<double> ts;
966       std::vector< std::pair<int,int> > dtits((*it0)[0][0].getTimeStepsInCoarseMEDFileFormat(ts));
967       std::size_t nbOfTS(dtits.size());
968       std::ostringstream oss3; oss3 << nbOfTS;
969       names.push_back(oss3.str());
970       for(std::size_t i=0;i<nbOfTS;i++)
971         {
972           std::ostringstream oss4; oss4 << dtits[i].first;
973           vtkIdType DtId(sil->AddChild(NbOfTSId,edge));
974           names.push_back(oss4.str());
975           std::ostringstream oss5; oss5 << dtits[i].second;
976           vtkIdType ItId(sil->AddChild(DtId,edge));
977           names.push_back(oss5.str());
978           std::ostringstream oss6; oss6 << ts[i];
979           sil->AddChild(ItId,edge);
980           names.push_back(oss6.str());
981         }
982       //
983       std::ostringstream oss; oss << MEDFileFieldRepresentationLeavesArrays::TS_STR << it0Cnt;
984       std::string tsName(oss.str());
985       vtkIdType typeId0(sil->AddChild(root,edge));
986       names.push_back(tsName);
987       for(std::vector< std::vector< MEDFileFieldRepresentationLeaves > >::const_iterator it1=(*it0).begin();it1!=(*it0).end();it1++)
988         {
989           std::string meshName((*it1)[0].getMeshName());
990           vtkIdType typeId1(sil->AddChild(typeId0,edge));
991           names.push_back(meshName);
992           std::size_t it2Cnt(0);
993           for(std::vector< MEDFileFieldRepresentationLeaves >::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++,it2Cnt++)
994             {
995               std::ostringstream oss2; oss2 << MEDFileFieldRepresentationLeavesArrays::COM_SUP_STR << it2Cnt;
996               std::string comSupStr(oss2.str());
997               vtkIdType typeId2(sil->AddChild(typeId1,edge));
998               names.push_back(comSupStr);
999               (*it2).feedSIL(_ms,meshName,sil,typeId2,edge,names);
1000             } 
1001         }
1002     }
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 }