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