1 // Copyright (C) 2020-2021 CEA/DEN, EDF R&D
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.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #include "MG_ADAPT.hxx"
22 #include <DriverGMF_Read.hxx>
23 #include <SMESH_Comment.hxx>
24 #include <SMESH_File.hxx>
25 #include <SMESH_MGLicenseKeyGen.hxx>
26 #include <SMESH_TypeDefs.hxx>
28 #include <MEDFileData.hxx>
29 #include <MEDFileField.hxx>
30 #include <MEDFileMesh.hxx>
31 #include <MeshFormatReader.hxx>
32 #include <MeshFormatWriter.hxx>
34 #include <Utils_SALOME_Exception.hxx>
35 #include <Basics_Utils.hxx>
38 #include <unistd.h> // getpid()
44 #include <memory> // unique_ptr
46 typedef SMESH_Comment ToComment;
48 using namespace MG_ADAPT;
49 static std::string removeFile(std::string fileName, int& notOk)
52 notOk = std::remove(fileName.c_str());
53 if (notOk) errStr = ToComment("\n error while removing file : ") << fileName;
54 else errStr = ToComment("\n file : ") << fileName << " succesfully deleted! \n ";
58 std::string MG_ADAPT::remove_extension(const std::string& filename)
60 size_t lastdot = filename.find_last_of(".");
61 if (lastdot == std::string::npos) return filename;
62 return filename.substr(0, lastdot);
67 bool isFileExist( const std::string& fName )
69 return SMESH_File( fName ).exists();
72 // =======================================================================
73 med_idt openMedFile(const std::string aFile)
74 // =======================================================================
75 // renvoie le medId associe au fichier Med apres ouverture
77 med_idt medIdt = MEDfileOpen(aFile.c_str(),MED_ACC_RDONLY);
80 THROW_SALOME_EXCEPTION("\nThe med file " << aFile << " cannot be opened.\n");
85 // =======================================================================
86 void getTimeStepInfos(std::string aFile, med_int& numdt, med_int& numit, std::string fieldName)
87 // =======================================================================
89 // Il faut voir si plusieurs maillages
94 // Ouverture du fichier
95 //~SCRUTE(aFile.toStdString());
96 medIdt = openMedFile(aFile);
97 if ( medIdt < 0 ) return ;
98 // Lecture du nombre de champs
99 med_int ncha = MEDnField(medIdt) ;
102 //~addMessage( ToComment(" error: there is no field in ") << aFile, /*fatal=*/true );
105 // Lecture des caracteristiques du champs
107 // Lecture du type du champ, des noms des composantes et du nom de l'unite
108 char nomcha [MED_NAME_SIZE+1];
109 strcpy(nomcha, fieldName.c_str());
110 // Lecture du nombre de composantes
111 med_int ncomp = MEDfieldnComponentByName(medIdt, nomcha);
112 char meshname[MED_NAME_SIZE+1];
113 char * comp = (char*) malloc(ncomp*MED_SNAME_SIZE+1);
114 char * unit = (char*) malloc(ncomp*MED_SNAME_SIZE+1);
115 char dtunit[MED_SNAME_SIZE+1];
117 med_field_type typcha;
119 erreur = MEDfieldInfoByName (medIdt, nomcha, meshname,&local,&typcha,comp,unit,dtunit, &nbofcstp);
124 //~addMessage( ToComment(" error: error while reading field ") << nomcha << " in file " << aFile , /*fatal=*/true );
129 med_int tmp_numdt, tmp_numit;
131 //~med_int step = data->myUseLastTimeStep ? nbofcstp : data->myTimeStep+1;
132 //~myPrint("step ", step);
133 erreur = MEDfieldComputingStepInfo ( medIdt, nomcha, 1, &numdt, &numit, &dt );
134 for( int step = 1; step <= nbofcstp; step++ )
136 erreur = MEDfieldComputingStepInfo ( medIdt, nomcha, step, &tmp_numdt, &tmp_numit, &dt );
137 if(tmp_numdt > numdt)
145 //~addMessage( ToComment(" error: error while reading field ") << nomcha << "step (numdt, numit) = " <<"("<< numdt<< ", "
146 //numit<< ")" <<" in file " << aFile , /*fatal=*/true );
150 // Fermeture du fichier
151 if ( medIdt > 0 ) MEDfileClose(medIdt);
155 struct GET_DEFAULT // struct used to get default value from GetOptionValue()
163 class outFileStream : public std::ofstream{
165 ~outFileStream(){close();} //to close file at dtor
168 } // anonymous namespace
170 //----------------------------------------------------------------------------------------
173 data = new MgAdaptHypothesisData();
174 data->myInMeshName = "";
175 data->fromMedFile = defaultFromMedFile();
176 data->myFileInDir = defaultWorkingDirectory();
177 data->myMeshFileIn = "";
178 data->myFileOutDir = defaultWorkingDirectory();
179 data->myOutMeshName = "";
180 data->myMeshFileOut = "";
181 data->myMeshOutMed = defaultMeshOutMed();
182 data->myPublish = defaultPublish();
183 data->myUseLocalMap = defaultUseLocalMap();
184 data->myUseBackgroundMap = defaultUseBackgroundMap();
185 data->myFileSizeMapDir = defaultWorkingDirectory();
186 data->myMeshFileBackground = "";
187 data->myUseConstantValue = defaultUseConstantValue();
188 data->myConstantValue = 0.0;
189 data->myFieldName = "";
190 data->myUseNoTimeStep = defaultUseNoTimeStep();
191 data->myUseLastTimeStep = defaultUseLastTimeStep();
192 data->myUseChosenTimeStep = defaultUseChosenTimeStep();
193 data->myTimeStep = -2;
195 data->myWorkingDir = defaultWorkingDirectory();
196 data->myLogFile = defaultLogFile();
197 data->myVerboseLevel = defaultVerboseLevel();
198 data->myPrintLogInFile = defaultPrintLogInFile();
199 data->myKeepFiles = defaultKeepFiles();
200 data->myRemoveLogOnSuccess = defaultRemoveLogOnSuccess();
205 MgAdapt::MgAdapt(MgAdaptHypothesisData* myData)
207 data = new MgAdaptHypothesisData();
212 MgAdapt::MgAdapt( const MgAdapt& copy)
214 data = new MgAdaptHypothesisData();
215 MgAdaptHypothesisData *copyData = copy.getData();
216 copyMgAdaptHypothesisData(copyData);
219 this->_option2value = copy._option2value;
220 this->_customOption2value = copy._customOption2value;
221 this->_defaultOptionValues = copy._defaultOptionValues;
222 this->_doubleOptions = copy._doubleOptions;
223 this->_charOptions = copy._charOptions;
224 this->_boolOptions = copy._boolOptions;
227 //-----------------------------------------------------------------------------------------
232 void MgAdapt::buildModel()
235 const char* boolOptionNames[] = { "compute_ridges", // yes
238 // const char* intOptionNames[] = { "max_number_of_errors_printed", // 1
239 // "max_number_of_threads", // 4
242 const char* doubleOptionNames[] = { "max_memory", // 0
245 const char* charOptionNames[] = { "components", // "yes"
246 "adaptation", // both
251 while (boolOptionNames[i][0])
253 _boolOptions.insert( boolOptionNames[i] );
254 _option2value[boolOptionNames[i++]].clear();
257 // while (intOptionNames[i][0])
258 // _option2value[intOptionNames[i++]].clear();
261 while (doubleOptionNames[i][0]) {
262 _doubleOptions.insert(doubleOptionNames[i]);
263 _option2value[doubleOptionNames[i++]].clear();
266 while (charOptionNames[i][0]) {
267 _charOptions.insert(charOptionNames[i]);
268 _option2value[charOptionNames[i++]].clear();
271 // default values to be used while MG-Adapt
273 _defaultOptionValues["adaptation" ] = "both";
274 _defaultOptionValues["components" ] = "outside components";
275 _defaultOptionValues["compute_ridges"] = "yes";
276 _defaultOptionValues["max_memory" ] = ToComment(defaultMaximumMemory());
279 //=============================================================================
280 TOptionValues MgAdapt::getOptionValues() const
283 TOptionValues::const_iterator op_val = _option2value.begin();
284 for ( ; op_val != _option2value.end(); ++op_val )
285 vals.insert( make_pair( op_val->first, getOptionValue( op_val->first, GET_DEFAULT() )));
290 std::vector <std::string> MgAdapt::getOptionValuesStrVec() const
292 std::vector <std::string> vals;
293 TOptionValues::const_iterator op_val = _option2value.begin();
294 for ( ; op_val != _option2value.end(); ++op_val )
295 vals.push_back(op_val->first+":"+getOptionValue( op_val->first, GET_DEFAULT() ));
300 std::vector <std::string> MgAdapt::getCustomOptionValuesStrVec() const
302 std::vector <std::string> vals;
303 TOptionValues::const_iterator op_val;
304 for ( op_val = _customOption2value.begin(); op_val != _customOption2value.end(); ++op_val )
306 vals.push_back(op_val->first+":"+getOptionValue( op_val->first, GET_DEFAULT() ));
310 const TOptionValues& MgAdapt::getCustomOptionValues() const
312 return _customOption2value;
314 void MgAdapt::setData(MgAdaptHypothesisData* myData)
316 copyMgAdaptHypothesisData(myData);
319 MgAdaptHypothesisData* MgAdapt::getData() const
323 void MgAdapt::setMedFileIn(std::string fileName)
325 if ( isFileExist(fileName) )
327 medFileIn = fileName;
329 if (medFileOut == "") // default MED file Out
330 medFileOut = remove_extension( fileName )+ ".adapt.med";
334 THROW_SALOME_EXCEPTION("\nThe file "<< fileName <<" does not exist.\n");
338 std::string MgAdapt::getMedFileIn()
343 void MgAdapt::setMedFileOut(std::string fileOut)
345 medFileOut = fileOut;
347 std::string MgAdapt::getMedFileOut()
351 void MgAdapt::setMeshOutMed(bool mybool)
355 bool MgAdapt::getMeshOutMed()
359 void MgAdapt::setPublish(bool mybool)
363 bool MgAdapt::getPublish()
367 void MgAdapt::setFieldName(std::string myFieldName)
369 fieldName = myFieldName;
371 std::string MgAdapt::getFieldName()
375 void MgAdapt::setTimeStep(int time)
379 int MgAdapt::getTimeStep() const
384 void MgAdapt::setRankTimeStep(int time, int myRank)
390 int MgAdapt::getRank()
394 void MgAdapt::setTimeStepRankLast()
396 myUseLastTimeStep = true;
397 myUseChosenTimeStep = false;
398 myUseNoTimeStep = false;
399 //~med_int aRank, tmst;
400 //~std::string fieldFile = useBackgroundMap ? sizeMapFile : medFileIn;
401 //~getTimeStepInfos(fieldFile, tmst, aRank);
402 //~setRankTimeStep((int) tmst, (int) aRank);
404 void MgAdapt::setNoTimeStep()
406 myUseLastTimeStep = false;
407 myUseChosenTimeStep = false;
408 myUseNoTimeStep = true;
409 //~int aRank = (int)MED_NO_IT;
410 //~int tmst = (int)MED_NO_DT ;
411 //~setRankTimeStep(tmst, aRank);
413 void MgAdapt::setChosenTimeStepRank()
415 myUseLastTimeStep = false;
416 myUseChosenTimeStep = true;
417 myUseNoTimeStep = false;
418 //~int aRank = (int)MED_NO_IT;
419 //~int tmst = (int)MED_NO_DT ;
420 //~setRankTimeStep(tmst, aRank);
422 void MgAdapt::setUseLocalMap(bool myLocal)
424 useLocalMap = myLocal;
427 bool MgAdapt::getUseLocalMap()
432 void MgAdapt::setUseBackgroundMap(bool bckg)
434 useBackgroundMap = bckg;
437 bool MgAdapt::getUseBackgroundMap()
439 return useBackgroundMap;
442 void MgAdapt::setUseConstantValue(bool cnst)
444 useConstantValue = cnst;
446 bool MgAdapt::getUseConstantValue()
448 return useConstantValue;
450 void MgAdapt::setLogFile(std::string myLogFile)
454 std::string MgAdapt::getLogFile()
458 void MgAdapt::setVerbosityLevel(int verboLevel)
460 verbosityLevel = verboLevel;
462 int MgAdapt::getVerbosityLevel()
464 return verbosityLevel;
466 void MgAdapt::setRemoveOnSuccess(bool rmons)
468 removeOnSuccess = rmons;
470 bool MgAdapt::getRemoveOnSuccess()
472 return removeOnSuccess;
474 void MgAdapt::setSizeMapFile(std::string mapFile)
476 if ( mapFile == "" || isFileExist(mapFile) )
478 sizeMapFile = mapFile;
482 THROW_SALOME_EXCEPTION("\nThe file "<< mapFile <<" does not exist.\n");
485 std::string MgAdapt::getSizeMapFile()
490 void MgAdapt::setMeshName(std::string name)
494 std::string MgAdapt::getMeshName()
498 void MgAdapt::setMeshNameOut(std::string name)
502 std::string MgAdapt::getMeshNameOut()
506 void MgAdapt::setFromMedFile(bool mybool)
508 fromMedFile = mybool;
510 bool MgAdapt::isFromMedFile()
514 void MgAdapt::setConstantValue(double cnst)
516 constantValue = cnst;
518 double MgAdapt::getConstantValue() const
520 return constantValue;
523 void MgAdapt::setWorkingDir(std::string dir)
527 std::string MgAdapt::getWorkingDir() const
531 void MgAdapt::setKeepWorkingFiles(bool mybool)
533 toKeepWorkingFiles = mybool;
535 bool MgAdapt::getKeepWorkingFiles()
537 return toKeepWorkingFiles;
539 void MgAdapt::setPrintLogInFile(bool print)
541 printLogInFile = print;
543 bool MgAdapt::getPrintLogInFile()
545 return printLogInFile;
548 bool MgAdapt::setAll()
551 setFromMedFile(data->fromMedFile);
553 checkDirPath(data->myFileInDir);
554 file = data->myFileInDir+data->myMeshFileIn;
556 setMeshName(data->myInMeshName);
557 setMeshNameOut(data->myOutMeshName);
558 checkDirPath(data->myFileOutDir);
559 std::string out = data->myFileOutDir+data->myMeshFileOut;
561 setPublish(data->myPublish);
562 setMeshOutMed(data->myMeshOutMed);
563 setUseLocalMap(data->myUseLocalMap);
564 setUseBackgroundMap(data->myUseBackgroundMap);
565 setUseConstantValue(data->myUseConstantValue);
568 if (useBackgroundMap)
570 checkDirPath(data->myFileSizeMapDir);
571 mapfile = data->myFileSizeMapDir+data->myMeshFileBackground;
572 setFieldName(data->myFieldName);
574 else if (useConstantValue)
576 setConstantValue(data->myConstantValue);
581 setConstantValue(0.0);
582 setFieldName(data->myFieldName);
585 setSizeMapFile(mapfile);
586 if (data->myUseNoTimeStep)
588 else if (data->myUseLastTimeStep)
589 setTimeStepRankLast();
592 setChosenTimeStepRank();
593 setRankTimeStep(data->myTimeStep, data->myRank);
595 /* Advanced options */
596 setWorkingDir(data->myWorkingDir);
597 checkDirPath(data->myWorkingDir);
598 setLogFile(data->myWorkingDir+defaultLogFile());
599 setVerbosityLevel(data->myVerboseLevel);
600 setRemoveOnSuccess(data->myRemoveLogOnSuccess);
601 setPrintLogInFile(data->myPrintLogInFile);
602 setKeepWorkingFiles(data->myKeepFiles);
607 void MgAdapt::checkDirPath(std::string& dirPath)
609 const char lastChar = *dirPath.rbegin();
611 if(lastChar != '\\') dirPath+='\\';
613 if(lastChar != '/') dirPath+='/';
616 //=============================================================================
617 void MgAdapt::setOptionValue(const std::string& optionName,
618 const std::string& optionValue)
620 // INFOS("setOptionValue");
621 // std::cout << "optionName: " << optionName << ", optionValue: " << optionValue << std::endl;
622 TOptionValues::iterator op_val = _option2value.find(optionName);
623 if (op_val == _option2value.end())
625 op_val = _customOption2value.find( optionName );
626 _customOption2value[ optionName ] = optionValue;
630 if (op_val->second != optionValue)
632 std::string lowerOptionValue = toLowerStr(optionValue);
633 const char* ptr = lowerOptionValue.c_str();
634 // strip white spaces
635 while (ptr[0] == ' ')
637 size_t i = strlen(ptr);
638 while (i != 0 && ptr[i - 1] == ' ')
642 std::string typeName;
647 else if (_charOptions.count(optionName))
649 // do not check strings
651 else if (_doubleOptions.count(optionName))
653 // check if value is double
657 else if (_boolOptions.count(optionName))
659 // check if value is bool
660 toBool(ptr, &typeOk);
665 // check if value is int
667 typeName = "integer";
669 if ( typeOk ) // check some specific values ?
674 std::string msg = "Advanced option '" + optionName + "' = '" + optionValue + "' but must be " + typeName;
675 throw std::invalid_argument(msg);
677 std::string value( ptr, i );
678 // std::cout << "==> value: " << value << std::endl;
679 if ( _defaultOptionValues[ optionName ] == value ) value.clear();
681 // std::cout << "==> value: " << value << std::endl;
682 op_val->second = value;
685 //=============================================================================
686 //! Return option value. If isDefault provided, it can be a default value,
687 // then *isDefault == true. If isDefault is not provided, the value will be
688 // empty if it equals a default one.
689 std::string MgAdapt::getOptionValue(const std::string& optionName, bool* isDefault) const
691 // INFOS("getOptionValue");
692 // std::cout << "optionName: " << optionName << ", isDefault: " << isDefault << std::endl;
693 TOptionValues::const_iterator op_val = _option2value.find(optionName);
694 if (op_val == _option2value.end())
696 op_val = _customOption2value.find(optionName);
697 if (op_val == _customOption2value.end())
699 std::string msg = "Unknown MG-Adapt option: <" + optionName + ">";
700 throw std::invalid_argument(msg);
703 std::string val = op_val->second;
704 if ( isDefault ) *isDefault = ( val.empty() );
706 if ( val.empty() && isDefault )
708 op_val = _defaultOptionValues.find( optionName );
709 if (op_val != _defaultOptionValues.end()) val = op_val->second;
711 // std::cout << "==> val: " << val << std::endl;
715 //================================================================================
717 * \brief Converts a string to a real value
719 //================================================================================
721 double MgAdapt::toDbl(const std::string& str, bool* isOk )
723 if ( str.empty() ) throw std::invalid_argument("Empty value provided");
726 double val = strtod(&str[0], &endPtr);
727 bool ok = (&str[0] != endPtr);
729 if ( isOk ) *isOk = ok;
733 std::string msg = "Not a real value:'" + str + "'";
734 throw std::invalid_argument(msg);
738 //================================================================================
740 * \brief Converts a string to a lower
742 //================================================================================
743 std::string MgAdapt::toLowerStr(const std::string& str)
746 for ( size_t i = 0; i <= s.size(); ++i )
747 s[i] = (char) tolower( s[i] );
750 //================================================================================
752 * \brief Converts a string to a bool
754 //================================================================================
756 bool MgAdapt::toBool(const std::string& str, bool* isOk )
759 if ( isOk ) *isOk = true;
761 for ( size_t i = 0; i <= s.size(); ++i )
762 s[i] = (char) tolower( s[i] );
764 if ( s == "1" || s == "true" || s == "active" || s == "yes" )
767 if ( s == "0" || s == "false" || s == "inactive" || s == "no" )
774 std::string msg = "Not a Boolean value:'" + str + "'";
775 throw std::invalid_argument(msg);
779 //================================================================================
781 * \brief Converts a string to a integer value
783 //================================================================================
785 int MgAdapt::toInt(const std::string& str, bool* isOk )
787 if ( str.empty() ) throw std::invalid_argument("Empty value provided");
790 int val = (int)strtol( &str[0], &endPtr, 10);
791 bool ok = (&str[0] != endPtr);
793 if ( isOk ) *isOk = ok;
797 std::string msg = "Not an integer value:'" + str + "'";
798 throw std::invalid_argument(msg);
802 //=============================================================================
803 bool MgAdapt::hasOptionDefined( const std::string& optionName ) const
805 bool isDefault = false;
808 getOptionValue( optionName, &isDefault );
810 catch ( std::invalid_argument )
816 //================================================================================
818 * \brief Return command to run MG-Adapt mesher excluding file prefix (-f)
820 //================================================================================
822 std::string MgAdapt::getCommandToRun(MgAdapt* hyp)
824 return hyp ? hyp->getCommandToRun() : ToComment("error with hypothesis!");
827 int MgAdapt::compute(std::string& errStr)
829 std::string cmd = getCommandToRun();
830 // std::cout << cmd << std::endl;
833 execCmd( cmd.c_str(), err ); // run
837 errStr = ToComment("system(mg-adapt.exe ...) command failed with error: ") << strerror( errno );
839 else if ( !isFileExist( meshFormatOutputMesh ))
841 errStr = ToComment(" failed to find file ") << meshFormatOutputMesh
842 << " output from MG-Adapt run";
846 convertMeshFile(meshFormatOutputMesh, solFormatOutput);
852 void MgAdapt::execCmd( const char* cmd, int& err)
855 std::array <char, 128> buffer;
857 outFileStream fileStream;
860 fileStream.open(logFile);
861 buf = fileStream.rdbuf();
865 buf = std::cout.rdbuf();
867 std::ostream logStream(buf);
871 # if defined(UNICODE)
872 const wchar_t * aCmd = Kernel_Utils::utf8_decode(cmd);
873 SMESHUtils::ArrayDeleter<const wchar_t> deleter( aCmd );
874 std::unique_ptr <FILE, decltype(&_pclose)> pipe(_wpopen(aCmd, O_RDONLY), _pclose );
876 std::unique_ptr <FILE, decltype(&_pclose)> pipe(_popen(cmd, "r"), _pclose );
879 std::unique_ptr <FILE, decltype(&pclose)> pipe(popen(cmd, "r"), pclose );
884 throw std::runtime_error("popen() failed!");
886 while(fgets(buffer.data(), buffer.size(), pipe.get()) !=nullptr )
888 logStream<<buffer.data() ;
893 * to delete tmp files .mesh, .sol and if needed
897 void MgAdapt::cleanUp()
901 if(toKeepWorkingFiles)
903 if(removeOnSuccess && printLogInFile)
904 tmpFilesToBeDeleted.push_back(logFile);
906 std::vector< std::string>::iterator it = tmpFilesToBeDeleted.begin();
907 for (; it!=tmpFilesToBeDeleted.end(); ++it)
909 errStr=removeFile(*it, notOk);
912 appendMsgToLogFile(errStr);
918 void MgAdapt::appendMsgToLogFile(std::string& msg)
920 std::ofstream logStream;
921 logStream.open(logFile, std::ofstream::out | std::ofstream::app);
925 //================================================================================
927 * \brief Return command to run MG-Tetra mesher excluding file prefix (-f)
929 //================================================================================
931 std::string MgAdapt::getCommandToRun()
934 || return system command with args and options
938 std::string cmd = getExeName();
939 std::string meshIn(""), sizeMapIn(""), solFileIn("");
940 updateTimeStepRank();
941 convertMedFile(meshIn, solFileIn, sizeMapIn);
942 if (!isFileExist(meshIn) || !isFileExist(solFileIn))
944 errStr = ToComment(" failed to find .mesh or .sol file from converter ")<< strerror( errno );
947 tmpFilesToBeDeleted.push_back(meshIn);
948 tmpFilesToBeDeleted.push_back(solFileIn);
949 if(useBackgroundMap && !isFileExist(sizeMapIn))
951 errStr = ToComment(" failed to find .mesh size map file from converter ")<< strerror( errno );
955 cmd+= " --in "+ meshIn;
956 meshFormatOutputMesh = getFileName()+".mesh";
957 tmpFilesToBeDeleted.push_back(meshFormatOutputMesh);
958 cmd+= " --out "+ meshFormatOutputMesh;
959 if (useLocalMap || useConstantValue) cmd+= " --sizemap "+ solFileIn;
960 else // (useBackgroundMap)
962 cmd+= " --background_mesh "+ sizeMapIn ;
963 cmd+= " --background_sizemap "+ solFileIn;
964 tmpFilesToBeDeleted.push_back(sizeMapIn);
968 //~// constant value TODO
970 // Check coherence between mesh dimension and option fo adaptation
971 checkDimensionOptionAdaptation();
973 // sizemap file is written only if level is higher than 3
974 if ( verbosityLevel > 3)
976 std::string solFileOut = getFileName()+".sol";
977 cmd+= " --write_sizemap "+ solFileOut;
978 solFormatOutput.push_back(solFileOut);
979 tmpFilesToBeDeleted.push_back(solFileOut);
982 std::string option, value;
984 const TOptionValues* options[] = { &_option2value, &_customOption2value };
985 for ( int iOp = 0; iOp < 2; ++iOp )
987 TOptionValues::const_iterator o2v = options[iOp]->begin();
988 for ( ; o2v != options[iOp]->end(); ++o2v )
991 value = getOptionValue( option, &isDefault );
995 if ( value.empty() )//value == NoValue() )
997 if ( _defaultOptionValues.count( option ))
998 continue; // non-custom option with no value
1001 if ( strncmp( "no", option.c_str(), 2 ) == 0 ) // options w/o values: --no_*
1003 if ( !value.empty() && toBool( value ) == false )
1007 if ( option[0] != '-' )
1011 // std::cout << "--- option: '" << option << ", value: '" << value <<"'"<< std::endl;
1012 cmd += option + " " + value;
1017 if (verbosityLevel != defaultVerboseLevel())
1019 cmd+= " --verbose "+ ToComment(verbosityLevel);
1023 smIdType nbVertex, nbEdge, nbFace, nbVol;
1024 DriverGMF_Read gmfReader;
1025 gmfReader.SetFile( meshIn );
1026 gmfReader.GetMeshInfo( nbVertex, nbEdge, nbFace, nbVol );
1028 std::string errorTxt;
1029 std::string key = SMESHUtils_MGLicenseKeyGen::GetKey( meshIn,
1030 FromSmIdType<int>( nbVertex ),
1031 FromSmIdType<int>( nbEdge ),
1032 FromSmIdType<int>( nbFace ),
1033 FromSmIdType<int>( nbVol ),
1036 return ToComment( "Problem with library SalomeMeshGemsKeyGenerator: " + errorTxt );
1038 cmd += " --key " + key;
1044 // std::cout << "--- cmd :"<< std::endl;
1045 // std::cout << cmd << std::endl;
1050 //=======================================================================
1051 //function : defaultMaximumMemory
1052 //=======================================================================
1055 #include <windows.h>
1056 #elif !defined(__APPLE__)
1057 #include <sys/sysinfo.h>
1060 double MgAdapt::defaultMaximumMemory()
1063 // See http://msdn.microsoft.com/en-us/library/aa366589.aspx
1064 MEMORYSTATUSEX statex;
1065 statex.dwLength = sizeof (statex);
1066 long err = GlobalMemoryStatusEx (&statex);
1069 double totMB = (double)statex.ullAvailPhys / 1024. / 1024.;
1070 return (double)( 0.7 * totMB );
1072 #elif !defined(__APPLE__)
1074 long err = sysinfo( &si );
1077 long ramMB = si.totalram * si.mem_unit / 1024 / 1024;
1078 return ( 0.7 * double( ramMB ));
1084 //=======================================================================
1085 //function : defaultWorkingDirectory
1086 //=======================================================================
1088 std::string MgAdapt::defaultWorkingDirectory()
1090 std::string aTmpDir;
1092 char *Tmp_dir = getenv("SALOME_TMP_DIR");
1106 //================================================================================
1108 * \brief Return a unique file name
1110 //================================================================================
1112 std::string MgAdapt::getFileName() const
1114 std::string aTmpDir = workingDir;
1115 const char lastChar = *aTmpDir.rbegin();
1117 if(lastChar != '\\') aTmpDir+='\\';
1119 if(lastChar != '/') aTmpDir+='/';
1122 SMESH_Comment aGenericName( aTmpDir );
1123 aGenericName << "MgAdapt_";
1125 aGenericName << getpid();
1127 aGenericName << _getpid();
1129 aGenericName << "_";
1130 aGenericName << std::abs((int)(long) aGenericName.data());
1132 return aGenericName;
1134 //=======================================================================
1135 //function : defaultLogFile
1136 //=======================================================================
1138 std::string MgAdapt::defaultLogFile()
1140 std::string alogFile("MG_ADAPT.log");
1143 //=======================================================================
1144 //function : defaultUseConstantValue
1145 //=======================================================================
1147 bool MgAdapt::defaultUseConstantValue()
1151 //=======================================================================
1152 //function : defaultUseNoTimeStep
1153 //=======================================================================
1155 bool MgAdapt::defaultUseNoTimeStep()
1159 //=======================================================================
1160 //function : defaultRemoveLogOnSuccess
1161 //=======================================================================
1163 bool MgAdapt::defaultRemoveLogOnSuccess()
1167 //=======================================================================
1168 //function : defaultPrintLogInFile
1169 //=======================================================================
1171 bool MgAdapt::defaultPrintLogInFile()
1175 //=======================================================================
1176 //function : defaultUseChosenTimeStep
1177 //=======================================================================
1179 bool MgAdapt::defaultUseChosenTimeStep()
1183 //=======================================================================
1184 //function : UseLastTimeStep
1185 //=======================================================================
1187 bool MgAdapt::defaultUseLastTimeStep()
1191 //=======================================================================
1192 //function : defaultUseBackgroundMap
1193 //=======================================================================
1195 bool MgAdapt::defaultUseBackgroundMap()
1199 //=======================================================================
1200 //function : defaultKeepFiles
1201 //=======================================================================
1203 bool MgAdapt::defaultKeepFiles()
1207 //=======================================================================
1208 //function : defaultUseLocalMap
1209 //=======================================================================
1211 bool MgAdapt::defaultUseLocalMap()
1215 //=======================================================================
1216 //function : defaultPublish
1217 //=======================================================================
1219 bool MgAdapt::defaultPublish()
1223 //=======================================================================
1224 //function : defaultMeshOutMed
1225 //=======================================================================
1227 bool MgAdapt::defaultMeshOutMed()
1231 //=======================================================================
1232 //function : defaultFromMedFile
1233 //=======================================================================
1235 bool MgAdapt::defaultFromMedFile()
1239 //=======================================================================
1240 //function : defaultVerboseLevel
1241 //=======================================================================
1243 int MgAdapt::defaultVerboseLevel()
1247 std::string MgAdapt::getExeName()
1249 return "mg-adapt.exe";
1251 void MgAdapt::copyMgAdaptHypothesisData( const MgAdaptHypothesisData* from)
1253 data->myFileInDir = from->myFileInDir;
1254 data->myMeshFileIn = from->myMeshFileIn;
1255 data->myMeshFileBackground = from->myMeshFileBackground;
1256 data->myOutMeshName = from->myOutMeshName;
1257 data->myMeshFileOut = from->myMeshFileOut;
1258 data->myFileOutDir = from->myFileOutDir;
1259 data->myFileSizeMapDir = from->myFileSizeMapDir;
1260 data->myFieldName = from->myFieldName;
1261 data->fromMedFile = from->fromMedFile;
1262 data->myPublish = from->myPublish;
1263 data->myMeshOutMed = from->myMeshOutMed;
1264 data->myUseLocalMap = from->myUseLocalMap;
1265 data->myUseBackgroundMap = from->myUseBackgroundMap;
1266 data->myUseConstantValue = from->myUseConstantValue;
1267 data->myConstantValue = from->myConstantValue;
1268 data->myTimeStep = from->myTimeStep;
1269 data->myRank = from->myRank;
1270 data->myUseNoTimeStep = from->myUseNoTimeStep;
1271 data->myUseLastTimeStep = from->myUseLastTimeStep;
1272 data->myUseChosenTimeStep = from->myUseChosenTimeStep;
1273 data->myWorkingDir = from->myWorkingDir;
1274 data->myLogFile = from->myLogFile;
1275 data->myPrintLogInFile = from->myPrintLogInFile;
1276 data->myKeepFiles = from->myKeepFiles;
1277 data->myRemoveLogOnSuccess = from->myRemoveLogOnSuccess;
1278 data->myVerboseLevel = from->myVerboseLevel;
1281 std::vector<std::string> MgAdapt::getListFieldsNames(std::string fileIn)
1283 MEDCoupling::MCAuto<MEDCoupling::MEDFileData> mfd = MEDCoupling::MEDFileData::New(fileIn);
1284 std::vector<std::string> listFieldsNames(mfd->getFields()->getFieldsNames());
1285 return listFieldsNames ;
1288 void MgAdapt::checkDimensionOptionAdaptation()
1290 // Quand le maillage est 3D, tout est possible
1291 // Quand le maillage est 2D, il faut 'surface' sauf si carte de fonds 3D
1292 MEDCoupling::MCAuto<MEDCoupling::MEDFileData> mfd = MEDCoupling::MEDFileData::New(medFileIn);
1293 int meshdim = mfd->getMeshes()->getMeshAtPos(0)->getMeshDimension() ;
1294 // std::cout << "meshdim = " << meshdim << std::endl;
1298 std::string optionName = "adaptation";
1299 std::string optionValue = getOptionValue(optionName);
1300 // std::cout << "optionValue = '" << optionValue <<"'"<< std::endl;
1301 bool a_tester = false ;
1302 // carte locale ou constante : impératif d'avoir "surface"
1303 if ( useLocalMap || useConstantValue) a_tester = true ;
1304 // carte de fond : impératif d'avoir "surface" si le fonds est aussi 2D
1307 MEDCoupling::MCAuto<MEDCoupling::MEDFileData> mfdbg = MEDCoupling::MEDFileData::New(sizeMapFile);
1308 int meshdimbg = mfdbg->getMeshes()->getMeshAtPos(0)->getMeshDimension() ;
1309 // std::cout << "meshdimbg = " << meshdimbg << std::endl;
1310 if ( meshdimbg == 2 ) a_tester = true ;
1314 if ( optionValue == "" ) setOptionValue (optionName, "surface");
1317 if ( optionValue != "surface" )
1319 THROW_SALOME_EXCEPTION("Mesh dimension is 2; the option should be 'surface'"
1320 " instead of '" << optionValue << "'.");
1327 void MgAdapt::checkFieldName(std::string fileIn)
1330 std::vector<std::string> listFieldsNames = getListFieldsNames(fileIn);
1331 std::size_t jaux(listFieldsNames.size());
1332 for(std::size_t j=0;j<jaux;j++)
1334 if ( fieldName == listFieldsNames[j] )
1342 std::cout << "Available field names:" << std::endl;
1343 for(std::size_t j=0;j<jaux;j++)
1344 { std::cout << listFieldsNames[j] << std::endl;}
1345 THROW_SALOME_EXCEPTION( "Field " << fieldName << " is not found.");
1349 void MgAdapt::checkTimeStepRank(std::string fileIn)
1352 MEDCoupling::MCAuto<MEDCoupling::MEDFileData> mfd = MEDCoupling::MEDFileData::New(fileIn);
1353 MEDCoupling::MCAuto<MEDCoupling::MEDFileAnyTypeFieldMultiTS> fts( mfd->getFields()->getFieldWithName(fieldName) );
1354 std::vector<double> timevalue;
1355 std::vector< std::pair<int,int> > timesteprank = fts->getTimeSteps(timevalue);
1356 std::size_t jaux(timesteprank.size());
1357 for(std::size_t j=0;j<jaux;j++)
1359 if ( ( timeStep == timesteprank[j].first ) & ( rank == timesteprank[j].second ) )
1367 std::cout << "Available (Time step, Rank):" << std::endl;
1368 for(std::size_t j=0;j<jaux;j++)
1369 { std::cout << "(Time step = " << timesteprank[j].first << ", Rank = " << timesteprank[j].second << ")" << std::endl;}
1370 THROW_SALOME_EXCEPTION("(Time step = " << timeStep << ", Rank = " << rank << ") is not found.");
1374 void MgAdapt::convertMedFile(std::string& meshFormatMeshFileName, std::string& solFormatFieldFileName, std::string& meshFormatsizeMapFile)
1376 std::vector<std::string> fieldFileNames;
1377 MEDCoupling::MeshFormatWriter writer;
1378 MEDCoupling::MCAuto<MEDCoupling::MEDFileData> mfd = MEDCoupling::MEDFileData::New(medFileIn);
1379 MEDCoupling::MEDFileMeshes* meshes = mfd->getMeshes();
1380 MEDCoupling::MEDFileMesh* fileMesh = meshes->getMeshAtPos(0); // ok only one mesh in file!
1381 if (meshNameOut =="")
1382 meshNameOut = fileMesh->getName();
1383 storeGroupsAndFams(fileMesh);
1385 MEDCoupling::MCAuto<MEDCoupling::MEDFileFields> fields = MEDCoupling::MEDFileFields::New();
1386 solFormatFieldFileName = getFileName();
1387 solFormatFieldFileName+=".sol";
1388 fieldFileNames.push_back(solFormatFieldFileName);
1390 if (useBackgroundMap)
1392 checkFieldName(sizeMapFile) ;
1393 checkTimeStepRank(sizeMapFile) ;
1394 meshFormatsizeMapFile = getFileName();
1395 meshFormatsizeMapFile += ".mesh";
1396 buildBackGroundMeshAndSolFiles(fieldFileNames, meshFormatsizeMapFile);
1398 else if(useLocalMap)
1400 checkFieldName(medFileIn) ;
1401 checkTimeStepRank(medFileIn) ;
1402 MEDCoupling::MCAuto<MEDCoupling::MEDFileAnyTypeFieldMultiTS> fts( mfd->getFields()->getFieldWithName(fieldName) );
1403 MEDCoupling::MCAuto<MEDCoupling::MEDFileAnyTypeField1TS> f = fts->getTimeStep(timeStep, rank);
1404 MEDCoupling::MCAuto<MEDCoupling::MEDFileFieldMultiTS> tmFts = MEDCoupling::MEDFileFieldMultiTS::New();
1405 tmFts->pushBackTimeStep(f);
1407 fields->pushField(tmFts);
1409 writer.setFieldFileNames( fieldFileNames);
1413 MEDCoupling::MCAuto<MEDCoupling::MEDCouplingMesh> mesh = fileMesh->getMeshAtLevel(1); // nodes mesh
1414 MEDCoupling::MCAuto<MEDCoupling::MEDCouplingUMesh> umesh = mesh->buildUnstructured(); // nodes mesh
1415 int dim = umesh->getSpaceDimension();
1416 int version = sizeof(double) < 8 ? 1 : 2;
1417 mcIdType nbNodes = umesh->getNumberOfNodes();
1418 buildConstantSizeMapSolFile(solFormatFieldFileName, dim, version, nbNodes);
1421 mfd->setFields( fields );
1422 meshFormatMeshFileName = getFileName();
1423 meshFormatMeshFileName+=".mesh";
1424 writer.setMeshFileName(meshFormatMeshFileName);
1425 writer.setMEDFileDS( mfd);
1430 void MgAdapt::convertMeshFile(std::string& meshFormatIn, std::vector< std::string>& solFieldFileNames) const
1432 MEDCoupling::MeshFormatReader reader(meshFormatIn, solFieldFileNames);
1434 MEDCoupling::MCAuto<MEDCoupling::MEDFileData> mfd = reader.loadInMedFileDS();
1436 MEDCoupling::MEDFileMeshes* meshes = mfd->getMeshes();
1437 MEDCoupling::MEDFileMesh* fileMesh = meshes->getMeshAtPos(0); // ok only one mesh in file!
1438 fileMesh->setName(meshNameOut);
1439 restoreGroupsAndFams(fileMesh);
1440 mfd->write(medFileOut, 2);
1443 void MgAdapt::storeGroupsAndFams(MEDCoupling::MEDFileMesh* fileMesh)
1445 storefams(fileMesh);
1446 storeGroups(fileMesh);
1449 void MgAdapt::restoreGroupsAndFams(MEDCoupling::MEDFileMesh* fileMesh) const
1451 restorefams(fileMesh);
1452 restoreGroups(fileMesh);
1454 void MgAdapt::storeGroups(MEDCoupling::MEDFileMesh* fileMesh)
1456 std::map<std::string, std::vector<std::string> > grpFams = fileMesh->getGroupInfo();
1457 std::map<std::string, std::vector<std::string> >::iterator g2ff = grpFams.begin();
1459 for ( ; g2ff != grpFams.end(); ++g2ff )
1461 std::string groupName = g2ff->first;
1462 std::vector<std::string> famNames = g2ff->second;
1464 if ( famNames.empty() ) continue;
1465 std::vector< int> famListId;
1466 for ( size_t i = 0; i < famNames.size(); ++i )
1468 famListId.push_back( FromIdType<int>( fileMesh->getFamilyId( famNames[i].c_str() )));
1470 group grp(groupName, famListId, famNames);
1471 groupVec.push_back(grp);
1475 void MgAdapt::storefams(MEDCoupling::MEDFileMesh* fileMesh)
1477 std::map<std::string, mcIdType> grpFams = fileMesh->getFamilyInfo();
1478 std::map<std::string, mcIdType >::iterator f = grpFams.begin();
1480 for ( ; f != grpFams.end(); ++f )
1482 if(!f->second) continue; // FAMILLE_ZERO
1483 family fs(f->first, FromIdType<int>( f->second ));
1484 famVec.push_back(fs);
1489 void MgAdapt::restorefams(MEDCoupling::MEDFileMesh* fileMesh) const
1491 std::vector<family>::const_iterator fIt = famVec.begin();
1493 for (; fIt!=famVec.end(); ++fIt)
1497 std::string givenFamNameFromMeshGemConverter = fileMesh->getFamilyNameGivenId( std::abs(fIt->_famId) );
1498 fileMesh->changeFamilyId(std::abs(fIt->_famId), fIt->_famId);
1499 fileMesh->changeFamilyName(givenFamNameFromMeshGemConverter, fIt->_famName);
1501 catch (const std::exception& e)
1503 std::cerr<<e.what();
1508 void MgAdapt::restoreGroups(MEDCoupling::MEDFileMesh* fileMesh) const
1510 std::map<std::string, std::vector<std::string> > info;
1511 std::vector <group>::const_iterator grpFams = groupVec.begin();
1513 for (; grpFams!=groupVec.end(); ++grpFams)
1515 info.insert(std::pair <std::string, std::vector<std::string> > (grpFams->_name, grpFams->_famNames) );
1518 fileMesh->setGroupInfo(info);
1521 void MgAdapt::buildConstantSizeMapSolFile(const std::string& solFormatFieldFileName, const int dim, const int version, const size_t nbNodes) const
1523 MeshFormat::Localizer loc;
1524 MeshFormat::MeshFormatParser writer;
1525 int fileId = writer.GmfOpenMesh( solFormatFieldFileName.c_str(), GmfWrite, version, dim);
1526 int typTab[] = {GmfSca};
1527 writer.GmfSetKwd(fileId, MeshFormat::GmfSolAtVertices, (int)nbNodes, 1, typTab);
1528 for (size_t i = 0; i<nbNodes; i++)
1530 double valTab[1] = {constantValue};
1531 writer.GmfSetLin( fileId, MeshFormat::GmfSolAtVertices, valTab);
1533 writer.GmfCloseMesh(fileId);
1536 void MgAdapt::buildBackGroundMeshAndSolFiles(const std::vector<std::string>& fieldFileNames, const std::string& meshFormatsizeMapFile) const
1538 MEDCoupling::MCAuto<MEDCoupling::MEDFileData> tmpMfd = MEDCoupling::MEDFileData::New(sizeMapFile);
1539 MEDCoupling::MEDFileFields* tmpFields = tmpMfd->getFields();
1540 MEDCoupling::MCAuto<MEDCoupling::MEDFileAnyTypeFieldMultiTS> fts( tmpFields->getFieldWithName(fieldName) );
1541 MEDCoupling::MCAuto<MEDCoupling::MEDFileFieldMultiTS> fts1 = MEDCoupling::DynamicCastSafe<MEDCoupling::MEDFileAnyTypeFieldMultiTS,MEDCoupling::MEDFileFieldMultiTS>(fts);
1542 MEDCoupling::MCAuto<MEDCoupling::MEDFileAnyTypeField1TS> f = fts1->getTimeStep(timeStep, rank);
1543 MEDCoupling::MCAuto<MEDCoupling::MEDFileFieldMultiTS> tmFts = MEDCoupling::MEDFileFieldMultiTS::New();
1544 tmFts->pushBackTimeStep(f);
1546 MEDCoupling::MCAuto<MEDCoupling::MEDFileFields> tmp_fields = MEDCoupling::MEDFileFields::New();
1547 tmp_fields->pushField(tmFts);
1549 tmpMfd->setFields( tmp_fields );
1550 MEDCoupling::MeshFormatWriter tmpWriter;
1551 tmpWriter.setMeshFileName(meshFormatsizeMapFile);
1552 tmpWriter.setFieldFileNames( fieldFileNames);
1553 tmpWriter.setMEDFileDS(tmpMfd);
1557 MgAdapt::Status MgAdapt::addMessage(const std::string& msg,
1558 const bool isFatal/*=false*/)
1561 _errorMessages.clear(); // warnings are useless if a fatal error encounters
1563 _errorMessages.push_back( msg );
1567 std::cout << msg << std::endl;
1569 return ( _status = isFatal ? MgAdapt::DRS_FAIL : MgAdapt::DRS_WARN_SKIP_ELEM );
1572 void MgAdapt::updateTimeStepRank()
1577 if (myUseNoTimeStep)
1581 setRankTimeStep((int)tmst, (int)arank);
1583 else if (myUseLastTimeStep)
1585 std::string fieldFile = useBackgroundMap ? sizeMapFile : medFileIn;
1586 getTimeStepInfos(fieldFile, tmst, arank, fieldName);
1587 setRankTimeStep((int)tmst, (int)arank);