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