Salome HOME
Split MEDFileField implementation into several parts to make eclipse and developper...
[tools/medcoupling.git] / src / MEDLoader / MEDFileField.cxx
1 // Copyright (C) 2007-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 (EDF R&D)
20
21 #include "MEDFileField.hxx"
22 #include "MEDFileMesh.hxx"
23 #include "MEDLoaderBase.hxx"
24 #include "MEDLoaderTraits.hxx"
25 #include "MEDFileSafeCaller.txx"
26 #include "MEDFileFieldOverView.hxx"
27 #include "MEDFileBlowStrEltUp.hxx"
28 #include "MEDFileFieldVisitor.hxx"
29
30 #include "MEDCouplingFieldDiscretization.hxx"
31
32 #include "InterpKernelAutoPtr.hxx"
33 #include "CellModel.hxx"
34
35 #include <algorithm>
36 #include <iterator>
37
38 extern INTERP_KERNEL::NormalizedCellType typmai2[MED_N_CELL_FIXED_GEO];
39 extern med_geometry_type typmainoeud[1];
40 extern med_geometry_type typmai3[34];
41
42 using namespace MEDCoupling;
43
44 //= MEDFileFields
45
46 MEDFileFields *MEDFileFields::New()
47 {
48   return new MEDFileFields;
49 }
50
51 MEDFileFields *MEDFileFields::New(const std::string& fileName, bool loadAll)
52 {
53   MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
54   return New(fid,loadAll);
55 }
56
57 MEDFileFields *MEDFileFields::NewAdv(const std::string& fileName, bool loadAll, const MEDFileEntities *entities)
58 {
59   MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
60   return NewAdv(fid,loadAll,entities);
61 }
62
63 MEDFileFields *MEDFileFields::NewAdv(med_idt fid, bool loadAll, const MEDFileEntities *entities)
64 {
65   return new MEDFileFields(fid,loadAll,0,entities);
66 }
67
68 MEDFileFields *MEDFileFields::NewWithDynGT(const std::string& fileName, const MEDFileStructureElements *se, bool loadAll)
69 {
70   MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
71   return NewWithDynGT(fid,se,loadAll);
72 }
73
74 MEDFileFields *MEDFileFields::NewWithDynGT(med_idt fid, const MEDFileStructureElements *se, bool loadAll)
75 {
76   if(!se)
77     throw INTERP_KERNEL::Exception("MEDFileFields::NewWithDynGT : null struct element pointer !");
78   INTERP_KERNEL::AutoCppPtr<MEDFileEntities> entities(MEDFileEntities::BuildFrom(*se));
79   return new MEDFileFields(fid,loadAll,0,entities);
80 }
81
82 MEDFileFields *MEDFileFields::New(med_idt fid, bool loadAll)
83 {
84   return new MEDFileFields(fid,loadAll,0,0);
85 }
86
87 MEDFileFields *MEDFileFields::LoadPartOf(const std::string& fileName, bool loadAll, const MEDFileMeshes *ms)
88 {
89   MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
90   return new MEDFileFields(fid,loadAll,ms,0);
91 }
92
93 MEDFileFields *MEDFileFields::LoadSpecificEntities(const std::string& fileName, const std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> >& entities, bool loadAll)
94 {
95   MEDFileUtilities::CheckFileForRead(fileName);
96   INTERP_KERNEL::AutoCppPtr<MEDFileEntities> ent(new MEDFileStaticEntities(entities));
97   MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
98   return new MEDFileFields(fid,loadAll,0,ent);
99 }
100
101 std::size_t MEDFileFields::getHeapMemorySizeWithoutChildren() const
102 {
103   std::size_t ret(MEDFileFieldGlobsReal::getHeapMemorySizeWithoutChildren());
104   ret+=_fields.capacity()*sizeof(MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA>);
105   return ret;
106 }
107
108 std::vector<const BigMemoryObject *> MEDFileFields::getDirectChildrenWithNull() const
109 {
110   std::vector<const BigMemoryObject *> ret;
111   for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++)
112     ret.push_back((const MEDFileAnyTypeFieldMultiTSWithoutSDA *)*it);
113   return ret;
114 }
115
116 MEDFileFields *MEDFileFields::deepCopy() const
117 {
118   MCAuto<MEDFileFields> ret(shallowCpy());
119   std::size_t i(0);
120   for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++,i++)
121     {
122       if((const MEDFileAnyTypeFieldMultiTSWithoutSDA*)*it)
123         ret->_fields[i]=(*it)->deepCopy();
124     }
125   ret->deepCpyGlobs(*this);
126   return ret.retn();
127 }
128
129 MEDFileFields *MEDFileFields::shallowCpy() const
130 {
131   return new MEDFileFields(*this);
132 }
133
134 /*!
135  * This method scans for all fields in \a this which time steps ids are common. Time step are discriminated by the pair of integer (iteration,order) whatever
136  * the double time value. If all returned time steps are \b exactly those for all fields in \a this output parameter \a areThereSomeForgottenTS will be set to false.
137  * If \a areThereSomeForgottenTS is set to true, only the sorted intersection of time steps present for all fields in \a this will be returned.
138  *
139  * \param [out] areThereSomeForgottenTS - indicates to the caller if there is some time steps in \a this that are not present for all fields in \a this.
140  * \return the sorted list of time steps (specified with a pair of integer iteration first and order second) present for all fields in \a this.
141  * 
142  * \sa MEDFileFields::partOfThisLyingOnSpecifiedTimeSteps, MEDFileFields::partOfThisNotLyingOnSpecifiedTimeSteps
143  */
144 std::vector< std::pair<int,int> > MEDFileFields::getCommonIterations(bool& areThereSomeForgottenTS) const
145 {
146   std::set< std::pair<int,int> > s;
147   bool firstShot=true;
148   areThereSomeForgottenTS=false;
149   for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++)
150     {
151       if(!(const MEDFileAnyTypeFieldMultiTSWithoutSDA*)*it)
152         continue;
153       std::vector< std::pair<int,int> > v=(*it)->getIterations();
154       std::set< std::pair<int,int> > s1; std::copy(v.begin(),v.end(),std::inserter(s1,s1.end()));
155       if(firstShot)
156         { s=s1; firstShot=false; }
157       else
158         {
159           std::set< std::pair<int,int> > s2; std::set_intersection(s.begin(),s.end(),s1.begin(),s1.end(),std::inserter(s2,s2.end()));
160           if(s!=s2)
161             areThereSomeForgottenTS=true;
162           s=s2;
163         }
164     }
165   std::vector< std::pair<int,int> > ret;
166   std::copy(s.begin(),s.end(),std::back_insert_iterator< std::vector< std::pair<int,int> > >(ret));
167   return ret;
168 }
169
170 int MEDFileFields::getNumberOfFields() const
171 {
172   return _fields.size();
173 }
174
175 std::vector<std::string> MEDFileFields::getFieldsNames() const
176 {
177   std::vector<std::string> ret(_fields.size());
178   int i(0);
179   for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++,i++)
180     {
181       const MEDFileAnyTypeFieldMultiTSWithoutSDA *f=(*it);
182       if(f)
183         {
184           ret[i]=f->getName();
185         }
186       else
187         {
188           std::ostringstream oss; oss << "MEDFileFields::getFieldsNames : At rank #" << i << " field is not defined !";
189           throw INTERP_KERNEL::Exception(oss.str());
190         }
191     }
192   return ret;
193 }
194
195 std::vector<std::string> MEDFileFields::getMeshesNames() const
196 {
197   std::vector<std::string> ret;
198   for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++)
199     {
200       const MEDFileAnyTypeFieldMultiTSWithoutSDA *cur(*it);
201       if(cur)
202         ret.push_back(cur->getMeshName());
203     }
204   return ret;
205 }
206
207 std::string MEDFileFields::simpleRepr() const
208 {
209   std::ostringstream oss;
210   oss << "(*****************)\n(* MEDFileFields *)\n(*****************)\n\n";
211   simpleRepr(0,oss);
212   return oss.str();
213 }
214
215 void MEDFileFields::simpleRepr(int bkOffset, std::ostream& oss) const
216 {
217   int nbOfFields(getNumberOfFields());
218   std::string startLine(bkOffset,' ');
219   oss << startLine << "There are " << nbOfFields << " fields in this :" << std::endl;
220   int i=0;
221   for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++,i++)
222     {
223       const MEDFileAnyTypeFieldMultiTSWithoutSDA *cur=(*it);
224       if(cur)
225         {
226           oss << startLine << "  - # "<< i << " has the following name : \"" << cur->getName() << "\"." << std::endl;
227         }
228       else
229         {
230           oss << startLine << "  - not defined !" << std::endl;
231         }
232     }
233   i=0;
234   for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++,i++)
235     {
236       const MEDFileAnyTypeFieldMultiTSWithoutSDA *cur=(*it);
237       std::string chapter(17,'0'+i);
238       oss << startLine << chapter << std::endl;
239       if(cur)
240         {
241           cur->simpleRepr(bkOffset+2,oss,i);
242         }
243       else
244         {
245           oss << startLine << "  - not defined !" << std::endl;
246         }
247       oss << startLine << chapter << std::endl;
248     }
249   simpleReprGlobs(oss);
250 }
251
252 MEDFileFields::MEDFileFields()
253 {
254 }
255
256 MEDFileFields::MEDFileFields(med_idt fid, bool loadAll, const MEDFileMeshes *ms, const MEDFileEntities *entities)
257 try:MEDFileFieldGlobsReal(fid)
258 {
259   int nbFields(MEDnField(fid));
260   _fields.resize(nbFields);
261   med_field_type typcha;
262   for(int i=0;i<nbFields;i++)
263     {
264       std::vector<std::string> infos;
265       std::string fieldName,dtunit,meshName;
266       int nbOfStep(MEDFileAnyTypeField1TS::LocateField2(fid,i,false,fieldName,typcha,infos,dtunit,meshName));
267       switch(typcha)
268       {
269         case MED_FLOAT64:
270           {
271             _fields[i]=MEDFileFieldMultiTSWithoutSDA::New(fid,fieldName,meshName,typcha,infos,nbOfStep,dtunit,loadAll,ms,entities);
272             break;
273           }
274         case MED_INT32:
275           {
276             _fields[i]=MEDFileIntFieldMultiTSWithoutSDA::New(fid,fieldName,meshName,typcha,infos,nbOfStep,dtunit,loadAll,ms,entities);
277             break;
278           }
279         case MED_FLOAT32:
280           {
281             _fields[i]=MEDFileFloatFieldMultiTSWithoutSDA::New(fid,fieldName,meshName,typcha,infos,nbOfStep,dtunit,loadAll,ms,entities);
282             break;
283           }
284         case MED_INT:
285           {
286             if(sizeof(med_int)==sizeof(int))
287               {
288                 _fields[i]=MEDFileIntFieldMultiTSWithoutSDA::New(fid,fieldName,meshName,typcha,infos,nbOfStep,dtunit,loadAll,ms,entities);
289                 break;
290               }
291           }
292         default:
293           {
294             std::ostringstream oss; oss << "constructor MEDFileFields(fileName) : file \'" << FileNameFromFID(fid) << "\' at pos #" << i << " field has name \'" << fieldName << "\' but the type of field is not in [MED_FLOAT64, MED_INT32, MED_FLOAT32] !";
295             throw INTERP_KERNEL::Exception(oss.str());
296           }
297       }
298     }
299   loadAllGlobals(fid,entities);
300 }
301 catch(INTERP_KERNEL::Exception& e)
302 {
303     throw e;
304 }
305
306 void MEDFileFields::writeLL(med_idt fid) const
307 {
308   int i=0;
309   writeGlobals(fid,*this);
310   for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++,i++)
311     {
312       const MEDFileAnyTypeFieldMultiTSWithoutSDA *elt=*it;
313       if(!elt)
314         {
315           std::ostringstream oss; oss << "MEDFileFields::write : at rank #" << i << "/" << _fields.size() << " field is empty !";
316           throw INTERP_KERNEL::Exception(oss.str());
317         }
318       elt->writeLL(fid,*this);
319     }
320 }
321
322 /*!
323  * This method alloc the arrays and load potentially huge arrays contained in this field.
324  * This method should be called when a MEDFileAnyTypeFieldMultiTS::New constructor has been with false as the last parameter.
325  * This method can be also called to refresh or reinit values from a file.
326  * 
327  * \throw If the fileName is not set or points to a non readable MED file.
328  */
329 void MEDFileFields::loadArrays()
330 {
331   if(getFileName().empty())
332     throw INTERP_KERNEL::Exception("MEDFileFields::loadArrays : the structure does not come from a file !");
333   MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(getFileName()));
334   for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::iterator it=_fields.begin();it!=_fields.end();it++)
335     {
336       MEDFileAnyTypeFieldMultiTSWithoutSDA *elt(*it);
337       if(elt)
338         elt->loadBigArraysRecursively(fid,*elt);
339     }
340 }
341
342 /*!
343  * This method behaves as MEDFileFields::loadArrays does, the first call, if \a this was built using a file without loading big arrays.
344  * But once data loaded once, this method does nothing.
345  * 
346  * \throw If the fileName is not set or points to a non readable MED file.
347  * \sa MEDFileFields::loadArrays, MEDFileFields::unloadArrays
348  */
349 void MEDFileFields::loadArraysIfNecessary()
350 {
351   if(!getFileName().empty())
352     {
353       MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(getFileName()));
354       for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::iterator it=_fields.begin();it!=_fields.end();it++)
355         {
356           MEDFileAnyTypeFieldMultiTSWithoutSDA *elt(*it);
357           if(elt)
358             elt->loadBigArraysRecursivelyIfNecessary(fid,*elt);
359         }
360     }
361 }
362
363 /*!
364  * This method releases potentially big data arrays and so returns to the same heap memory than status loaded with 'loadAll' parameter set to false.
365  * \b WARNING, this method does release arrays even if \a this does not come from a load of a MED file.
366  * So this method can lead to a loss of data. If you want to unload arrays safely call MEDFileFields::unloadArraysWithoutDataLoss instead.
367  * 
368  * \sa MEDFileFields::loadArrays, MEDFileFields::loadArraysIfNecessary, MEDFileFields::unloadArraysWithoutDataLoss
369  */
370 void MEDFileFields::unloadArrays()
371 {
372   for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::iterator it=_fields.begin();it!=_fields.end();it++)
373     {
374       MEDFileAnyTypeFieldMultiTSWithoutSDA *elt(*it);
375       if(elt)
376         elt->unloadArrays();
377     }
378 }
379
380 /*!
381  * This method potentially releases big data arrays if \a this is coming from a file. If \a this has been built from scratch this method will have no effect.
382  * This method is the symetrical method of MEDFileFields::loadArraysIfNecessary.
383  * This method is useful to reduce \b safely amount of heap memory necessary for \a this by using MED file as database.
384  * 
385  * \sa MEDFileFields::loadArraysIfNecessary
386  */
387 void MEDFileFields::unloadArraysWithoutDataLoss()
388 {
389   if(!getFileName().empty())
390     unloadArrays();
391 }
392
393 std::vector<std::string> MEDFileFields::getPflsReallyUsed() const
394 {
395   std::vector<std::string> ret;
396   std::set<std::string> ret2;
397   for(std::vector< MCAuto< MEDFileAnyTypeFieldMultiTSWithoutSDA > >::const_iterator it=_fields.begin();it!=_fields.end();it++)
398     {
399       std::vector<std::string> tmp=(*it)->getPflsReallyUsed2();
400       for(std::vector<std::string>::const_iterator it2=tmp.begin();it2!=tmp.end();it2++)
401         if(ret2.find(*it2)==ret2.end())
402           {
403             ret.push_back(*it2);
404             ret2.insert(*it2);
405           }
406     }
407   return ret;
408 }
409
410 std::vector<std::string> MEDFileFields::getLocsReallyUsed() const
411 {
412   std::vector<std::string> ret;
413   std::set<std::string> ret2;
414   for(std::vector< MCAuto< MEDFileAnyTypeFieldMultiTSWithoutSDA > >::const_iterator it=_fields.begin();it!=_fields.end();it++)
415     {
416       std::vector<std::string> tmp((*it)->getLocsReallyUsed2());
417       for(std::vector<std::string>::const_iterator it2=tmp.begin();it2!=tmp.end();it2++)
418         if(ret2.find(*it2)==ret2.end())
419           {
420             ret.push_back(*it2);
421             ret2.insert(*it2);
422           }
423     }
424   return ret;
425 }
426
427 std::vector<std::string> MEDFileFields::getPflsReallyUsedMulti() const
428 {
429   std::vector<std::string> ret;
430   for(std::vector< MCAuto< MEDFileAnyTypeFieldMultiTSWithoutSDA > >::const_iterator it=_fields.begin();it!=_fields.end();it++)
431     {
432       std::vector<std::string> tmp((*it)->getPflsReallyUsedMulti2());
433       ret.insert(ret.end(),tmp.begin(),tmp.end());
434     }
435   return ret;
436 }
437
438 std::vector<std::string> MEDFileFields::getLocsReallyUsedMulti() const
439 {
440   std::vector<std::string> ret;
441   for(std::vector< MCAuto< MEDFileAnyTypeFieldMultiTSWithoutSDA > >::const_iterator it=_fields.begin();it!=_fields.end();it++)
442     {
443       std::vector<std::string> tmp((*it)->getLocsReallyUsed2());
444       ret.insert(ret.end(),tmp.begin(),tmp.end());
445     }
446   return ret;
447 }
448
449 void MEDFileFields::changePflsRefsNamesGen(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif)
450 {
451   for(std::vector< MCAuto< MEDFileAnyTypeFieldMultiTSWithoutSDA > >::iterator it=_fields.begin();it!=_fields.end();it++)
452     (*it)->changePflsRefsNamesGen2(mapOfModif);
453 }
454
455 void MEDFileFields::changeLocsRefsNamesGen(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif)
456 {
457   for(std::vector< MCAuto< MEDFileAnyTypeFieldMultiTSWithoutSDA > >::iterator it=_fields.begin();it!=_fields.end();it++)
458     (*it)->changeLocsRefsNamesGen2(mapOfModif);
459 }
460
461 void MEDFileFields::resize(int newSize)
462 {
463   _fields.resize(newSize);
464 }
465
466 void MEDFileFields::pushFields(const std::vector<MEDFileAnyTypeFieldMultiTS *>& fields)
467 {
468   for(std::vector<MEDFileAnyTypeFieldMultiTS *>::const_iterator it=fields.begin();it!=fields.end();it++)
469     pushField(*it);
470 }
471
472 void MEDFileFields::pushField(MEDFileAnyTypeFieldMultiTS *field)
473 {
474   if(!field)
475     throw INTERP_KERNEL::Exception("MEDFileFields::pushMesh : invalid input pointer ! should be different from 0 !");
476   _fields.push_back(field->getContent());
477   appendGlobs(*field,1e-12);
478 }
479
480 void MEDFileFields::setFieldAtPos(int i, MEDFileAnyTypeFieldMultiTS *field)
481 {
482   if(!field)
483     throw INTERP_KERNEL::Exception("MEDFileFields::setFieldAtPos : invalid input pointer ! should be different from 0 !");
484   if(i>=(int)_fields.size())
485     _fields.resize(i+1);
486   _fields[i]=field->getContent();
487   appendGlobs(*field,1e-12);
488 }
489
490 void MEDFileFields::destroyFieldAtPos(int i)
491 {
492   destroyFieldsAtPos(&i,&i+1);
493 }
494
495 void MEDFileFields::destroyFieldsAtPos(const int *startIds, const int *endIds)
496 {
497   std::vector<bool> b(_fields.size(),true);
498   for(const int *i=startIds;i!=endIds;i++)
499     {
500       if(*i<0 || *i>=(int)_fields.size())
501         {
502           std::ostringstream oss; oss << "MEDFileFields::destroyFieldsAtPos : Invalid given id in input (" << *i << ") should be in [0," << _fields.size() << ") !";
503           throw INTERP_KERNEL::Exception(oss.str());
504         }
505       b[*i]=false;
506     }
507   std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> > fields(std::count(b.begin(),b.end(),true));
508   std::size_t j=0;
509   for(std::size_t i=0;i<_fields.size();i++)
510     if(b[i])
511       fields[j++]=_fields[i];
512   _fields=fields;
513 }
514
515 void MEDFileFields::destroyFieldsAtPos2(int bg, int end, int step)
516 {
517   static const char msg[]="MEDFileFields::destroyFieldsAtPos2";
518   int nbOfEntriesToKill(DataArrayInt::GetNumberOfItemGivenBESRelative(bg,end,step,msg));
519   std::vector<bool> b(_fields.size(),true);
520   int k=bg;
521   for(int i=0;i<nbOfEntriesToKill;i++,k+=step)
522     {
523       if(k<0 || k>=(int)_fields.size())
524         {
525           std::ostringstream oss; oss << "MEDFileFields::destroyFieldsAtPos2 : Invalid given id in input (" << k << ") should be in [0," << _fields.size() << ") !";
526           throw INTERP_KERNEL::Exception(oss.str());
527         }
528       b[k]=false;
529     }
530   std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> > fields(std::count(b.begin(),b.end(),true));
531   std::size_t j(0);
532   for(std::size_t i=0;i<_fields.size();i++)
533     if(b[i])
534       fields[j++]=_fields[i];
535   _fields=fields;
536 }
537
538 bool MEDFileFields::changeMeshNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
539 {
540   bool ret(false);
541   for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::iterator it=_fields.begin();it!=_fields.end();it++)
542     {
543       MEDFileAnyTypeFieldMultiTSWithoutSDA *cur(*it);
544       if(cur)
545         ret=cur->changeMeshNames(modifTab) || ret;
546     }
547   return ret;
548 }
549
550 /*!
551  * \param [in] meshName the name of the mesh that will be renumbered.
552  * \param [in] oldCode is of format returned by MEDCouplingUMesh::getDistributionOfTypes. And for each *i* oldCode[3*i+2] gives the position (MEDFileUMesh::PutInThirdComponentOfCodeOffset).
553  *             This code corresponds to the distribution of types in the corresponding mesh.
554  * \param [in] newCode idem to param \a oldCode except that here the new distribution is given.
555  * \param [in] renumO2N the old to new renumber array.
556  * \return If true a renumbering has been performed. The structure in \a this has been modified. If false, nothing has been done: it is typically the case if \a meshName is not refered by any 
557  *         field in \a this.
558  */
559 bool MEDFileFields::renumberEntitiesLyingOnMesh(const std::string& meshName, const std::vector<int>& oldCode, const std::vector<int>& newCode, const DataArrayInt *renumO2N)
560 {
561   bool ret(false);
562   for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::iterator it=_fields.begin();it!=_fields.end();it++)
563     {
564       MEDFileAnyTypeFieldMultiTSWithoutSDA *fmts(*it);
565       if(fmts)
566         {
567           ret=fmts->renumberEntitiesLyingOnMesh(meshName,oldCode,newCode,renumO2N,*this) || ret;
568         }
569     }
570   return ret;
571 }
572
573 /*!
574  * Return an extraction of \a this using \a extractDef map to specify the extraction.
575  * The keys of \a extractDef is level relative to max ext of \a mm mesh.
576  *
577  * \return A new object that the caller is responsible to deallocate.
578  */
579 MEDFileFields *MEDFileFields::extractPart(const std::map<int, MCAuto<DataArrayInt> >& extractDef, MEDFileMesh *mm) const
580 {
581   if(!mm)
582     throw INTERP_KERNEL::Exception("MEDFileFields::extractPart : input mesh is NULL !");
583   MCAuto<MEDFileFields> fsOut(MEDFileFields::New());
584   int nbFields(getNumberOfFields());
585   for(int i=0;i<nbFields;i++)
586     {
587       MCAuto<MEDFileAnyTypeFieldMultiTS> fmts(getFieldAtPos(i));
588       if(!fmts)
589         {
590           std::ostringstream oss; oss << "MEDFileFields::extractPart : at pos #" << i << " field is null !";
591           throw INTERP_KERNEL::Exception(oss.str());
592         }
593       MCAuto<MEDFileAnyTypeFieldMultiTS> fmtsOut(fmts->extractPart(extractDef,mm));
594       fsOut->pushField(fmtsOut);
595     }
596   return fsOut.retn();
597 }
598
599 void MEDFileFields::accept(MEDFileFieldVisitor& visitor) const
600 {
601   for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++)
602     if((*it).isNotNull())
603       {
604         visitor.newFieldEntry(*it);
605         (*it)->accept(visitor);
606         visitor.endFieldEntry(*it);
607       }
608 }
609
610 MEDFileAnyTypeFieldMultiTS *MEDFileFields::getFieldAtPos(int i) const
611 {
612   if(i<0 || i>=(int)_fields.size())
613     {
614       std::ostringstream oss; oss << "MEDFileFields::getFieldAtPos : Invalid given id in input (" << i << ") should be in [0," << _fields.size() << ") !";
615       throw INTERP_KERNEL::Exception(oss.str());
616     }
617   const MEDFileAnyTypeFieldMultiTSWithoutSDA *fmts=_fields[i];
618   if(!fmts)
619     return 0;
620   MCAuto<MEDFileAnyTypeFieldMultiTS> ret;
621   const MEDFileFieldMultiTSWithoutSDA *fmtsC(dynamic_cast<const MEDFileFieldMultiTSWithoutSDA *>(fmts));
622   const MEDFileIntFieldMultiTSWithoutSDA *fmtsC2(dynamic_cast<const MEDFileIntFieldMultiTSWithoutSDA *>(fmts));
623   const MEDFileFloatFieldMultiTSWithoutSDA *fmtsC3(dynamic_cast<const MEDFileFloatFieldMultiTSWithoutSDA *>(fmts));
624   if(fmtsC)
625     ret=MEDFileFieldMultiTS::New(*fmtsC,false);
626   else if(fmtsC2)
627     ret=MEDFileIntFieldMultiTS::New(*fmtsC2,false);
628   else if(fmtsC3)
629     ret=MEDFileFloatFieldMultiTS::New(*fmtsC3,false);
630   else
631     {
632       std::ostringstream oss; oss << "MEDFileFields::getFieldAtPos : At pos #" << i << " field is neither double (FLOAT64) nor float (FLOAT32) nor integer (INT32) !";
633       throw INTERP_KERNEL::Exception(oss.str());
634     }
635   ret->shallowCpyGlobs(*this);
636   return ret.retn();
637 }
638
639 /*!
640  * Return a shallow copy of \a this reduced to the fields ids defined in [ \a startIds , endIds ).
641  * This method is accessible in python using __getitem__ with a list in input.
642  * \return a new object that the caller should deal with.
643  */
644 MEDFileFields *MEDFileFields::buildSubPart(const int *startIds, const int *endIds) const
645 {
646   MCAuto<MEDFileFields> ret=shallowCpy();
647   std::size_t sz=std::distance(startIds,endIds);
648   std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> > fields(sz);
649   int j=0;
650   for(const int *i=startIds;i!=endIds;i++,j++)
651     {
652       if(*i<0 || *i>=(int)_fields.size())
653         {
654           std::ostringstream oss; oss << "MEDFileFields::buildSubPart : Invalid given id in input (" << *i << ") should be in [0," << _fields.size() << ") !";
655           throw INTERP_KERNEL::Exception(oss.str());
656         }
657       fields[j]=_fields[*i];
658     }
659   ret->_fields=fields;
660   return ret.retn();
661 }
662
663 MEDFileAnyTypeFieldMultiTS *MEDFileFields::getFieldWithName(const std::string& fieldName) const
664 {
665   return getFieldAtPos(getPosFromFieldName(fieldName));
666 }
667
668 /*!
669  * This method removes, if any, fields in \a this having no time steps.
670  * If there is one or more than one such field in \a this true is returned and those fields will not be referenced anymore in \a this.
671  * 
672  * If false is returned \a this does not contain such fields. If false is returned this method can be considered as const.
673  */
674 bool MEDFileFields::removeFieldsWithoutAnyTimeStep()
675 {
676   std::vector<MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> > newFields;
677   for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++)
678     {
679       const MEDFileAnyTypeFieldMultiTSWithoutSDA *elt(*it);
680       if(elt)
681         {
682           if(elt->getNumberOfTS()>0)
683             newFields.push_back(*it);
684         }
685     }
686   if(_fields.size()==newFields.size())
687     return false;
688   _fields=newFields;
689   return true;
690 }
691
692 /*!
693  * This method returns a new object containing part of \a this fields lying on mesh name specified by the input parameter \a meshName.
694  * This method can be seen as a filter applied on \a this, that returns an object containing
695  * reduced the list of fields compared to those in \a this. The returned object is a new object but the object on which it lies are only
696  * shallow copied from \a this.
697  * 
698  * \param [in] meshName - the name of the mesh on w
699  * \return a new object that the caller should deal with.
700  */
701 MEDFileFields *MEDFileFields::partOfThisLyingOnSpecifiedMeshName(const std::string& meshName) const
702 {
703   MCAuto<MEDFileFields> ret(MEDFileFields::New());
704   for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++)
705     {
706       const MEDFileAnyTypeFieldMultiTSWithoutSDA *cur(*it);
707       if(!cur)
708         continue;
709       if(cur->getMeshName()==meshName)
710         {
711           cur->incrRef();
712           MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> cur2(const_cast<MEDFileAnyTypeFieldMultiTSWithoutSDA *>(cur));
713           ret->_fields.push_back(cur2);
714         }
715     }
716   ret->shallowCpyOnlyUsedGlobs(*this);
717   return ret.retn();
718 }
719
720 /*!
721  * This method returns a new object containing part of \a this fields lying ** exactly ** on the time steps specified by input parameter \a timeSteps.
722  * Input time steps are specified using a pair of integer (iteration, order).
723  * This method can be seen as a filter applied on \a this, that returns an object containing the same number of fields than those in \a this,
724  * but for each multitimestep only the time steps in \a timeSteps are kept.
725  * Typically the input parameter \a timeSteps comes from the call of MEDFileFields::getCommonIterations.
726  * 
727  * The returned object points to shallow copy of elements in \a this.
728  * 
729  * \param [in] timeSteps - the time steps given by a vector of pair of integers (iteration,order)
730  * \throw If there is a field in \a this that is \b not defined on a time step in the input \a timeSteps.
731  * \sa MEDFileFields::getCommonIterations, MEDFileFields::partOfThisNotLyingOnSpecifiedTimeSteps
732  */
733 MEDFileFields *MEDFileFields::partOfThisLyingOnSpecifiedTimeSteps(const std::vector< std::pair<int,int> >& timeSteps) const
734 {
735   MCAuto<MEDFileFields> ret(MEDFileFields::New());
736   for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++)
737     {
738       const MEDFileAnyTypeFieldMultiTSWithoutSDA *cur(*it);
739       if(!cur)
740         continue;
741       MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> elt=cur->partOfThisLyingOnSpecifiedTimeSteps(timeSteps);
742       ret->_fields.push_back(elt);
743     }
744   ret->shallowCpyOnlyUsedGlobs(*this);
745   return ret.retn();
746 }
747
748 /*!
749  * \sa MEDFileFields::getCommonIterations, MEDFileFields::partOfThisLyingOnSpecifiedTimeSteps
750  */
751 MEDFileFields *MEDFileFields::partOfThisNotLyingOnSpecifiedTimeSteps(const std::vector< std::pair<int,int> >& timeSteps) const
752 {
753   MCAuto<MEDFileFields> ret=MEDFileFields::New();
754   for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++)
755     {
756       const MEDFileAnyTypeFieldMultiTSWithoutSDA *cur(*it);
757       if(!cur)
758         continue;
759       MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> elt=cur->partOfThisNotLyingOnSpecifiedTimeSteps(timeSteps);
760       if(elt->getNumberOfTS()!=0)
761         ret->_fields.push_back(elt);
762     }
763   ret->shallowCpyOnlyUsedGlobs(*this);
764   return ret.retn();
765 }
766
767 bool MEDFileFields::presenceOfStructureElements() const
768 {
769   for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++)
770     if((*it).isNotNull())
771       if((*it)->presenceOfStructureElements())
772         return true;
773   return false;
774 }
775
776 void MEDFileFields::killStructureElements()
777 {
778   std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> > ret;
779   for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::iterator it=_fields.begin();it!=_fields.end();it++)
780     if((*it).isNotNull())
781       {
782         if((*it)->presenceOfStructureElements())
783           {
784             if(!(*it)->onlyStructureElements())
785               {
786                 (*it)->killStructureElements();
787                 ret.push_back(*it);
788               }
789           }
790         else
791           {
792             ret.push_back(*it);
793           }
794       }
795   _fields=ret;
796 }
797
798 void MEDFileFields::keepOnlyStructureElements()
799 {
800   std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> > ret;
801   for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::iterator it=_fields.begin();it!=_fields.end();it++)
802     if((*it).isNotNull())
803       {
804         if((*it)->presenceOfStructureElements())
805           {
806             if(!(*it)->onlyStructureElements())
807               (*it)->keepOnlyStructureElements();
808             ret.push_back(*it);
809           }
810       }
811   _fields=ret;
812 }
813
814 void MEDFileFields::keepOnlyOnMeshSE(const std::string& meshName, const std::string& seName)
815 {
816   std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> > ret;
817   for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::iterator it=_fields.begin();it!=_fields.end();it++)
818     if((*it).isNotNull())
819       {
820         if((*it)->getMeshName()!=meshName)
821           continue;
822         std::vector< std::pair<std::string,std::string> > ps;
823         (*it)->getMeshSENames(ps);
824         std::pair<std::string,std::string> p(meshName,seName);
825         if(std::find(ps.begin(),ps.end(),p)!=ps.end())
826           (*it)->keepOnlyOnSE(seName);
827         ret.push_back(*it);
828       }
829   _fields=ret;
830 }
831
832 void MEDFileFields::getMeshSENames(std::vector< std::pair<std::string,std::string> >& ps) const
833 {
834   for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++)
835     if((*it).isNotNull())
836       (*it)->getMeshSENames(ps);
837 }
838
839 void MEDFileFields::blowUpSE(MEDFileMeshes *ms, const MEDFileStructureElements *ses)
840 {
841   MEDFileBlowStrEltUp::DealWithSE(this,ms,ses);
842 }
843
844 MCAuto<MEDFileFields> MEDFileFields::partOfThisOnStructureElements() const
845 {
846   MCAuto<MEDFileFields> ret(deepCopy());
847   ret->keepOnlyStructureElements();
848   return ret;
849 }
850
851 MCAuto<MEDFileFields> MEDFileFields::partOfThisLyingOnSpecifiedMeshSEName(const std::string& meshName, const std::string& seName) const
852 {
853   MCAuto<MEDFileFields> ret(deepCopy());
854   ret->keepOnlyOnMeshSE(meshName,seName);
855   return ret;
856 }
857
858 void MEDFileFields::aggregate(const MEDFileFields& other)
859 {
860   int nbFieldsToAdd(other.getNumberOfFields());
861   std::vector<std::string> fsn(getFieldsNames());
862   for(int i=0;i<nbFieldsToAdd;i++)
863     {
864       MCAuto<MEDFileAnyTypeFieldMultiTS> elt(other.getFieldAtPos(i));
865       std::string name(elt->getName());
866       if(std::find(fsn.begin(),fsn.end(),name)!=fsn.end())
867         {
868           std::ostringstream oss; oss << "MEDFileFields::aggregate : name \"" << name << "\" already appears !";
869           throw INTERP_KERNEL::Exception(oss.str());
870         }
871       pushField(elt);
872     }
873 }
874
875 MEDFileFieldsIterator *MEDFileFields::iterator()
876 {
877   return new MEDFileFieldsIterator(this);
878 }
879
880 int MEDFileFields::getPosFromFieldName(const std::string& fieldName) const
881 {
882   std::string tmp(fieldName);
883   std::vector<std::string> poss;
884   for(std::size_t i=0;i<_fields.size();i++)
885     {
886       const MEDFileAnyTypeFieldMultiTSWithoutSDA *f(_fields[i]);
887       if(f)
888         {
889           std::string fname(f->getName());
890           if(tmp==fname)
891             return i;
892           else
893             poss.push_back(fname);
894         }
895     }
896   std::ostringstream oss; oss << "MEDFileFields::getPosFromFieldName : impossible to find field '" << tmp << "' in this ! Possibilities are : ";
897   std::copy(poss.begin(),poss.end(),std::ostream_iterator<std::string>(oss,", "));
898   oss << " !";
899   throw INTERP_KERNEL::Exception(oss.str());
900 }
901
902 MEDFileFieldsIterator::MEDFileFieldsIterator(MEDFileFields *fs):_fs(fs),_iter_id(0),_nb_iter(0)
903 {
904   if(fs)
905     {
906       fs->incrRef();
907       _nb_iter=fs->getNumberOfFields();
908     }
909 }
910
911 MEDFileFieldsIterator::~MEDFileFieldsIterator() 
912 {
913 }
914
915 MEDFileAnyTypeFieldMultiTS *MEDFileFieldsIterator::nextt()
916 {
917   if(_iter_id<_nb_iter)
918     {
919       MEDFileFields *fs(_fs);
920       if(fs)
921         return fs->getFieldAtPos(_iter_id++);
922       else
923         return 0;
924     }
925   else
926     return 0;
927 }