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