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