Salome HOME
768ee2db2fbdce310cc45eacdc3a8c480356e02c
[tools/medcoupling.git] / src / MEDLoader / MEDFileField.cxx
1 // Copyright (C) 2007-2020  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[INTERP_KERNEL::NORM_MAXTYPE];
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 (int)_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   med_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]=MEDFileInt32FieldMultiTSWithoutSDA::New(fid,fieldName,meshName,typcha,infos,nbOfStep,dtunit,loadAll,ms,entities);
277             break;
278           }
279         case MED_INT64:
280           {
281             _fields[i]=MEDFileInt64FieldMultiTSWithoutSDA::New(fid,fieldName,meshName,typcha,infos,nbOfStep,dtunit,loadAll,ms,entities);
282             break;
283           }
284         case MED_FLOAT32:
285           {
286             _fields[i]=MEDFileFloatFieldMultiTSWithoutSDA::New(fid,fieldName,meshName,typcha,infos,nbOfStep,dtunit,loadAll,ms,entities);
287             break;
288           }
289         case MED_INT:
290           {
291             if(sizeof(med_int)==sizeof(int))
292               {
293                 _fields[i]=MEDFileInt32FieldMultiTSWithoutSDA::New(fid,fieldName,meshName,typcha,infos,nbOfStep,dtunit,loadAll,ms,entities);
294                 break;
295               }
296           }
297         default:
298           {
299             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, MED_INT64] !";
300             throw INTERP_KERNEL::Exception(oss.str());
301           }
302       }
303     }
304   loadAllGlobals(fid,entities);
305 }
306 catch(INTERP_KERNEL::Exception& e)
307 {
308     throw e;
309 }
310
311 void MEDFileFields::writeLL(med_idt fid) const
312 {
313   int i=0;
314   writeGlobals(fid,*this);
315   for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++,i++)
316     {
317       const MEDFileAnyTypeFieldMultiTSWithoutSDA *elt=*it;
318       if(!elt)
319         {
320           std::ostringstream oss; oss << "MEDFileFields::write : at rank #" << i << "/" << _fields.size() << " field is empty !";
321           throw INTERP_KERNEL::Exception(oss.str());
322         }
323       elt->writeLL(fid,*this);
324     }
325 }
326
327 /*!
328  * This method alloc the arrays and load potentially huge arrays contained in this field.
329  * This method should be called when a MEDFileAnyTypeFieldMultiTS::New constructor has been with false as the last parameter.
330  * This method can be also called to refresh or reinit values from a file.
331  * 
332  * \throw If the fileName is not set or points to a non readable MED file.
333  */
334 void MEDFileFields::loadArrays()
335 {
336   if(getFileName().empty())
337     throw INTERP_KERNEL::Exception("MEDFileFields::loadArrays : the structure does not come from a file !");
338   MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(getFileName()));
339   for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::iterator it=_fields.begin();it!=_fields.end();it++)
340     {
341       MEDFileAnyTypeFieldMultiTSWithoutSDA *elt(*it);
342       if(elt)
343         elt->loadBigArraysRecursively(fid,*elt);
344     }
345 }
346
347 /*!
348  * This method behaves as MEDFileFields::loadArrays does, the first call, if \a this was built using a file without loading big arrays.
349  * But once data loaded once, this method does nothing.
350  * 
351  * \throw If the fileName is not set or points to a non readable MED file.
352  * \sa MEDFileFields::loadArrays, MEDFileFields::unloadArrays
353  */
354 void MEDFileFields::loadArraysIfNecessary()
355 {
356   if(!getFileName().empty())
357     {
358       MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(getFileName()));
359       for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::iterator it=_fields.begin();it!=_fields.end();it++)
360         {
361           MEDFileAnyTypeFieldMultiTSWithoutSDA *elt(*it);
362           if(elt)
363             elt->loadBigArraysRecursivelyIfNecessary(fid,*elt);
364         }
365     }
366 }
367
368 /*!
369  * This method releases potentially big data arrays and so returns to the same heap memory than status loaded with 'loadAll' parameter set to false.
370  * \b WARNING, this method does release arrays even if \a this does not come from a load of a MED file.
371  * So this method can lead to a loss of data. If you want to unload arrays safely call MEDFileFields::unloadArraysWithoutDataLoss instead.
372  * 
373  * \sa MEDFileFields::loadArrays, MEDFileFields::loadArraysIfNecessary, MEDFileFields::unloadArraysWithoutDataLoss
374  */
375 void MEDFileFields::unloadArrays()
376 {
377   for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::iterator it=_fields.begin();it!=_fields.end();it++)
378     {
379       MEDFileAnyTypeFieldMultiTSWithoutSDA *elt(*it);
380       if(elt)
381         elt->unloadArrays();
382     }
383 }
384
385 /*!
386  * 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.
387  * This method is the symmetrical method of MEDFileFields::loadArraysIfNecessary.
388  * This method is useful to reduce \b safely amount of heap memory necessary for \a this by using MED file as database.
389  * 
390  * \sa MEDFileFields::loadArraysIfNecessary
391  */
392 void MEDFileFields::unloadArraysWithoutDataLoss()
393 {
394   if(!getFileName().empty())
395     unloadArrays();
396 }
397
398 std::vector<std::string> MEDFileFields::getPflsReallyUsed() const
399 {
400   std::vector<std::string> ret;
401   std::set<std::string> ret2;
402   for(std::vector< MCAuto< MEDFileAnyTypeFieldMultiTSWithoutSDA > >::const_iterator it=_fields.begin();it!=_fields.end();it++)
403     {
404       std::vector<std::string> tmp=(*it)->getPflsReallyUsed2();
405       for(std::vector<std::string>::const_iterator it2=tmp.begin();it2!=tmp.end();it2++)
406         if(ret2.find(*it2)==ret2.end())
407           {
408             ret.push_back(*it2);
409             ret2.insert(*it2);
410           }
411     }
412   return ret;
413 }
414
415 std::vector<std::string> MEDFileFields::getLocsReallyUsed() const
416 {
417   std::vector<std::string> ret;
418   std::set<std::string> ret2;
419   for(std::vector< MCAuto< MEDFileAnyTypeFieldMultiTSWithoutSDA > >::const_iterator it=_fields.begin();it!=_fields.end();it++)
420     {
421       std::vector<std::string> tmp((*it)->getLocsReallyUsed2());
422       for(std::vector<std::string>::const_iterator it2=tmp.begin();it2!=tmp.end();it2++)
423         if(ret2.find(*it2)==ret2.end())
424           {
425             ret.push_back(*it2);
426             ret2.insert(*it2);
427           }
428     }
429   return ret;
430 }
431
432 std::vector<std::string> MEDFileFields::getPflsReallyUsedMulti() const
433 {
434   std::vector<std::string> ret;
435   for(std::vector< MCAuto< MEDFileAnyTypeFieldMultiTSWithoutSDA > >::const_iterator it=_fields.begin();it!=_fields.end();it++)
436     {
437       std::vector<std::string> tmp((*it)->getPflsReallyUsedMulti2());
438       ret.insert(ret.end(),tmp.begin(),tmp.end());
439     }
440   return ret;
441 }
442
443 std::vector<std::string> MEDFileFields::getLocsReallyUsedMulti() const
444 {
445   std::vector<std::string> ret;
446   for(std::vector< MCAuto< MEDFileAnyTypeFieldMultiTSWithoutSDA > >::const_iterator it=_fields.begin();it!=_fields.end();it++)
447     {
448       std::vector<std::string> tmp((*it)->getLocsReallyUsed2());
449       ret.insert(ret.end(),tmp.begin(),tmp.end());
450     }
451   return ret;
452 }
453
454 void MEDFileFields::changePflsRefsNamesGen(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif)
455 {
456   for(std::vector< MCAuto< MEDFileAnyTypeFieldMultiTSWithoutSDA > >::iterator it=_fields.begin();it!=_fields.end();it++)
457     (*it)->changePflsRefsNamesGen2(mapOfModif);
458 }
459
460 void MEDFileFields::changeLocsRefsNamesGen(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif)
461 {
462   for(std::vector< MCAuto< MEDFileAnyTypeFieldMultiTSWithoutSDA > >::iterator it=_fields.begin();it!=_fields.end();it++)
463     (*it)->changeLocsRefsNamesGen2(mapOfModif);
464 }
465
466 void MEDFileFields::resize(int newSize)
467 {
468   _fields.resize(newSize);
469 }
470
471 void MEDFileFields::pushFields(const std::vector<MEDFileAnyTypeFieldMultiTS *>& fields)
472 {
473   for(std::vector<MEDFileAnyTypeFieldMultiTS *>::const_iterator it=fields.begin();it!=fields.end();it++)
474     pushField(*it);
475 }
476
477 void MEDFileFields::pushField(MEDFileAnyTypeFieldMultiTS *field)
478 {
479   if(!field)
480     throw INTERP_KERNEL::Exception("MEDFileFields::pushMesh : invalid input pointer ! should be different from 0 !");
481   _fields.push_back(field->getContent());
482   appendGlobs(*field,1e-12);
483 }
484
485 void MEDFileFields::setFieldAtPos(int i, MEDFileAnyTypeFieldMultiTS *field)
486 {
487   if(!field)
488     throw INTERP_KERNEL::Exception("MEDFileFields::setFieldAtPos : invalid input pointer ! should be different from 0 !");
489   if(i>=(int)_fields.size())
490     _fields.resize(i+1);
491   _fields[i]=field->getContent();
492   appendGlobs(*field,1e-12);
493 }
494
495 void MEDFileFields::destroyFieldAtPos(int i)
496 {
497   destroyFieldsAtPos(&i,&i+1);
498 }
499
500 void MEDFileFields::destroyFieldsAtPos(const int *startIds, const int *endIds)
501 {
502   std::vector<bool> b(_fields.size(),true);
503   for(const int *i=startIds;i!=endIds;i++)
504     {
505       if(*i<0 || *i>=(int)_fields.size())
506         {
507           std::ostringstream oss; oss << "MEDFileFields::destroyFieldsAtPos : Invalid given id in input (" << *i << ") should be in [0," << _fields.size() << ") !";
508           throw INTERP_KERNEL::Exception(oss.str());
509         }
510       b[*i]=false;
511     }
512   std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> > fields(std::count(b.begin(),b.end(),true));
513   std::size_t j=0;
514   for(std::size_t i=0;i<_fields.size();i++)
515     if(b[i])
516       fields[j++]=_fields[i];
517   _fields=fields;
518 }
519
520 void MEDFileFields::destroyFieldsAtPos2(int bg, int end, int step)
521 {
522   static const char msg[]="MEDFileFields::destroyFieldsAtPos2";
523   mcIdType nbOfEntriesToKill(DataArrayIdType::GetNumberOfItemGivenBESRelative(bg,end,step,msg));
524   std::vector<bool> b(_fields.size(),true);
525   int k=bg;
526   for(int i=0;i<nbOfEntriesToKill;i++,k+=step)
527     {
528       if(k<0 || k>=(int)_fields.size())
529         {
530           std::ostringstream oss; oss << "MEDFileFields::destroyFieldsAtPos2 : Invalid given id in input (" << k << ") should be in [0," << _fields.size() << ") !";
531           throw INTERP_KERNEL::Exception(oss.str());
532         }
533       b[k]=false;
534     }
535   std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> > fields(std::count(b.begin(),b.end(),true));
536   std::size_t j(0);
537   for(std::size_t i=0;i<_fields.size();i++)
538     if(b[i])
539       fields[j++]=_fields[i];
540   _fields=fields;
541 }
542
543 bool MEDFileFields::changeMeshNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
544 {
545   bool ret(false);
546   for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::iterator it=_fields.begin();it!=_fields.end();it++)
547     {
548       MEDFileAnyTypeFieldMultiTSWithoutSDA *cur(*it);
549       if(cur)
550         ret=cur->changeMeshNames(modifTab) || ret;
551     }
552   return ret;
553 }
554
555 /*!
556  * \param [in] meshName the name of the mesh that will be renumbered.
557  * \param [in] oldCode is of format returned by MEDCouplingUMesh::getDistributionOfTypes. And for each *i* oldCode[3*i+2] gives the position (MEDFileUMesh::PutInThirdComponentOfCodeOffset).
558  *             This code corresponds to the distribution of types in the corresponding mesh.
559  * \param [in] newCode idem to param \a oldCode except that here the new distribution is given.
560  * \param [in] renumO2N the old to new renumber array.
561  * \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 referred by any 
562  *         field in \a this.
563  */
564 bool MEDFileFields::renumberEntitiesLyingOnMesh(const std::string& meshName, const std::vector<mcIdType>& oldCode, const std::vector<mcIdType>& newCode, const DataArrayIdType *renumO2N)
565 {
566   bool ret(false);
567   for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::iterator it=_fields.begin();it!=_fields.end();it++)
568     {
569       MEDFileAnyTypeFieldMultiTSWithoutSDA *fmts(*it);
570       if(fmts)
571         {
572           ret=fmts->renumberEntitiesLyingOnMesh(meshName,oldCode,newCode,renumO2N,*this) || ret;
573         }
574     }
575   return ret;
576 }
577
578 /*!
579  * Return an extraction of \a this using \a extractDef map to specify the extraction.
580  * The keys of \a extractDef is level relative to max ext of \a mm mesh.
581  *
582  * \return A new object that the caller is responsible to deallocate.
583  */
584 MEDFileFields *MEDFileFields::extractPart(const std::map<int, MCAuto<DataArrayIdType> >& extractDef, MEDFileMesh *mm) const
585 {
586   if(!mm)
587     throw INTERP_KERNEL::Exception("MEDFileFields::extractPart : input mesh is NULL !");
588   MCAuto<MEDFileFields> fsOut(MEDFileFields::New());
589   int nbFields(getNumberOfFields());
590   for(int i=0;i<nbFields;i++)
591     {
592       MCAuto<MEDFileAnyTypeFieldMultiTS> fmts(getFieldAtPos(i));
593       if(!fmts)
594         {
595           std::ostringstream oss; oss << "MEDFileFields::extractPart : at pos #" << i << " field is null !";
596           throw INTERP_KERNEL::Exception(oss.str());
597         }
598       MCAuto<MEDFileAnyTypeFieldMultiTS> fmtsOut(fmts->extractPart(extractDef,mm));
599       fsOut->pushField(fmtsOut);
600     }
601   return fsOut.retn();
602 }
603
604 void MEDFileFields::accept(MEDFileFieldVisitor& visitor) const
605 {
606   for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++)
607     if((*it).isNotNull())
608       {
609         visitor.newFieldEntry(*it);
610         (*it)->accept(visitor);
611         visitor.endFieldEntry(*it);
612       }
613 }
614
615 class PFLData
616 {
617 public:
618   PFLData():_add_pts_in_pfl(0) { }
619   PFLData(const MCAuto<DataArrayIdType>& mat, const MCAuto<DataArrayIdType>& pfl, mcIdType nbOfNewPts):_matrix(mat),_pfl(pfl),_add_pts_in_pfl(nbOfNewPts) { }
620   std::string getPflName() const { if(_pfl.isNull()) { return std::string(); } else { return _pfl->getName(); } }
621   mcIdType getNbOfAddPtsInPfl() const { return _add_pts_in_pfl; }
622   MCAuto<DataArrayIdType> getProfile() const { return _pfl; }
623   MCAuto<DataArrayIdType> getMatrix() const { return _matrix; }
624 private:
625   MCAuto<DataArrayIdType> _matrix;
626   MCAuto<DataArrayIdType> _pfl;
627   mcIdType _add_pts_in_pfl;
628 };
629
630 class MEDFileFieldLin2QuadVisitor : public MEDFileFieldVisitor
631 {
632 public:
633   MEDFileFieldLin2QuadVisitor(const MEDFileUMesh *lin, const MEDFileUMesh *quad, const MEDFileFieldGlobsReal *linGlobs, MEDFileFields* outFs):_lin(lin),_quad(quad),_lin_globs(linGlobs),_out_fs(outFs),_gt(INTERP_KERNEL::NORM_ERROR),_1ts_update_requested(false) { }
634   void newFieldEntry(const MEDFileAnyTypeFieldMultiTSWithoutSDA *field) { if(field->getMeshName()!=_lin->getName()) return; _cur_fmts=MEDFileFieldMultiTS::New(); }
635   void endFieldEntry(const MEDFileAnyTypeFieldMultiTSWithoutSDA *field) { if(_cur_fmts.isNotNull()) { if(_cur_fmts->getNumberOfTS()>0) _out_fs->pushField(_cur_fmts); } }
636   //
637   void newTimeStepEntry(const MEDFileAnyTypeField1TSWithoutSDA *ts);
638   void endTimeStepEntry(const MEDFileAnyTypeField1TSWithoutSDA *ts);
639   //
640   void newMeshEntry(const MEDFileFieldPerMesh *fpm);
641   void endMeshEntry(const MEDFileFieldPerMesh *fpm) { }
642   //
643   void newPerMeshPerTypeEntry(const MEDFileFieldPerMeshPerTypeCommon *pmpt);
644   void endPerMeshPerTypeEntry(const MEDFileFieldPerMeshPerTypeCommon *pmpt) { }
645   //
646   void newPerMeshPerTypePerDisc(const MEDFileFieldPerMeshPerTypePerDisc *pmptpd);
647 private:
648   void updateData(MEDFileFieldPerMeshPerTypePerDisc *pmtd, mcIdType deltaNbNodes);
649 private:
650   const MEDFileUMesh *_lin;
651   const MEDFileUMesh *_quad;
652   const MEDFileFieldGlobsReal *_lin_globs;
653   MEDFileFields *_out_fs;
654   MCAuto<MEDFileFieldMultiTS> _cur_fmts;
655   MCAuto<MEDFileField1TS> _cur_f1ts;
656   INTERP_KERNEL::NormalizedCellType _gt;
657   // Info on 1TS modification
658   bool _1ts_update_requested;
659   // Cache of matrix to compute faster the values on newly created points
660   std::map< std::string, PFLData > _cache;
661   std::vector<std::string> _pfls_to_be_updated;
662 };
663
664 void MEDFileFieldLin2QuadVisitor::newPerMeshPerTypePerDisc(const MEDFileFieldPerMeshPerTypePerDisc *pmptpd)
665 {
666   if(_cur_f1ts.isNull())
667     return;
668   if(pmptpd->getType()!=ON_NODES)
669     throw INTERP_KERNEL::Exception("Not managed yet for ON_CELLS ON_GAUSS_NE and ON_GAUSS_PT");
670   _1ts_update_requested=true;
671   MEDFileAnyTypeField1TSWithoutSDA *ct(_cur_f1ts->contentNotNullBase());
672   int locId(pmptpd->getFather()->locIdOfLeaf(pmptpd));
673   MEDFileFieldPerMeshPerTypePerDisc *pmtdToModify(ct->getLeafGivenMeshAndTypeAndLocId(_lin->getName(),_gt,locId));
674   std::string pflName(pmptpd->getProfile());
675   _pfls_to_be_updated.push_back(pflName);
676   std::map< std::string, PFLData >::iterator itCache(_cache.find(pflName));
677   if(itCache!=_cache.end())
678     {
679       updateData(pmtdToModify,(*itCache).second.getNbOfAddPtsInPfl());
680       return ;
681     }
682   MCAuto<DataArrayIdType> pfl;
683   if(pflName.empty())
684     pfl=DataArrayIdType::Range(0,pmptpd->getNumberOfVals(),1);
685   else
686     pfl=_lin_globs->getProfile(pflName)->deepCopy();
687   //
688   MCAuto<MEDCouplingUMesh> mesh3D(_lin->getMeshAtLevel(0)),mesh3DQuadratic(_quad->getMeshAtLevel(0));
689   MCAuto<DataArrayIdType> cellIds(mesh3D->getCellIdsLyingOnNodes(pfl->begin(),pfl->end(),true));
690   MCAuto<MEDCouplingUMesh> mesh3DQuadraticRestricted(mesh3DQuadratic->buildPartOfMySelf(cellIds->begin(),cellIds->end(),true));
691   MCAuto<DataArrayIdType> mesh3DQuadraticRestrictedNodeIds(mesh3DQuadraticRestricted->computeFetchedNodeIds());
692   mesh3DQuadraticRestrictedNodeIds->checkMonotonic(true);
693   MCAuto<DataArrayIdType> newPtsIds(mesh3DQuadraticRestrictedNodeIds->buildSubstraction(pfl));
694   MCAuto<MEDCoupling1SGTUMesh> allSeg3;
695   {
696     MCAuto<DataArrayIdType> a,b,c,d;
697     MCAuto<MEDCouplingUMesh> seg3Tmp(mesh3DQuadraticRestricted->explodeIntoEdges(a,b,c,d));
698     allSeg3=MEDCoupling1SGTUMesh::New(seg3Tmp);
699   }
700   if(allSeg3->getCellModelEnum()!=INTERP_KERNEL::NORM_SEG3)
701     throw INTERP_KERNEL::Exception("MEDFileFieldLin2QuadVisitor::newPerMeshPerTypePerDisc : invalid situation where SEG3 expected !");
702   MCAuto<DataArrayIdType> midPts,cellSeg3Ids,matrix;
703   {
704     DataArrayIdType *nodeConn(allSeg3->getNodalConnectivity());
705     nodeConn->rearrange(3);
706     {
707       std::vector<std::size_t> v(1,2);
708       midPts=nodeConn->keepSelectedComponents(v);
709     }
710     cellSeg3Ids=DataArrayIdType::FindPermutationFromFirstToSecond(midPts,newPtsIds);
711     {
712       std::vector<std::size_t> v(2); v[0]=0; v[1]=1;
713       MCAuto<DataArrayIdType> tmp(nodeConn->keepSelectedComponents(v));
714       matrix=tmp->selectByTupleId(cellSeg3Ids->begin(),cellSeg3Ids->end());
715     }
716     nodeConn->rearrange(1);
717   }
718   MCAuto<DataArrayIdType> pflq;
719   if(!pflName.empty())
720     {
721       std::vector<const DataArrayIdType *> vs(2);
722       vs[0]=pfl; vs[1]=newPtsIds;
723       pflq=DataArrayIdType::Aggregate(vs);
724       pflq->setName(pflName);
725     }
726   PFLData pdata(matrix,pflq,newPtsIds->getNumberOfTuples());
727   _cache[pflName]=pdata;
728   updateData(pmtdToModify,pdata.getNbOfAddPtsInPfl());
729 }
730
731 void MEDFileFieldLin2QuadVisitor::updateData(MEDFileFieldPerMeshPerTypePerDisc *pmtd, mcIdType deltaNbNodes)
732 {
733   pmtd->incrementNbOfVals(deltaNbNodes);
734 }
735
736 void MEDFileFieldLin2QuadVisitor::newPerMeshPerTypeEntry(const MEDFileFieldPerMeshPerTypeCommon *pmpt)
737 {
738   const MEDFileFieldPerMeshPerType *pmpt2(dynamic_cast<const MEDFileFieldPerMeshPerType *>(pmpt));
739   if(!pmpt2)
740     throw INTERP_KERNEL::Exception("MEDFileFieldLin2QuadVisitor::newPerMeshPerTypeEntry : not managed for structure elements !");
741   if(pmpt2->getNumberOfLoc()!=1)
742     throw INTERP_KERNEL::Exception("MEDFileFieldLin2QuadVisitor::newPerMeshPerTypeEntry : not managed for multi discr per timestep !");
743   _gt=pmpt->getGeoType();
744 }
745
746 void MEDFileFieldLin2QuadVisitor::newMeshEntry(const MEDFileFieldPerMesh *fpm)
747 {
748   if(fpm->getMeshName()!=_lin->getName())
749     throw INTERP_KERNEL::Exception("MEDFileFieldLin2QuadVisitor::newMeshEntry : mismatch into meshName !");
750 }
751
752 void MEDFileFieldLin2QuadVisitor::newTimeStepEntry(const MEDFileAnyTypeField1TSWithoutSDA *ts)
753 {
754   _1ts_update_requested=false; _pfls_to_be_updated.clear();
755   if(!ts)
756     return ;
757   const MEDFileField1TSWithoutSDA *tsd(dynamic_cast<const MEDFileField1TSWithoutSDA *>(ts));
758   if(!tsd)
759     return ;
760   MCAuto<MEDFileAnyTypeField1TSWithoutSDA> contentCpy(ts->deepCopy());
761   MCAuto<MEDFileField1TSWithoutSDA> contentCpy2(DynamicCastSafe<MEDFileAnyTypeField1TSWithoutSDA,MEDFileField1TSWithoutSDA>(contentCpy));
762   if(contentCpy2.isNull())
763     return;
764   _cur_f1ts=MEDFileField1TS::New(*contentCpy2,true);
765   _cur_f1ts->deepCpyGlobs(*_lin_globs);
766 }
767
768 void MEDFileFieldLin2QuadVisitor::endTimeStepEntry(const MEDFileAnyTypeField1TSWithoutSDA *ts)
769 {
770   if(_cur_f1ts.isNull())
771     return ;
772   if(_1ts_update_requested)
773     {
774       MCAuto<DataArrayIdType> matrix,oldPfl;
775       for(std::vector<std::string>::const_iterator it=_pfls_to_be_updated.begin();it!=_pfls_to_be_updated.end();it++)
776         {
777           std::map< std::string, PFLData >::const_iterator it2(_cache.find(*it));
778           if(it2==_cache.end())
779             throw INTERP_KERNEL::Exception("MEDFileFieldLin2QuadVisitor::endTimeStepEntry : invalid situation !");
780           matrix=(*it2).second.getMatrix();
781           if((*it).empty())
782             continue;
783           int locId(_cur_f1ts->getProfileId(*it));
784           oldPfl.takeRef(_cur_f1ts->getProfile(*it));
785           {
786             std::vector<int> locToKill(1,locId);
787             _cur_f1ts->killProfileIds(locToKill);
788           }
789           _cur_f1ts->appendProfile((*it2).second.getProfile());
790         }
791       DataArrayDouble *arr(_cur_f1ts->getUndergroundDataArray());
792       MCAuto<DataArrayDouble> res;
793       {
794         std::vector<std::size_t> v(1,0),v2(1,1);
795         MCAuto<DataArrayIdType> pts0(matrix->keepSelectedComponents(v));
796         MCAuto<DataArrayIdType> pts1(matrix->keepSelectedComponents(v2));
797         if(oldPfl.isNotNull())
798           {
799             pts0=oldPfl->findIdForEach(pts0->begin(),pts0->end());
800             pts1=oldPfl->findIdForEach(pts1->begin(),pts1->end());
801           }
802         MCAuto<DataArrayDouble> part0(arr->selectByTupleId(*pts0));
803         MCAuto<DataArrayDouble> part1(arr->selectByTupleId(*pts1));
804         res=DataArrayDouble::Add(part0,part1);
805         res->applyLin(0.5,0.);
806       }
807       res=DataArrayDouble::Aggregate(arr,res);
808       _cur_f1ts->setArray(res);
809     }
810   if(_cur_fmts.isNotNull())
811     { _cur_fmts->pushBackTimeStep(_cur_f1ts); }
812   _1ts_update_requested=false;
813 }
814
815 /*!
816  * \a newQuad is expected to be the result of MEDFileUMesh::linearToQuadratic of \a oldLin
817  */
818 MCAuto<MEDFileFields> MEDFileFields::linearToQuadratic(const MEDFileMeshes *oldLin, const MEDFileMeshes *newQuad) const
819 {
820   if(!oldLin || !newQuad)
821     throw INTERP_KERNEL::Exception("MEDFileFields::linearToQuadratic : input meshes must be non NULL !");
822   MCAuto<MEDFileFields> ret(MEDFileFields::New());
823   for(int i=0;i<oldLin->getNumberOfMeshes();i++)
824     {
825       MEDFileMesh *mm(oldLin->getMeshAtPos(i));
826       if(!mm)
827         continue;
828       MEDFileUMesh *mmu(dynamic_cast<MEDFileUMesh *>(mm));
829       if(!mmu)
830         continue;
831       MEDFileMesh *mmq(newQuad->getMeshWithName(mmu->getName()));
832       MEDFileUMesh *mmqu(dynamic_cast<MEDFileUMesh *>(mmq));
833       if(!mmqu)
834         {
835           std::ostringstream oss; oss << "MEDFileFields::linearToQuadratic : mismatch of name between input meshes for name \"" << mmu->getName() << "\"";
836           throw INTERP_KERNEL::Exception(oss.str());
837         }
838       MEDFileFieldLin2QuadVisitor vis(mmu,mmqu,this,ret);
839       accept(vis);
840     }
841   return ret;
842 }
843
844 MEDFileAnyTypeFieldMultiTS *MEDFileFields::getFieldAtPos(int i) const
845 {
846   if(i<0 || i>=(int)_fields.size())
847     {
848       std::ostringstream oss; oss << "MEDFileFields::getFieldAtPos : Invalid given id in input (" << i << ") should be in [0," << _fields.size() << ") !";
849       throw INTERP_KERNEL::Exception(oss.str());
850     }
851   const MEDFileAnyTypeFieldMultiTSWithoutSDA *fmts=_fields[i];
852   if(!fmts)
853     return 0;
854   MCAuto<MEDFileAnyTypeFieldMultiTS> ret;
855   const MEDFileFieldMultiTSWithoutSDA *fmtsC(dynamic_cast<const MEDFileFieldMultiTSWithoutSDA *>(fmts));
856   const MEDFileInt32FieldMultiTSWithoutSDA *fmtsC2(dynamic_cast<const MEDFileInt32FieldMultiTSWithoutSDA *>(fmts));
857   const MEDFileInt64FieldMultiTSWithoutSDA *fmtsC4(dynamic_cast<const MEDFileInt64FieldMultiTSWithoutSDA *>(fmts));
858   const MEDFileFloatFieldMultiTSWithoutSDA *fmtsC3(dynamic_cast<const MEDFileFloatFieldMultiTSWithoutSDA *>(fmts));
859   if(fmtsC)
860     ret=MEDFileFieldMultiTS::New(*fmtsC,false);
861   else if(fmtsC2)
862     ret=MEDFileInt32FieldMultiTS::New(*fmtsC2,false);
863   else if(fmtsC4)
864     ret=MEDFileInt64FieldMultiTS::New(*fmtsC4,false);
865   else if(fmtsC3)
866     ret=MEDFileFloatFieldMultiTS::New(*fmtsC3,false);
867   else
868     {
869       std::ostringstream oss; oss << "MEDFileFields::getFieldAtPos : At pos #" << i << " field is neither double (FLOAT64) nor float (FLOAT32) nor integer (INT32) nor integer (INT64) !";
870       throw INTERP_KERNEL::Exception(oss.str());
871     }
872   ret->shallowCpyGlobs(*this);
873   return ret.retn();
874 }
875
876 /*!
877  * Return a shallow copy of \a this reduced to the fields ids defined in [ \a startIds , endIds ).
878  * This method is accessible in python using __getitem__ with a list in input.
879  * \return a new object that the caller should deal with.
880  */
881 MEDFileFields *MEDFileFields::buildSubPart(const int *startIds, const int *endIds) const
882 {
883   MCAuto<MEDFileFields> ret=shallowCpy();
884   std::size_t sz=std::distance(startIds,endIds);
885   std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> > fields(sz);
886   int j=0;
887   for(const int *i=startIds;i!=endIds;i++,j++)
888     {
889       if(*i<0 || *i>=(int)_fields.size())
890         {
891           std::ostringstream oss; oss << "MEDFileFields::buildSubPart : Invalid given id in input (" << *i << ") should be in [0," << _fields.size() << ") !";
892           throw INTERP_KERNEL::Exception(oss.str());
893         }
894       fields[j]=_fields[*i];
895     }
896   ret->_fields=fields;
897   return ret.retn();
898 }
899
900 MEDFileAnyTypeFieldMultiTS *MEDFileFields::getFieldWithName(const std::string& fieldName) const
901 {
902   return getFieldAtPos(getPosFromFieldName(fieldName));
903 }
904
905 /*!
906  * This method removes, if any, fields in \a this having no time steps.
907  * 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.
908  * 
909  * If false is returned \a this does not contain such fields. If false is returned this method can be considered as const.
910  */
911 bool MEDFileFields::removeFieldsWithoutAnyTimeStep()
912 {
913   std::vector<MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> > newFields;
914   for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++)
915     {
916       const MEDFileAnyTypeFieldMultiTSWithoutSDA *elt(*it);
917       if(elt)
918         {
919           if(elt->getNumberOfTS()>0)
920             newFields.push_back(*it);
921         }
922     }
923   if(_fields.size()==newFields.size())
924     return false;
925   _fields=newFields;
926   return true;
927 }
928
929 /*!
930  * This method returns a new object containing part of \a this fields lying on mesh name specified by the input parameter \a meshName.
931  * This method can be seen as a filter applied on \a this, that returns an object containing
932  * 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
933  * shallow copied from \a this.
934  * 
935  * \param [in] meshName - the name of the mesh on w
936  * \return a new object that the caller should deal with.
937  */
938 MEDFileFields *MEDFileFields::partOfThisLyingOnSpecifiedMeshName(const std::string& meshName) const
939 {
940   MCAuto<MEDFileFields> ret(MEDFileFields::New());
941   for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++)
942     {
943       const MEDFileAnyTypeFieldMultiTSWithoutSDA *cur(*it);
944       if(!cur)
945         continue;
946       if(cur->getMeshName()==meshName)
947         {
948           cur->incrRef();
949           MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> cur2(const_cast<MEDFileAnyTypeFieldMultiTSWithoutSDA *>(cur));
950           ret->_fields.push_back(cur2);
951         }
952     }
953   ret->shallowCpyOnlyUsedGlobs(*this);
954   return ret.retn();
955 }
956
957 /*!
958  * This method returns a new object containing part of \a this fields lying ** exactly ** on the time steps specified by input parameter \a timeSteps.
959  * Input time steps are specified using a pair of integer (iteration, order).
960  * 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,
961  * but for each multitimestep only the time steps in \a timeSteps are kept.
962  * Typically the input parameter \a timeSteps comes from the call of MEDFileFields::getCommonIterations.
963  * 
964  * The returned object points to shallow copy of elements in \a this.
965  * 
966  * \param [in] timeSteps - the time steps given by a vector of pair of integers (iteration,order)
967  * \throw If there is a field in \a this that is \b not defined on a time step in the input \a timeSteps.
968  * \sa MEDFileFields::getCommonIterations, MEDFileFields::partOfThisNotLyingOnSpecifiedTimeSteps
969  */
970 MEDFileFields *MEDFileFields::partOfThisLyingOnSpecifiedTimeSteps(const std::vector< std::pair<int,int> >& timeSteps) const
971 {
972   MCAuto<MEDFileFields> ret(MEDFileFields::New());
973   for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++)
974     {
975       const MEDFileAnyTypeFieldMultiTSWithoutSDA *cur(*it);
976       if(!cur)
977         continue;
978       MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> elt=cur->partOfThisLyingOnSpecifiedTimeSteps(timeSteps);
979       ret->_fields.push_back(elt);
980     }
981   ret->shallowCpyOnlyUsedGlobs(*this);
982   return ret.retn();
983 }
984
985 /*!
986  * \sa MEDFileFields::getCommonIterations, MEDFileFields::partOfThisLyingOnSpecifiedTimeSteps
987  */
988 MEDFileFields *MEDFileFields::partOfThisNotLyingOnSpecifiedTimeSteps(const std::vector< std::pair<int,int> >& timeSteps) const
989 {
990   MCAuto<MEDFileFields> ret=MEDFileFields::New();
991   for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++)
992     {
993       const MEDFileAnyTypeFieldMultiTSWithoutSDA *cur(*it);
994       if(!cur)
995         continue;
996       MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> elt=cur->partOfThisNotLyingOnSpecifiedTimeSteps(timeSteps);
997       if(elt->getNumberOfTS()!=0)
998         ret->_fields.push_back(elt);
999     }
1000   ret->shallowCpyOnlyUsedGlobs(*this);
1001   return ret.retn();
1002 }
1003
1004 bool MEDFileFields::presenceOfStructureElements() const
1005 {
1006   for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++)
1007     if((*it).isNotNull())
1008       if((*it)->presenceOfStructureElements())
1009         return true;
1010   return false;
1011 }
1012
1013 void MEDFileFields::killStructureElements()
1014 {
1015   std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> > ret;
1016   for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::iterator it=_fields.begin();it!=_fields.end();it++)
1017     if((*it).isNotNull())
1018       {
1019         if((*it)->presenceOfStructureElements())
1020           {
1021             if(!(*it)->onlyStructureElements())
1022               {
1023                 (*it)->killStructureElements();
1024                 ret.push_back(*it);
1025               }
1026           }
1027         else
1028           {
1029             ret.push_back(*it);
1030           }
1031       }
1032   _fields=ret;
1033 }
1034
1035 void MEDFileFields::keepOnlyStructureElements()
1036 {
1037   std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> > ret;
1038   for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::iterator it=_fields.begin();it!=_fields.end();it++)
1039     if((*it).isNotNull())
1040       {
1041         if((*it)->presenceOfStructureElements())
1042           {
1043             if(!(*it)->onlyStructureElements())
1044               (*it)->keepOnlyStructureElements();
1045             ret.push_back(*it);
1046           }
1047       }
1048   _fields=ret;
1049 }
1050
1051 void MEDFileFields::keepOnlyOnMeshSE(const std::string& meshName, const std::string& seName)
1052 {
1053   std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> > ret;
1054   for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::iterator it=_fields.begin();it!=_fields.end();it++)
1055     if((*it).isNotNull())
1056       {
1057         if((*it)->getMeshName()!=meshName)
1058           continue;
1059         std::vector< std::pair<std::string,std::string> > ps;
1060         (*it)->getMeshSENames(ps);
1061         std::pair<std::string,std::string> p(meshName,seName);
1062         if(std::find(ps.begin(),ps.end(),p)!=ps.end())
1063           (*it)->keepOnlyOnSE(seName);
1064         ret.push_back(*it);
1065       }
1066   _fields=ret;
1067 }
1068
1069 void MEDFileFields::getMeshSENames(std::vector< std::pair<std::string,std::string> >& ps) const
1070 {
1071   for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++)
1072     if((*it).isNotNull())
1073       (*it)->getMeshSENames(ps);
1074 }
1075
1076 void MEDFileFields::blowUpSE(MEDFileMeshes *ms, const MEDFileStructureElements *ses)
1077 {
1078   MEDFileBlowStrEltUp::DealWithSE(this,ms,ses);
1079 }
1080
1081 MCAuto<MEDFileFields> MEDFileFields::partOfThisOnStructureElements() const
1082 {
1083   MCAuto<MEDFileFields> ret(deepCopy());
1084   ret->keepOnlyStructureElements();
1085   return ret;
1086 }
1087
1088 MCAuto<MEDFileFields> MEDFileFields::partOfThisLyingOnSpecifiedMeshSEName(const std::string& meshName, const std::string& seName) const
1089 {
1090   MCAuto<MEDFileFields> ret(deepCopy());
1091   ret->keepOnlyOnMeshSE(meshName,seName);
1092   return ret;
1093 }
1094
1095 void MEDFileFields::aggregate(const MEDFileFields& other)
1096 {
1097   int nbFieldsToAdd(other.getNumberOfFields());
1098   std::vector<std::string> fsn(getFieldsNames());
1099   for(int i=0;i<nbFieldsToAdd;i++)
1100     {
1101       MCAuto<MEDFileAnyTypeFieldMultiTS> elt(other.getFieldAtPos(i));
1102       std::string name(elt->getName());
1103       if(std::find(fsn.begin(),fsn.end(),name)!=fsn.end())
1104         {
1105           std::ostringstream oss; oss << "MEDFileFields::aggregate : name \"" << name << "\" already appears !";
1106           throw INTERP_KERNEL::Exception(oss.str());
1107         }
1108       pushField(elt);
1109     }
1110 }
1111
1112 MEDFileFieldsIterator *MEDFileFields::iterator()
1113 {
1114   return new MEDFileFieldsIterator(this);
1115 }
1116
1117 int MEDFileFields::getPosFromFieldName(const std::string& fieldName) const
1118 {
1119   std::string tmp(fieldName);
1120   std::vector<std::string> poss;
1121   for(unsigned int i=0;i<_fields.size();i++)
1122     {
1123       const MEDFileAnyTypeFieldMultiTSWithoutSDA *f(_fields[i]);
1124       if(f)
1125         {
1126           std::string fname(f->getName());
1127           if(tmp==fname)
1128             return i;
1129           else
1130             poss.push_back(fname);
1131         }
1132     }
1133   std::ostringstream oss; oss << "MEDFileFields::getPosFromFieldName : impossible to find field '" << tmp << "' in this ! Possibilities are : ";
1134   std::copy(poss.begin(),poss.end(),std::ostream_iterator<std::string>(oss,", "));
1135   oss << " !";
1136   throw INTERP_KERNEL::Exception(oss.str());
1137 }
1138
1139 MEDFileFieldsIterator::MEDFileFieldsIterator(MEDFileFields *fs):_fs(fs),_iter_id(0),_nb_iter(0)
1140 {
1141   if(fs)
1142     {
1143       fs->incrRef();
1144       _nb_iter=fs->getNumberOfFields();
1145     }
1146 }
1147
1148 MEDFileFieldsIterator::~MEDFileFieldsIterator() 
1149 {
1150 }
1151
1152 MEDFileAnyTypeFieldMultiTS *MEDFileFieldsIterator::nextt()
1153 {
1154   if(_iter_id<_nb_iter)
1155     {
1156       MEDFileFields *fs(_fs);
1157       if(fs)
1158         return fs->getFieldAtPos(_iter_id++);
1159       else
1160         return 0;
1161     }
1162   else
1163     return 0;
1164 }