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