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