Salome HOME
Message d'erreur en l'absence de fichier
[modules/smesh.git] / src / SMESH / MG_ADAPT.cxx
1 // Copyright (C) 2007-2020  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 // file : MG_ADAPT.cxx
22
23 #include "MG_ADAPT.hxx"
24
25 #include "MeshFormatReader.hxx"
26 #include "MeshFormatWriter.hxx"
27 #include "MEDFileMesh.hxx"
28 #include "MCAuto.hxx"
29 #include "MEDFileData.hxx"
30 #include "MEDFileField.hxx"
31 #include "MEDCouplingFieldDouble.hxx"
32
33 #include <SALOME_NamingService.hxx>
34 #include <Utils_SALOME_Exception.hxx>
35
36 #include <utilities.h>
37 #include <iostream>
38 #include <unistd.h>
39 #include <TCollection_AsciiString.hxx>
40 #include <cstring>
41 #include <cstdlib>
42 #include <boost/filesystem.hpp>
43
44 using namespace MG_ADAPT;
45 static std::string removeFile(std::string fileName, int& notOk)
46 {
47   std::string errStr;
48   notOk = std::remove(fileName.c_str());
49   if (notOk) errStr = ToComment("\n error while removing file : ") << fileName;
50         else errStr = ToComment("\n file : ") << fileName << " succesfully deleted! \n ";
51
52   return errStr;
53 }
54 std::string remove_extension(const std::string& filename) {
55   size_t lastdot = filename.find_last_of(".");
56   if (lastdot == std::string::npos) return filename;
57   return filename.substr(0, lastdot);
58 }
59 namespace
60 {
61 struct GET_DEFAULT // struct used to get default value from GetOptionValue()
62 {
63   bool isDefault;
64   operator bool* () {
65       return &isDefault;
66   }
67 };
68 }
69
70 //----------------------------------------------------------------------------------------
71 MgAdapt::MgAdapt()
72 {
73   data = new MgAdaptHypothesisData();
74   data->myInMeshName = "";
75   data->fromMedFile = defaultFromMedFile();
76   data->myFileInDir = defaultWorkingDirectory();
77   data->myMeshFileIn = "";
78   data->myFileOutDir = defaultWorkingDirectory();
79   data->myOutMeshName = "";
80   data->myMeshFileOut = "";
81   data->myMeshOutMed = defaultMeshOutMed();
82   data->myPublish = defaultPublish();
83   data->myUseLocalMap = defaultUseLocalMap();
84   data->myUseBackgroundMap = defaultUseBackgroundMap();
85   data->myFileSizeMapDir = defaultWorkingDirectory();
86   data->myMeshFileBackground = "";
87   data->myUseConstantValue = defaultUseConstantValue();
88   data->myConstantValue = 0.0;
89   data->myFieldName = "";
90   data->myUseNoTimeStep = defaultUseNoTimeStep();
91   data->myUseLastTimeStep = defaultUseLastTimeStep();
92   data->myUseChosenTimeStep = defaultUseChosenTimeStep();
93   data->myTimeStep = -2;
94   data->myRank =  -2;
95   data->myWorkingDir = defaultWorkingDirectory();
96   data->myLogFile = defaultLogFile();
97   data->myVerboseLevel = defaultVerboseLevel();
98   data->myPrintLogInFile = defaultPrintLogInFile();
99   data->myKeepFiles = defaultKeepFiles();
100   data->myRemoveLogOnSuccess = defaultRemoveLogOnSuccess();
101
102   buildModel();
103   setAll();
104 }
105 MgAdapt::MgAdapt(MgAdaptHypothesisData* myData)
106 {
107   data = new MgAdaptHypothesisData();
108   setData(myData);
109   buildModel();
110 }
111
112 MgAdapt::MgAdapt( const MgAdapt& copy)
113 {
114   data = new MgAdaptHypothesisData();
115   MgAdaptHypothesisData *copyData = copy.getData();
116   copyMgAdaptHypothesisData(copyData);
117   setAll();
118
119   this->_option2value = copy._option2value;
120   this->_customOption2value = copy._customOption2value;
121   this->_defaultOptionValues = copy._defaultOptionValues;
122   this->_doubleOptions = copy._doubleOptions;
123   this->_charOptions = copy._charOptions;
124   this->_boolOptions = copy._boolOptions;
125 }
126
127 //-----------------------------------------------------------------------------------------
128 MgAdapt::~MgAdapt()
129 {
130   delete data;
131 }
132 void MgAdapt::buildModel()
133 {
134
135   const char* boolOptionNames[] = { "compute_ridges",                          // yes
136                                     "" // mark of end
137                                   };
138   // const char* intOptionNames[] = { "max_number_of_errors_printed", // 1
139   //                                  "max_number_of_threads",        // 4
140   //                                  "" // mark of end
141   // };
142   const char* doubleOptionNames[] = { "max_memory",  // 0
143                                       "" // mark of end
144                                     };
145   const char* charOptionNames[] = { "components",                    // "yes"
146                                     "adaptation",            // both
147                                     "" // mark of end
148                                   };
149
150   int i = 0;
151   while (boolOptionNames[i][0])
152   {
153     _boolOptions.insert( boolOptionNames[i] );
154     _option2value[boolOptionNames[i++]].clear();
155   }
156   // i = 0;
157   // while (intOptionNames[i][0])
158   //   _option2value[intOptionNames[i++]].clear();
159
160   i = 0;
161   while (doubleOptionNames[i][0]) {
162     _doubleOptions.insert(doubleOptionNames[i]);
163     _option2value[doubleOptionNames[i++]].clear();
164   }
165   i = 0;
166   while (charOptionNames[i][0]) {
167     _charOptions.insert(charOptionNames[i]);
168     _option2value[charOptionNames[i++]].clear();
169   }
170
171   // default values to be used while MG-Adapt
172
173   _defaultOptionValues["adaptation"                         ] = "both";
174   _defaultOptionValues["components"                         ] = "outside components";
175   _defaultOptionValues["compute_ridges"                     ] = "yes";
176   _defaultOptionValues["max_memory"                         ] = ToComment(defaultMaximumMemory());
177 }
178
179 //=============================================================================
180 TOptionValues MgAdapt::getOptionValues() const
181 {
182   TOptionValues vals;
183   TOptionValues::const_iterator op_val = _option2value.begin();
184   for ( ; op_val != _option2value.end(); ++op_val )
185     vals.insert( make_pair( op_val->first, getOptionValue( op_val->first, GET_DEFAULT() )));
186
187   return vals;
188 }
189
190 std::vector <std::string> MgAdapt::getOptionValuesStrVec() const
191 {
192   std::vector <std::string> vals;
193   TOptionValues::const_iterator op_val = _option2value.begin();
194   for ( ; op_val != _option2value.end(); ++op_val )
195     vals.push_back(op_val->first+":"+getOptionValue( op_val->first, GET_DEFAULT() ));
196
197   return vals;
198 }
199
200 std::vector <std::string> MgAdapt::getCustomOptionValuesStrVec() const
201 {
202   std::vector <std::string> vals;
203   TOptionValues::const_iterator op_val;
204   for ( op_val = _customOption2value.begin(); op_val != _customOption2value.end(); ++op_val )
205   {
206     vals.push_back(op_val->first+":"+getOptionValue( op_val->first, GET_DEFAULT() ));
207   }
208   return vals;
209 }
210 const TOptionValues& MgAdapt::getCustomOptionValues() const
211 {
212   return _customOption2value;
213 }
214 void MgAdapt::setData(MgAdaptHypothesisData* myData)
215 {
216   copyMgAdaptHypothesisData(myData);
217   setAll();
218 }
219 MgAdaptHypothesisData* MgAdapt::getData() const
220 {
221   return data;
222 }
223 void MgAdapt::setMedFileIn(std::string fileName)
224 {
225   if ( isFileExist(fileName) )
226   {
227     medFileIn = fileName;
228
229     if (medFileOut == "") // default MED file Out
230       medFileOut = remove_extension( fileName )+ ".adapt.med";
231   }
232   else
233   {
234     std::cout << "\nThe file " + fileName + " does not exist.\n" << std::endl;
235 //     SALOME::ExceptionStruct es;
236 //     es.type = SALOME::BAD_PARAM;
237 //     std::string text = "\nThe file " + fileName + " does not exist.\n" ;
238 //     std::cout << text << std::endl;
239 //     es.text = "The mesh file does not exist.";
240 //     es.text = CORBA::string_dup(text.c_str());
241 //     throw SALOME::SALOME_Exception(es);
242     throw SALOME_Exception(("The file " + fileName + " does not exist." ).c_str() );
243   }
244 }
245
246 std::string MgAdapt::getMedFileIn()
247 {
248   return medFileIn;
249 }
250
251 void MgAdapt::setMedFileOut(std::string fileOut)
252 {
253   medFileOut = fileOut;
254 }
255 std::string MgAdapt::getMedFileOut()
256 {
257   return medFileOut;
258 }
259 void MgAdapt::setMeshOutMed(bool mybool)
260 {
261   meshOutMed = mybool;
262 }
263 bool MgAdapt::getMeshOutMed()
264 {
265   return meshOutMed;
266 }
267 void MgAdapt::setPublish(bool mybool)
268 {
269   publish = mybool;
270 }
271 bool MgAdapt::getPublish()
272 {
273   return publish;
274 }
275 void MgAdapt::setFieldName(std::string myFieldName)
276 {
277   fieldName = myFieldName;
278 }
279 std::string MgAdapt::getFieldName()
280 {
281   return fieldName;
282 }
283 void MgAdapt::setTimeStep(int time)
284 {
285   timeStep = time;
286 }
287 int MgAdapt::getTimeStep() const
288 {
289   return timeStep;
290 }
291
292 void MgAdapt::setRankTimeStep(int time, int myRank)
293 {
294   timeStep = time;
295   rank = myRank;
296 }
297
298 int MgAdapt::getRank()
299 {
300   return rank;
301 }
302 void MgAdapt::setTimeStepRankLast()
303 {
304   myUseLastTimeStep = true;
305   myUseChosenTimeStep = false;
306   myUseNoTimeStep = false;
307   //~med_int aRank, tmst;
308      //~std::string fieldFile = useBackgroundMap ? sizeMapFile : medFileIn;
309   //~getTimeStepInfos(fieldFile, tmst, aRank);
310   //~setRankTimeStep((int) tmst, (int) aRank);
311 }
312 void MgAdapt::setNoTimeStep()
313 {
314   myUseLastTimeStep = false;
315   myUseChosenTimeStep = false;
316   myUseNoTimeStep = true;
317   //~int aRank = (int)MED_NO_IT;
318   //~int tmst  = (int)MED_NO_DT ;
319   //~setRankTimeStep(tmst, aRank);
320 }
321 void MgAdapt::setChosenTimeStepRank()
322 {
323   myUseLastTimeStep = false;
324   myUseChosenTimeStep = true;
325   myUseNoTimeStep = false;
326   //~int aRank = (int)MED_NO_IT;
327   //~int tmst  = (int)MED_NO_DT ;
328   //~setRankTimeStep(tmst, aRank);
329 }
330 void MgAdapt::setUseLocalMap(bool myLocal)
331 {
332   useLocalMap = myLocal;
333 }
334
335 bool MgAdapt::getUseLocalMap()
336 {
337   return useLocalMap;
338 }
339
340 void MgAdapt::setUseBackgroundMap(bool bckg)
341 {
342   useBackgroundMap = bckg;
343 }
344
345 bool MgAdapt::getUseBackgroundMap()
346 {
347   return useBackgroundMap;
348 }
349
350 void MgAdapt::setUseConstantValue(bool cnst)
351 {
352   useConstantValue = cnst;
353 }
354 bool MgAdapt::getUseConstantValue()
355 {
356   return useConstantValue;
357 }
358 void MgAdapt::setLogFile(std::string myLogFile)
359 {
360   logFile = myLogFile;
361 }
362 std::string MgAdapt::getLogFile()
363 {
364   return logFile;
365 }
366 void MgAdapt::setVerbosityLevel(int verboLevel)
367 {
368   verbosityLevel = verboLevel;
369 }
370 int MgAdapt::getVerbosityLevel()
371 {
372   return verbosityLevel;
373 }
374 void MgAdapt::setRemoveOnSuccess(bool rmons)
375 {
376   removeOnSuccess = rmons;
377 }
378 bool MgAdapt::getRemoveOnSuccess()
379 {
380   return removeOnSuccess;
381 }
382 void MgAdapt::setSizeMapFile(std::string mapFile)
383 {
384   if ( mapFile == "" || isFileExist(mapFile) )
385   {
386     sizeMapFile = mapFile;
387   }
388   else
389   {
390     std::cout << "\nThe file " + mapFile + " does not exist.\n" << std::endl;
391     throw SALOME_Exception(("The file " + mapFile + " does not exist." ).c_str() );
392   }
393 }
394 std::string MgAdapt::getSizeMapFile()
395 {
396   return sizeMapFile;
397 }
398
399 void MgAdapt::setMeshName(std::string name)
400 {
401   meshName = name;
402 }
403 std::string MgAdapt::getMeshName()
404 {
405   return meshName;
406 }
407 void MgAdapt::setMeshNameOut(std::string name)
408 {
409   meshNameOut = name;
410 }
411 std::string MgAdapt::getMeshNameOut()
412 {
413   return meshNameOut;
414 }
415 void MgAdapt::setFromMedFile(bool mybool)
416 {
417   fromMedFile = mybool;
418 }
419 bool MgAdapt::isFromMedFile()
420 {
421   return fromMedFile;
422 }
423 void MgAdapt::setConstantValue(double cnst)
424 {
425   constantValue = cnst;
426 }
427 double MgAdapt::getConstantValue() const
428 {
429   return constantValue;
430 }
431
432 void MgAdapt::setWorkingDir(std::string dir)
433 {
434   workingDir = dir;
435 }
436 std::string MgAdapt::getWorkingDir() const
437 {
438   return workingDir;
439 }
440 void MgAdapt::setKeepWorkingFiles(bool mybool)
441 {
442   toKeepWorkingFiles = mybool;
443 }
444 bool MgAdapt::getKeepWorkingFiles()
445 {
446   return toKeepWorkingFiles;
447 }
448 void MgAdapt::setPrintLogInFile(bool print)
449 {
450   printLogInFile = print;
451 }
452 bool MgAdapt::getPrintLogInFile()
453 {
454   return printLogInFile;
455 }
456
457 bool MgAdapt::setAll()
458 {
459
460   setFromMedFile(data->fromMedFile);
461   std::string file;
462   checkDirPath(data->myFileInDir);
463   file = data->myFileInDir+data->myMeshFileIn;
464   setMedFileIn(file);
465   setMeshName(data->myInMeshName);
466   setMeshNameOut(data->myOutMeshName);
467   checkDirPath(data->myFileOutDir);
468   std::string out = data->myFileOutDir+data->myMeshFileOut;
469   setMedFileOut(out);
470   setPublish(data->myPublish);
471   setMeshOutMed(data->myMeshOutMed);
472   setUseLocalMap(data->myUseLocalMap);
473   setUseBackgroundMap(data->myUseBackgroundMap);
474   setUseConstantValue(data->myUseConstantValue);
475
476   std::string mapfile;
477   if (useBackgroundMap)
478   {
479     checkDirPath(data->myFileSizeMapDir);
480     mapfile = data->myFileSizeMapDir+data->myMeshFileBackground;
481     setFieldName(data->myFieldName);
482   }
483   else if (useConstantValue)
484   {
485     setConstantValue(data->myConstantValue);
486   }
487   else
488   {
489     mapfile ="";
490     setConstantValue(0.0);
491     setFieldName(data->myFieldName);
492   }
493
494   setSizeMapFile(mapfile);
495   if (data->myUseNoTimeStep)
496     setNoTimeStep();
497   else if (data->myUseLastTimeStep)
498     setTimeStepRankLast();
499   else
500   {
501     setChosenTimeStepRank();
502     setRankTimeStep(data->myTimeStep, data->myRank);
503   }
504   /* Advanced options */
505   setWorkingDir(data->myWorkingDir);
506   checkDirPath(data->myWorkingDir);
507   setLogFile(data->myWorkingDir+defaultLogFile());
508   setVerbosityLevel(data->myVerboseLevel);
509   setRemoveOnSuccess(data->myRemoveLogOnSuccess);
510   setPrintLogInFile(data->myPrintLogInFile);
511   setKeepWorkingFiles(data->myKeepFiles);
512
513   return true;
514 }
515
516 void MgAdapt::checkDirPath(std::string& dirPath)
517 {
518   const char lastChar = *dirPath.rbegin();
519 #ifdef WIN32
520   if(lastChar != '\\') dirPath+='\\';
521 #else
522   if(lastChar != '/') dirPath+='/';
523 #endif
524 }
525 //=============================================================================
526 void MgAdapt::setOptionValue(const std::string& optionName,
527                              const std::string& optionValue)
528 throw (std::invalid_argument)
529 {
530   TOptionValues::iterator op_val = _option2value.find(optionName);
531   if (op_val == _option2value.end())
532   {
533     op_val = _customOption2value.find( optionName );
534     _customOption2value[ optionName ] = optionValue;
535     return;
536   }
537
538   if (op_val->second != optionValue)
539   {
540
541     std::string lowerOptionValue = toLowerStr(optionValue);
542     const char* ptr = lowerOptionValue.c_str();
543     // strip white spaces
544     while (ptr[0] == ' ')
545       ptr++;
546     int i = strlen(ptr);
547     while (i != 0 && ptr[i - 1] == ' ')
548       i--;
549     // check value type
550     bool typeOk = true;
551     std::string typeName;
552     if (i == 0)
553     {
554       // empty string
555     }
556     else if (_charOptions.count(optionName))
557     {
558       // do not check strings
559     }
560     else if (_doubleOptions.count(optionName))
561     {
562       // check if value is double
563       toDbl(ptr, &typeOk);
564       typeName = "real";
565     }
566     else if (_boolOptions.count(optionName))
567     {
568       // check if value is bool
569       toBool(ptr, &typeOk);
570       typeName = "bool";
571     }
572     else
573     {
574       // check if value is int
575       toInt(ptr, &typeOk);
576       typeName = "integer";
577     }
578     if ( typeOk ) // check some specific values ?
579     {
580     }
581     if ( !typeOk )
582     {
583       std::string msg = "Advanced option '" + optionName + "' = '" + optionValue + "' but must be " + typeName;
584       throw std::invalid_argument(msg);
585     }
586     std::string value( ptr, i );
587     if ( _defaultOptionValues[ optionName ] == value ) value.clear();
588
589     op_val->second = value;
590
591   }
592 }
593 //=============================================================================
594 //! Return option value. If isDefault provided, it can be a default value,
595 //  then *isDefault == true. If isDefault is not provided, the value will be
596 //  empty if it equals a default one.
597 std::string MgAdapt::getOptionValue(const std::string& optionName, bool*              isDefault) const
598 throw (std::invalid_argument)
599 {
600   TOptionValues::const_iterator op_val = _option2value.find(optionName);
601   if (op_val == _option2value.end())
602   {
603     op_val = _customOption2value.find(optionName);
604     if (op_val == _customOption2value.end())
605     {
606       std::string msg = "Unknown MG-Adapt option: <" + optionName + ">";
607       throw std::invalid_argument(msg);
608     }
609   }
610   std::string val = op_val->second;
611   if ( isDefault ) *isDefault = ( val.empty() );
612
613   if ( val.empty() && isDefault )
614   {
615     op_val = _defaultOptionValues.find( optionName );
616     if (op_val != _defaultOptionValues.end()) val = op_val->second;
617   }
618   return val;
619 }
620 //================================================================================
621 /*!
622  * \brief Converts a string to a real value
623  */
624 //================================================================================
625
626 double MgAdapt::toDbl(const std::string& str, bool* isOk )
627 throw (std::invalid_argument)
628 {
629   if ( str.empty() ) throw std::invalid_argument("Empty value provided");
630
631   char * endPtr;
632   double val = strtod(&str[0], &endPtr);
633   bool ok = (&str[0] != endPtr);
634
635   if ( isOk ) *isOk = ok;
636
637   if ( !ok )
638   {
639     std::string msg = "Not a real value:'" + str + "'";
640     throw std::invalid_argument(msg);
641   }
642   return val;
643 }
644 //================================================================================
645 /*!
646  * \brief Converts a string to a lower
647  */
648 //================================================================================
649 std::string MgAdapt::toLowerStr(const std::string& str)
650 {
651   std::string s = str;
652   for ( size_t i = 0; i <= s.size(); ++i )
653     s[i] = tolower( s[i] );
654   return s;
655 }
656 //================================================================================
657 /*!
658  * \brief Converts a string to a bool
659  */
660 //================================================================================
661
662 bool MgAdapt::toBool(const std::string& str, bool* isOk )
663 throw (std::invalid_argument)
664 {
665   std::string s = str;
666   if ( isOk ) *isOk = true;
667
668   for ( size_t i = 0; i <= s.size(); ++i )
669     s[i] = tolower( s[i] );
670
671   if ( s == "1" || s == "true" || s == "active" || s == "yes" )
672     return true;
673
674   if ( s == "0" || s == "false" || s == "inactive" || s == "no" )
675     return false;
676
677   if ( isOk )
678     *isOk = false;
679   else
680   {
681     std::string msg = "Not a Boolean value:'" + str + "'";
682     throw std::invalid_argument(msg);
683   }
684   return false;
685 }
686 //================================================================================
687 /*!
688  * \brief Converts a string to a integer value
689  */
690 //================================================================================
691
692 int MgAdapt::toInt(const std::string& str, bool* isOk )
693 throw (std::invalid_argument)
694 {
695   if ( str.empty() ) throw std::invalid_argument("Empty value provided");
696
697   char * endPtr;
698   int val = (int)strtol( &str[0], &endPtr, 10);
699   bool ok = (&str[0] != endPtr);
700
701   if ( isOk ) *isOk = ok;
702
703   if ( !ok )
704   {
705     std::string msg = "Not an integer value:'" + str + "'";
706     throw std::invalid_argument(msg);
707   }
708   return val;
709 }
710 //=============================================================================
711 bool MgAdapt::hasOptionDefined( const std::string& optionName ) const
712 {
713   bool isDefault = false;
714   try
715   {
716     getOptionValue( optionName, &isDefault );
717   }
718   catch ( std::invalid_argument )
719   {
720     return false;
721   }
722   return !isDefault;
723 }
724 //================================================================================
725 /*!
726  * \brief Return command to run MG-Tetra mesher excluding file prefix (-f)
727  */
728 //================================================================================
729
730 std::string MgAdapt::getCommandToRun(MgAdapt* hyp)
731 {
732   return hyp ? hyp->getCommandToRun() : ToComment("error with hypothesis!");
733 }
734
735
736
737 int MgAdapt::compute(std::string& errStr)
738 {
739   std::string cmd = getCommandToRun();
740   int err = 0;
741   execCmd( cmd.c_str(), err ); // run
742
743   if ( err )
744   {
745     errStr = ToComment("system(mg-adapt.exe ...) command failed with error: ") << strerror( errno );
746   }
747   else
748   {
749     convertMeshFile(meshFormatOutputMesh, solFormatOutput);
750   }
751   if (!err) cleanUp();
752   return err;
753 }
754
755 void MgAdapt::execCmd( const char* cmd, int& err)
756 {
757   err = 1;
758   std::array <char, 128> buffer;
759   std::streambuf* buf;
760 outFileStream fileStream;
761   if (printLogInFile)
762   {
763   fileStream.open(logFile);
764   buf = fileStream.rdbuf();
765   }
766   else
767   {
768     buf = std::cout.rdbuf();
769   }
770   std::ostream logStream(buf);
771
772   std::unique_ptr <FILE, decltype(&pclose)> pipe(popen(cmd, "r"), pclose );
773   if(!pipe)
774   {
775     throw std::runtime_error("popen() failed!");
776   }
777   while(fgets(buffer.data(), buffer.size(), pipe.get()) !=nullptr )
778   {
779     logStream<<buffer.data() ;
780   }
781   err = 0;
782 }
783 /*
784  * to delete tmp files .mesh, .sol and if needed
785  * the log file
786  *
787  */
788 void MgAdapt::cleanUp()
789 {
790   int notOk;
791   std::string errStr;
792   if(toKeepWorkingFiles)
793     return;
794   if(removeOnSuccess && printLogInFile)
795     tmpFilesToBeDeleted.push_back(logFile);
796
797   std::vector< std::string>::iterator it = tmpFilesToBeDeleted.begin();
798   for (; it!=tmpFilesToBeDeleted.end(); ++it)
799   {
800     errStr=removeFile(*it, notOk);
801     if (notOk)
802     {
803       appendMsgToLogFile(errStr);
804     }
805
806   }
807 }
808
809 void MgAdapt::appendMsgToLogFile(std::string& msg)
810 {
811   std::ofstream logStream;
812   logStream.open(logFile, std::ofstream::out | std::ofstream::app);
813   logStream<< msg;
814   logStream.close();
815 }
816 //================================================================================
817 /*!
818  * \brief Return command to run MG-Tetra mesher excluding file prefix (-f)
819  */
820 //================================================================================
821
822 std::string MgAdapt::getCommandToRun()
823 {
824   /*
825   || return system command with args and options
826   ||
827   */
828   std::string errStr;
829   std::string cmd = getExeName();
830   std::string meshIn(""), sizeMapIn(""), solFileIn("");
831   updateTimeStepRank();
832   convertMedFile(meshIn, solFileIn, sizeMapIn);
833   if (!isFileExist(meshIn) || !isFileExist(solFileIn))
834   {
835     errStr = ToComment(" failed to find .mesh or .sol file from converter ")<< strerror( errno );
836     return errStr;
837   }
838   tmpFilesToBeDeleted.push_back(meshIn);
839   tmpFilesToBeDeleted.push_back(solFileIn);
840   if(useBackgroundMap && !isFileExist(sizeMapIn))
841   {
842     errStr = ToComment(" failed to find .mesh size map file from converter ")<< strerror( errno );
843     return errStr;
844   }
845
846   cmd+= " --in "+ meshIn;
847   meshFormatOutputMesh = getFileName()+".mesh";
848   tmpFilesToBeDeleted.push_back(meshFormatOutputMesh);
849   cmd+= " --out "+ meshFormatOutputMesh;
850   if (useLocalMap || useConstantValue) cmd+= " --sizemap "+ solFileIn;
851   else //  (useBackgroundMap)
852   {
853     cmd+= " --background_mesh "+ sizeMapIn ;
854     cmd+= " --background_sizemap "+ solFileIn;
855     tmpFilesToBeDeleted.push_back(sizeMapIn);
856   }
857   //~else
858   //~{
859       //~// constant value TODO
860   //~}
861   /* sizemap file is not adapted in case of only surface adaptation see MeshGems docs */
862   std::string adapOp   = "adaptation";
863   std::string adpOpVal = getOptionValue(adapOp);
864   std::string surfaceAdapt = "surface";
865   if(surfaceAdapt != adpOpVal )
866   {
867     std::string solFileOut = getFileName()+".sol";
868     cmd+= " --write_sizemap "+ solFileOut;
869     solFormatOutput.push_back(solFileOut);
870     tmpFilesToBeDeleted.push_back(solFileOut);
871   }
872   if (verbosityLevel != defaultVerboseLevel())
873   {
874     cmd+= " --verbose "+ ToComment(verbosityLevel);
875   }
876
877   std::string option, value;
878   bool isDefault;
879   const TOptionValues* options[] = { &_option2value, &_customOption2value };
880   for ( int iOp = 0; iOp < 2; ++iOp )
881   {
882     TOptionValues::const_iterator o2v = options[iOp]->begin();
883     for ( ; o2v != options[iOp]->end(); ++o2v )
884     {
885       option = o2v->first;
886       value = getOptionValue( option, &isDefault );
887
888       if ( isDefault )
889           continue;
890       if ( value.empty() )//value == NoValue() )
891       {
892         if ( _defaultOptionValues.count( option ))
893             continue; // non-custom option with no value
894         //value.clear();
895       }
896       if ( strncmp( "no", option.c_str(), 2 ) == 0 ) // options w/o values: --no_*
897       {
898         if ( !value.empty() && toBool( value ) == false )
899             continue;
900         value.clear();
901       }
902       if ( option[0] != '-' )
903         cmd += " --";
904       else
905         cmd += " ";
906       cmd += option + " " + value;
907     }
908   }
909     //~}
910 //~cmd+= " >"
911 #ifdef WIN32
912     cmd += " < NUL";
913 #endif
914
915   return cmd;
916 }
917
918 bool MgAdapt::isFileExist(const std::string& fName)
919 {
920
921   if ( fName.empty() ) return false;
922
923   boost::system::error_code err;
924   bool res = boost::filesystem::exists( fName, err );
925
926   return err ? false : res;
927 }
928 //=======================================================================
929 //function : defaultMaximumMemory
930 //=======================================================================
931
932 #if defined(WIN32)
933 #include <windows.h>
934 #elif !defined(__APPLE__)
935 #include <sys/sysinfo.h>
936 #endif
937
938 double MgAdapt::defaultMaximumMemory()
939 {
940 #if defined(WIN32)
941   // See http://msdn.microsoft.com/en-us/library/aa366589.aspx
942   MEMORYSTATUSEX statex;
943   statex.dwLength = sizeof (statex);
944   long err = GlobalMemoryStatusEx (&statex);
945   if (err != 0)
946   {
947     double totMB = (double)statex.ullAvailPhys / 1024. / 1024.;
948     return (double)( 0.7 * totMB );
949   }
950 #elif !defined(__APPLE__)
951   struct sysinfo si;
952   long err = sysinfo( &si );
953   if ( err == 0 )
954   {
955     long ramMB = si.totalram * si.mem_unit / 1024 / 1024;
956     return ( 0.7 * ramMB );
957   }
958 #endif
959   return 1024;
960 }
961
962 //=======================================================================
963 //function : defaultWorkingDirectory
964 //=======================================================================
965
966 std::string MgAdapt::defaultWorkingDirectory()
967 {
968   TCollection_AsciiString aTmpDir;
969
970   char *Tmp_dir = getenv("SALOME_TMP_DIR");
971   if(Tmp_dir != NULL)
972   {
973     aTmpDir = Tmp_dir;
974   }
975   else {
976 #ifdef WIN32
977     aTmpDir = TCollection_AsciiString("C:\\");
978 #else
979     aTmpDir = TCollection_AsciiString("/tmp/");
980 #endif
981   }
982   return aTmpDir.ToCString();
983 }
984 //================================================================================
985 /*!
986  * \brief Return a unique file name
987  */
988 //================================================================================
989
990 std::string MgAdapt::getFileName() const
991 {
992   std::string aTmpDir = workingDir;
993   const char lastChar = *aTmpDir.rbegin();
994 #ifdef WIN32
995   if(lastChar != '\\') aTmpDir+='\\';
996 #else
997   if(lastChar != '/') aTmpDir+='/';
998 #endif
999
1000   TCollection_AsciiString aGenericName = (char*)aTmpDir.c_str();
1001   aGenericName += "MgAdapt_";
1002   aGenericName += getpid();
1003   aGenericName += "_";
1004   aGenericName += Abs((Standard_Integer)(long) aGenericName.ToCString());
1005
1006   return aGenericName.ToCString();
1007 }
1008 //=======================================================================
1009 //function : defaultLogFile
1010 //=======================================================================
1011
1012 std::string MgAdapt::defaultLogFile()
1013 {
1014   std::string alogFile("MG_ADAPT.log");
1015   return alogFile;
1016 }
1017 //=======================================================================
1018 //function : defaultUseConstantValue
1019 //=======================================================================
1020
1021 bool MgAdapt::defaultUseConstantValue()
1022 {
1023   return false;
1024 }
1025 //=======================================================================
1026 //function : defaultUseNoTimeStep
1027 //=======================================================================
1028
1029 bool MgAdapt::defaultUseNoTimeStep()
1030 {
1031   return true;
1032 }
1033 //=======================================================================
1034 //function : defaultRemoveLogOnSuccess
1035 //=======================================================================
1036
1037 bool MgAdapt::defaultRemoveLogOnSuccess()
1038 {
1039   return true;
1040 }
1041 //=======================================================================
1042 //function : defaultPrintLogInFile
1043 //=======================================================================
1044
1045 bool MgAdapt::defaultPrintLogInFile()
1046 {
1047   return false;
1048 }
1049 //=======================================================================
1050 //function : defaultUseChosenTimeStep
1051 //=======================================================================
1052
1053 bool MgAdapt::defaultUseChosenTimeStep()
1054 {
1055   return false;
1056 }
1057 //=======================================================================
1058 //function : UseLastTimeStep
1059 //=======================================================================
1060
1061 bool MgAdapt::defaultUseLastTimeStep()
1062 {
1063   return false;
1064 }
1065 //=======================================================================
1066 //function : defaultUseBackgroundMap
1067 //=======================================================================
1068
1069 bool MgAdapt::defaultUseBackgroundMap()
1070 {
1071   return false;
1072 }
1073 //=======================================================================
1074 //function : defaultKeepFiles
1075 //=======================================================================
1076
1077 bool MgAdapt::defaultKeepFiles()
1078 {
1079   return false;
1080 }
1081 //=======================================================================
1082 //function : defaultUseLocalMap
1083 //=======================================================================
1084
1085 bool MgAdapt::defaultUseLocalMap()
1086 {
1087   return true;
1088 }
1089 //=======================================================================
1090 //function : defaultPublish
1091 //=======================================================================
1092
1093 bool MgAdapt::defaultPublish()
1094 {
1095   return false;
1096 }
1097 //=======================================================================
1098 //function : defaultMeshOutMed
1099 //=======================================================================
1100
1101 bool MgAdapt::defaultMeshOutMed()
1102 {
1103   return true;
1104 }
1105 //=======================================================================
1106 //function : defaultFromMedFile
1107 //=======================================================================
1108
1109 bool MgAdapt::defaultFromMedFile()
1110 {
1111   return true;
1112 }
1113 //=======================================================================
1114 //function : defaultVerboseLevel
1115 //=======================================================================
1116
1117 int  MgAdapt::defaultVerboseLevel()
1118 {
1119   return 3;
1120 }
1121 std::string MgAdapt::getExeName()
1122 {
1123   return "mg-adapt.exe";
1124 }
1125 void MgAdapt::copyMgAdaptHypothesisData( const MgAdaptHypothesisData* from)
1126 {
1127   data->myFileInDir = from->myFileInDir;
1128   data->myMeshFileIn = from->myMeshFileIn;
1129   data->myMeshFileBackground = from->myMeshFileBackground;
1130   data->myOutMeshName = from->myOutMeshName;
1131   data->myMeshFileOut = from->myMeshFileOut;
1132   data->myFileOutDir = from->myFileOutDir;
1133   data->myFileSizeMapDir = from->myFileSizeMapDir;
1134   data->myFieldName = from->myFieldName;
1135   data->fromMedFile = from->fromMedFile;
1136   data->myPublish = from->myPublish;
1137   data->myMeshOutMed = from->myMeshOutMed;
1138   data->myUseLocalMap = from->myUseLocalMap;
1139   data->myUseBackgroundMap = from->myUseBackgroundMap;
1140   data->myUseConstantValue = from->myUseConstantValue;
1141   data->myConstantValue = from->myConstantValue;
1142   data->myTimeStep = from->myTimeStep;
1143   data->myRank = from->myRank;
1144   data->myUseNoTimeStep = from->myUseNoTimeStep;
1145   data->myUseLastTimeStep = from->myUseLastTimeStep;
1146   data->myUseChosenTimeStep = from->myUseChosenTimeStep;
1147   data->myWorkingDir = from->myWorkingDir;
1148   data->myLogFile = from->myLogFile;
1149   data->myPrintLogInFile = from->myPrintLogInFile;
1150   data->myKeepFiles = from->myKeepFiles;
1151   data->myRemoveLogOnSuccess = from->myRemoveLogOnSuccess;
1152   data->myVerboseLevel = from->myVerboseLevel;
1153 }
1154
1155
1156 void MgAdapt::convertMedFile(std::string& meshFormatMeshFileName, std::string& solFormatFieldFileName, std::string& meshFormatsizeMapFile)
1157 {
1158   std::vector<std::string> fieldFileNames;
1159   MEDCoupling::MeshFormatWriter writer;
1160   MEDCoupling::MCAuto<MEDCoupling::MEDFileData> mfd = MEDCoupling::MEDFileData::New(medFileIn);
1161   MEDCoupling::MEDFileMeshes* meshes = mfd->getMeshes();
1162   MEDCoupling::MEDFileMesh* fileMesh = meshes->getMeshAtPos(0); // ok only one mesh in file!
1163   if (meshNameOut =="")
1164       meshNameOut = fileMesh->getName();
1165   storeGroupsAndFams(fileMesh);
1166
1167   MEDCoupling::MCAuto<MEDCoupling::MEDFileFields> fields = MEDCoupling::MEDFileFields::New();
1168   solFormatFieldFileName = getFileName();
1169   solFormatFieldFileName+=".sol";
1170   fieldFileNames.push_back(solFormatFieldFileName);
1171
1172   if (useBackgroundMap)
1173   {
1174     meshFormatsizeMapFile = getFileName();
1175     meshFormatsizeMapFile += ".mesh";
1176     buildBackGroundMeshAndSolFiles(fieldFileNames, meshFormatsizeMapFile);
1177   }
1178   else if(useLocalMap)
1179   {
1180     MEDCoupling::MCAuto<MEDCoupling::MEDFileAnyTypeFieldMultiTS> fts = dynamic_cast<MEDCoupling::MEDFileFieldMultiTS *>( mfd->getFields()->getFieldWithName(fieldName) );
1181     MEDCoupling::MCAuto<MEDCoupling::MEDFileAnyTypeField1TS> f = fts->getTimeStep(timeStep, rank);
1182     MEDCoupling::MCAuto<MEDCoupling::MEDFileFieldMultiTS> tmFts = MEDCoupling::MEDFileFieldMultiTS::New();
1183     tmFts->pushBackTimeStep(f);
1184
1185     fields->pushField(tmFts);
1186
1187     writer.setFieldFileNames( fieldFileNames);
1188   }
1189   else
1190   {
1191     MEDCoupling::MCAuto<MEDCoupling::MEDCouplingMesh> mesh = fileMesh->getMeshAtLevel(1); // nodes mesh
1192     MEDCoupling::MCAuto<MEDCoupling::MEDCouplingUMesh> umesh = mesh->buildUnstructured(); // nodes mesh
1193     int dim  =  umesh->getSpaceDimension();
1194     int version =  sizeof(double) < 8 ? 1 : 2;
1195     mcIdType nbNodes =  umesh->getNumberOfNodes();
1196     buildConstantSizeMapSolFile(solFormatFieldFileName, dim, version, nbNodes);
1197   }
1198
1199   mfd->setFields( fields );
1200   meshFormatMeshFileName = getFileName();
1201   meshFormatMeshFileName+=".mesh";
1202   writer.setMeshFileName(meshFormatMeshFileName);
1203   writer.setMEDFileDS( mfd);
1204   writer.write();
1205
1206 }
1207
1208 void MgAdapt::convertMeshFile(std::string& meshFormatIn, std::vector< std::string>& solFieldFileNames) const
1209 {
1210   MEDCoupling::MeshFormatReader reader(meshFormatIn, solFieldFileNames);
1211
1212   MEDCoupling::MCAuto<MEDCoupling::MEDFileData> mfd = reader.loadInMedFileDS();
1213   // write MED
1214   MEDCoupling::MEDFileMeshes* meshes = mfd->getMeshes();
1215   MEDCoupling::MEDFileMesh* fileMesh = meshes->getMeshAtPos(0); // ok only one mesh in file!
1216   fileMesh->setName(meshNameOut);
1217   restoreGroupsAndFams(fileMesh);
1218   mfd->write(medFileOut, 2);
1219 }
1220
1221 void MgAdapt::storeGroupsAndFams(MEDCoupling::MEDFileMesh* fileMesh)
1222 {
1223   storefams(fileMesh);
1224   storeGroups(fileMesh);
1225 }
1226
1227 void MgAdapt::restoreGroupsAndFams(MEDCoupling::MEDFileMesh* fileMesh) const
1228 {
1229   restorefams(fileMesh);
1230   restoreGroups(fileMesh);
1231 }
1232 void MgAdapt::storeGroups(MEDCoupling::MEDFileMesh* fileMesh)
1233 {
1234   std::map<std::string, std::vector<std::string> > grpFams = fileMesh->getGroupInfo();
1235   std::map<std::string, std::vector<std::string> >::iterator g2ff = grpFams.begin();
1236
1237   for ( ; g2ff != grpFams.end(); ++g2ff )
1238   {
1239     std::string        groupName = g2ff->first;
1240     std::vector<std::string> famNames = g2ff->second;
1241
1242     if ( famNames.empty() ) continue;
1243     std::size_t k = 0;
1244     std::vector< mcIdType> famListId;
1245     for ( size_t i = 0; i < famNames.size(); ++i )
1246     {
1247       famListId.push_back( fileMesh->getFamilyId( famNames[i].c_str() ) );
1248     }
1249     group grp(groupName, famListId, famNames);
1250     groupVec.push_back(grp);
1251   }
1252 }
1253
1254 void MgAdapt::storefams(MEDCoupling::MEDFileMesh* fileMesh)
1255 {
1256   std::map<std::string, mcIdType> grpFams = fileMesh->getFamilyInfo();
1257   std::map<std::string, mcIdType >::iterator f = grpFams.begin();
1258
1259   for ( ; f != grpFams.end(); ++f )
1260   {
1261     if(!f->second) continue;  // FAMILLE_ZERO
1262     family fs(f->first, f->second);
1263     famVec.push_back(fs);
1264   }
1265
1266 }
1267
1268 void MgAdapt::restorefams(MEDCoupling::MEDFileMesh* fileMesh) const
1269 {
1270   std::vector<family>::const_iterator fIt = famVec.begin();
1271
1272   for (; fIt!=famVec.end(); ++fIt)
1273   {
1274     try  //
1275     {
1276       std::string givenFamNameFromMeshGemConverter = fileMesh->getFamilyNameGivenId( std::abs(fIt->_famId) );
1277       fileMesh->changeFamilyId(std::abs(fIt->_famId), fIt->_famId);
1278       fileMesh->changeFamilyName(givenFamNameFromMeshGemConverter, fIt->_famName);
1279     }
1280     catch (const std::exception& e)
1281     {
1282       std::cerr<<e.what();
1283     }
1284   }
1285 }
1286
1287 void MgAdapt::restoreGroups(MEDCoupling::MEDFileMesh* fileMesh) const
1288 {
1289   std::map<std::string, std::vector<std::string> > info;
1290   std::vector <group>::const_iterator grpFams = groupVec.begin();
1291
1292   for (; grpFams!=groupVec.end(); ++grpFams)
1293   {
1294     info.insert(std::pair <std::string, std::vector<std::string> > (grpFams->_name, grpFams->_famNames) );
1295   }
1296
1297   fileMesh->setGroupInfo(info);
1298 }
1299
1300 void MgAdapt::buildConstantSizeMapSolFile(const std::string& solFormatFieldFileName, const int dim, const int version, const mcIdType nbNodes) const
1301 {
1302   MeshFormat::Localizer loc;
1303   MeshFormat::MeshFormatParser writer;
1304   int fileId = writer.GmfOpenMesh( solFormatFieldFileName.c_str(), GmfWrite, version, dim);
1305   int typTab[] = {GmfSca};
1306   writer.GmfSetKwd(fileId, MeshFormat::GmfSolAtVertices, (int)nbNodes, 1, typTab);
1307   for (mcIdType i = 0; i<nbNodes; i++)
1308   {
1309     double valTab[1] = {constantValue};
1310     writer.GmfSetLin( fileId, MeshFormat::GmfSolAtVertices, valTab);
1311   }
1312   writer.GmfCloseMesh(fileId);
1313 }
1314
1315 void MgAdapt::buildBackGroundMeshAndSolFiles(const std::vector<std::string>& fieldFileNames, const std::string& meshFormatsizeMapFile) const
1316 {
1317   MEDCoupling::MCAuto<MEDCoupling::MEDFileData> tmpMfd = MEDCoupling::MEDFileData::New(sizeMapFile);
1318   MEDCoupling::MEDFileFields* tmpFields = tmpMfd->getFields();
1319   MEDCoupling::MEDFileAnyTypeFieldMultiTS* fts = tmpFields->getFieldWithName(fieldName);
1320   MEDCoupling::MCAuto<MEDCoupling::MEDFileFieldMultiTS>  fts1 = dynamic_cast<MEDCoupling::MEDFileFieldMultiTS *>(fts);
1321   MEDCoupling::MCAuto<MEDCoupling::MEDFileAnyTypeField1TS> f = fts1->getTimeStep(timeStep, rank);
1322   MEDCoupling::MCAuto<MEDCoupling::MEDFileFieldMultiTS> tmFts = MEDCoupling::MEDFileFieldMultiTS::New();
1323   tmFts->pushBackTimeStep(f);
1324
1325   MEDCoupling::MCAuto<MEDCoupling::MEDFileFields> tmp_fields = MEDCoupling::MEDFileFields::New();
1326   tmp_fields->pushField(tmFts);
1327
1328   tmpMfd->setFields( tmp_fields );
1329   MEDCoupling::MeshFormatWriter tmpWriter;
1330   tmpWriter.setMeshFileName(meshFormatsizeMapFile);
1331   tmpWriter.setFieldFileNames( fieldFileNames);
1332   tmpWriter.setMEDFileDS(tmpMfd);
1333   tmpWriter.write();
1334 }
1335 // =======================================================================
1336 med_idt MgAdapt::openMedFile(const std::string aFile)
1337 // =======================================================================
1338 // renvoie le medId associe au fichier Med apres ouverture
1339 {
1340   med_idt medIdt = MEDfileOpen(aFile.c_str(),MED_ACC_RDONLY);
1341   if (medIdt <0)
1342   {
1343     SALOME::ExceptionStruct es;
1344     es.type = SALOME::BAD_PARAM;
1345     std::string text = "The med file " + aFile + " cannot be opened." ;
1346 //     es.text = "The mesh file does not exist.";
1347     es.text = CORBA::string_dup(text.c_str());
1348     throw SALOME::SALOME_Exception(es);
1349     return 0;
1350   }
1351   return medIdt;
1352 }
1353
1354 MgAdapt::Status MgAdapt::addMessage(const std::string& msg,
1355                                   const bool         isFatal/*=false*/)
1356 {
1357   if ( isFatal )
1358     _myErrorMessages.clear(); // warnings are useless if a fatal error encounters
1359
1360   _myErrorMessages.push_back( msg );
1361
1362 //~MESSAGE(msg);
1363 #ifdef _DEBUG_
1364   std::cout << msg << std::endl;
1365 #endif
1366   return ( _myStatus = isFatal ? MgAdapt::DRS_FAIL : MgAdapt::DRS_WARN_SKIP_ELEM );
1367 }
1368
1369 // =======================================================================
1370 void MgAdapt::getTimeStepInfos(std::string aFile, med_int& numdt, med_int& numit)
1371 // =======================================================================
1372 {
1373 // Il faut voir si plusieurs maillages
1374
1375   herr_t erreur = 0 ;
1376   med_idt medIdt ;
1377
1378
1379   // Ouverture du fichier
1380   //~SCRUTE(aFile.toStdString());
1381   medIdt = openMedFile(aFile);
1382   if ( medIdt < 0 ) return ;
1383   // Lecture du nombre de champs
1384   med_int ncha = MEDnField(medIdt) ;
1385   if (ncha < 1 )
1386   {
1387     //~addMessage( ToComment(" error: there is no field in  ") << aFile, /*fatal=*/true );
1388     return;
1389   }
1390   // Lecture des caracteristiques du champs
1391
1392   //       Lecture du type du champ, des noms des composantes et du nom de l'unite
1393   char nomcha  [MED_NAME_SIZE+1];
1394   strcpy(nomcha, fieldName.c_str());
1395 //       Lecture du nombre de composantes
1396   med_int ncomp = MEDfieldnComponentByName(medIdt, nomcha);
1397   char meshname[MED_NAME_SIZE+1];
1398   char * comp = (char*) malloc(ncomp*MED_SNAME_SIZE+1);
1399   char * unit = (char*) malloc(ncomp*MED_SNAME_SIZE+1);
1400   char dtunit[MED_SNAME_SIZE+1];
1401   med_bool local;
1402   med_field_type typcha;
1403   med_int nbofcstp;
1404   erreur =  MEDfieldInfoByName (medIdt, nomcha, meshname,&local,&typcha,comp,unit,dtunit, &nbofcstp);
1405   free(comp);
1406   free(unit);
1407   if ( erreur < 0 )
1408   {
1409       //~addMessage( ToComment(" error: error while reading field  ") << nomcha << " in file " << aFile , /*fatal=*/true );
1410     return;
1411   }
1412
1413   med_float dt;
1414   med_int tmp_numdt, tmp_numit;
1415
1416   //~med_int step = data->myUseLastTimeStep ? nbofcstp : data->myTimeStep+1;
1417   //~myPrint("step ", step);
1418   erreur = MEDfieldComputingStepInfo ( medIdt, nomcha, 1, &numdt, &numit, &dt );
1419   for(med_int step = 1; step <= nbofcstp; step++ )
1420   {
1421     erreur = MEDfieldComputingStepInfo ( medIdt, nomcha, step, &tmp_numdt, &tmp_numit, &dt );
1422     if(tmp_numdt > numdt)
1423     {
1424       numdt = tmp_numdt;
1425       numit = tmp_numit;
1426     }
1427   }
1428   if ( erreur < 0 )
1429   {
1430     //~addMessage( ToComment(" error: error while reading field ") << nomcha << "step (numdt, numit) = " <<"("<< numdt<< ", " \
1431     numit<< ")" <<" in file " << aFile , /*fatal=*/true );
1432     return;
1433   }
1434
1435   // Fermeture du fichier
1436   if ( medIdt > 0 ) MEDfileClose(medIdt);
1437
1438 }
1439
1440 void MgAdapt::updateTimeStepRank()
1441 {
1442
1443   med_int arank;
1444   med_int tmst;
1445   if (myUseNoTimeStep)
1446   {
1447     arank = MED_NO_IT;
1448     tmst  = MED_NO_DT ;
1449     setRankTimeStep((int)tmst, (int)arank);
1450   }
1451   else if (myUseLastTimeStep)
1452   {
1453     std::string fieldFile = useBackgroundMap ? sizeMapFile : medFileIn;
1454     getTimeStepInfos(fieldFile, tmst, arank);
1455     setRankTimeStep((int)tmst, (int)arank);
1456   }
1457 }