1 // Copyright (C) 2007-2020 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 // file : MG_ADAPT.cxx
23 #include "MG_ADAPT.hxx"
25 #include "MeshFormatReader.hxx"
26 #include "MeshFormatWriter.hxx"
27 #include "MEDFileMesh.hxx"
29 #include "MEDFileData.hxx"
30 #include "MEDFileField.hxx"
31 #include "MEDCouplingFieldDouble.hxx"
33 #include <SALOME_NamingService.hxx>
34 #include <Utils_SALOME_Exception.hxx>
35 #include "Utils_CorbaException.hxx"
37 #include <utilities.h>
40 #include <TCollection_AsciiString.hxx>
43 #include <boost/filesystem.hpp>
45 using namespace MG_ADAPT;
46 static std::string removeFile(std::string fileName, int& notOk)
49 notOk = std::remove(fileName.c_str());
50 if (notOk) errStr = ToComment("\n error while removing file : ") << fileName;
51 else errStr = ToComment("\n file : ") << fileName << " succesfully deleted! \n ";
55 std::string remove_extension(const std::string& filename) {
56 size_t lastdot = filename.find_last_of(".");
57 if (lastdot == std::string::npos) return filename;
58 return filename.substr(0, lastdot);
62 struct GET_DEFAULT // struct used to get default value from GetOptionValue()
71 //----------------------------------------------------------------------------------------
74 data = new MgAdaptHypothesisData();
75 data->myInMeshName = "";
76 data->fromMedFile = defaultFromMedFile();
77 data->myFileInDir = defaultWorkingDirectory();
78 data->myMeshFileIn = "";
79 data->myFileOutDir = defaultWorkingDirectory();
80 data->myOutMeshName = "";
81 data->myMeshFileOut = "";
82 data->myMeshOutMed = defaultMeshOutMed();
83 data->myPublish = defaultPublish();
84 data->myUseLocalMap = defaultUseLocalMap();
85 data->myUseBackgroundMap = defaultUseBackgroundMap();
86 data->myFileSizeMapDir = defaultWorkingDirectory();
87 data->myMeshFileBackground = "";
88 data->myUseConstantValue = defaultUseConstantValue();
89 data->myConstantValue = 0.0;
90 data->myFieldName = "";
91 data->myUseNoTimeStep = defaultUseNoTimeStep();
92 data->myUseLastTimeStep = defaultUseLastTimeStep();
93 data->myUseChosenTimeStep = defaultUseChosenTimeStep();
94 data->myTimeStep = -2;
96 data->myWorkingDir = defaultWorkingDirectory();
97 data->myLogFile = defaultLogFile();
98 data->myVerboseLevel = defaultVerboseLevel();
99 data->myPrintLogInFile = defaultPrintLogInFile();
100 data->myKeepFiles = defaultKeepFiles();
101 data->myRemoveLogOnSuccess = defaultRemoveLogOnSuccess();
106 MgAdapt::MgAdapt(MgAdaptHypothesisData* myData)
108 data = new MgAdaptHypothesisData();
113 MgAdapt::MgAdapt( const MgAdapt& copy)
115 data = new MgAdaptHypothesisData();
116 MgAdaptHypothesisData *copyData = copy.getData();
117 copyMgAdaptHypothesisData(copyData);
120 this->_option2value = copy._option2value;
121 this->_customOption2value = copy._customOption2value;
122 this->_defaultOptionValues = copy._defaultOptionValues;
123 this->_doubleOptions = copy._doubleOptions;
124 this->_charOptions = copy._charOptions;
125 this->_boolOptions = copy._boolOptions;
128 //-----------------------------------------------------------------------------------------
133 void MgAdapt::buildModel()
136 const char* boolOptionNames[] = { "compute_ridges", // yes
139 // const char* intOptionNames[] = { "max_number_of_errors_printed", // 1
140 // "max_number_of_threads", // 4
143 const char* doubleOptionNames[] = { "max_memory", // 0
146 const char* charOptionNames[] = { "components", // "yes"
147 "adaptation", // both
152 while (boolOptionNames[i][0])
154 _boolOptions.insert( boolOptionNames[i] );
155 _option2value[boolOptionNames[i++]].clear();
158 // while (intOptionNames[i][0])
159 // _option2value[intOptionNames[i++]].clear();
162 while (doubleOptionNames[i][0]) {
163 _doubleOptions.insert(doubleOptionNames[i]);
164 _option2value[doubleOptionNames[i++]].clear();
167 while (charOptionNames[i][0]) {
168 _charOptions.insert(charOptionNames[i]);
169 _option2value[charOptionNames[i++]].clear();
172 // default values to be used while MG-Adapt
174 _defaultOptionValues["adaptation" ] = "both";
175 _defaultOptionValues["components" ] = "outside components";
176 _defaultOptionValues["compute_ridges"] = "yes";
177 _defaultOptionValues["max_memory" ] = ToComment(defaultMaximumMemory());
180 //=============================================================================
181 TOptionValues MgAdapt::getOptionValues() const
184 TOptionValues::const_iterator op_val = _option2value.begin();
185 for ( ; op_val != _option2value.end(); ++op_val )
186 vals.insert( make_pair( op_val->first, getOptionValue( op_val->first, GET_DEFAULT() )));
191 std::vector <std::string> MgAdapt::getOptionValuesStrVec() const
193 std::vector <std::string> vals;
194 TOptionValues::const_iterator op_val = _option2value.begin();
195 for ( ; op_val != _option2value.end(); ++op_val )
196 vals.push_back(op_val->first+":"+getOptionValue( op_val->first, GET_DEFAULT() ));
201 std::vector <std::string> MgAdapt::getCustomOptionValuesStrVec() const
203 std::vector <std::string> vals;
204 TOptionValues::const_iterator op_val;
205 for ( op_val = _customOption2value.begin(); op_val != _customOption2value.end(); ++op_val )
207 vals.push_back(op_val->first+":"+getOptionValue( op_val->first, GET_DEFAULT() ));
211 const TOptionValues& MgAdapt::getCustomOptionValues() const
213 return _customOption2value;
215 void MgAdapt::setData(MgAdaptHypothesisData* myData)
217 copyMgAdaptHypothesisData(myData);
220 MgAdaptHypothesisData* MgAdapt::getData() const
224 void MgAdapt::setMedFileIn(std::string fileName)
226 if ( isFileExist(fileName) )
228 medFileIn = fileName;
230 if (medFileOut == "") // default MED file Out
231 medFileOut = remove_extension( fileName )+ ".adapt.med";
235 SALOME::ExceptionStruct es;
236 es.type = SALOME::BAD_PARAM;
237 std::string text = "\nThe file " + fileName + " does not exist.\n" ;
238 es.text = CORBA::string_dup(text.c_str());
239 throw SALOME::SALOME_Exception(es);
243 std::string MgAdapt::getMedFileIn()
248 void MgAdapt::setMedFileOut(std::string fileOut)
250 medFileOut = fileOut;
252 std::string MgAdapt::getMedFileOut()
256 void MgAdapt::setMeshOutMed(bool mybool)
260 bool MgAdapt::getMeshOutMed()
264 void MgAdapt::setPublish(bool mybool)
268 bool MgAdapt::getPublish()
272 void MgAdapt::setFieldName(std::string myFieldName)
274 fieldName = myFieldName;
276 std::string MgAdapt::getFieldName()
280 void MgAdapt::setTimeStep(int time)
284 int MgAdapt::getTimeStep() const
289 void MgAdapt::setRankTimeStep(int time, int myRank)
295 int MgAdapt::getRank()
299 void MgAdapt::setTimeStepRankLast()
301 myUseLastTimeStep = true;
302 myUseChosenTimeStep = false;
303 myUseNoTimeStep = false;
304 //~med_int aRank, tmst;
305 //~std::string fieldFile = useBackgroundMap ? sizeMapFile : medFileIn;
306 //~getTimeStepInfos(fieldFile, tmst, aRank);
307 //~setRankTimeStep((int) tmst, (int) aRank);
309 void MgAdapt::setNoTimeStep()
311 myUseLastTimeStep = false;
312 myUseChosenTimeStep = false;
313 myUseNoTimeStep = true;
314 //~int aRank = (int)MED_NO_IT;
315 //~int tmst = (int)MED_NO_DT ;
316 //~setRankTimeStep(tmst, aRank);
318 void MgAdapt::setChosenTimeStepRank()
320 myUseLastTimeStep = false;
321 myUseChosenTimeStep = true;
322 myUseNoTimeStep = false;
323 //~int aRank = (int)MED_NO_IT;
324 //~int tmst = (int)MED_NO_DT ;
325 //~setRankTimeStep(tmst, aRank);
327 void MgAdapt::setUseLocalMap(bool myLocal)
329 useLocalMap = myLocal;
332 bool MgAdapt::getUseLocalMap()
337 void MgAdapt::setUseBackgroundMap(bool bckg)
339 useBackgroundMap = bckg;
342 bool MgAdapt::getUseBackgroundMap()
344 return useBackgroundMap;
347 void MgAdapt::setUseConstantValue(bool cnst)
349 useConstantValue = cnst;
351 bool MgAdapt::getUseConstantValue()
353 return useConstantValue;
355 void MgAdapt::setLogFile(std::string myLogFile)
359 std::string MgAdapt::getLogFile()
363 void MgAdapt::setVerbosityLevel(int verboLevel)
365 verbosityLevel = verboLevel;
367 int MgAdapt::getVerbosityLevel()
369 return verbosityLevel;
371 void MgAdapt::setRemoveOnSuccess(bool rmons)
373 removeOnSuccess = rmons;
375 bool MgAdapt::getRemoveOnSuccess()
377 return removeOnSuccess;
379 void MgAdapt::setSizeMapFile(std::string mapFile)
381 if ( mapFile == "" || isFileExist(mapFile) )
383 sizeMapFile = mapFile;
387 SALOME::ExceptionStruct es;
388 es.type = SALOME::BAD_PARAM;
389 std::string text = "\nThe file " + mapFile + " does not exist.\n" ;
390 es.text = CORBA::string_dup(text.c_str());
391 throw SALOME::SALOME_Exception(es);
394 std::string MgAdapt::getSizeMapFile()
399 void MgAdapt::setMeshName(std::string name)
403 std::string MgAdapt::getMeshName()
407 void MgAdapt::setMeshNameOut(std::string name)
411 std::string MgAdapt::getMeshNameOut()
415 void MgAdapt::setFromMedFile(bool mybool)
417 fromMedFile = mybool;
419 bool MgAdapt::isFromMedFile()
423 void MgAdapt::setConstantValue(double cnst)
425 constantValue = cnst;
427 double MgAdapt::getConstantValue() const
429 return constantValue;
432 void MgAdapt::setWorkingDir(std::string dir)
436 std::string MgAdapt::getWorkingDir() const
440 void MgAdapt::setKeepWorkingFiles(bool mybool)
442 toKeepWorkingFiles = mybool;
444 bool MgAdapt::getKeepWorkingFiles()
446 return toKeepWorkingFiles;
448 void MgAdapt::setPrintLogInFile(bool print)
450 printLogInFile = print;
452 bool MgAdapt::getPrintLogInFile()
454 return printLogInFile;
457 bool MgAdapt::setAll()
460 setFromMedFile(data->fromMedFile);
462 checkDirPath(data->myFileInDir);
463 file = data->myFileInDir+data->myMeshFileIn;
465 setMeshName(data->myInMeshName);
466 setMeshNameOut(data->myOutMeshName);
467 checkDirPath(data->myFileOutDir);
468 std::string out = data->myFileOutDir+data->myMeshFileOut;
470 setPublish(data->myPublish);
471 setMeshOutMed(data->myMeshOutMed);
472 setUseLocalMap(data->myUseLocalMap);
473 setUseBackgroundMap(data->myUseBackgroundMap);
474 setUseConstantValue(data->myUseConstantValue);
477 if (useBackgroundMap)
479 checkDirPath(data->myFileSizeMapDir);
480 mapfile = data->myFileSizeMapDir+data->myMeshFileBackground;
481 setFieldName(data->myFieldName);
483 else if (useConstantValue)
485 setConstantValue(data->myConstantValue);
490 setConstantValue(0.0);
491 setFieldName(data->myFieldName);
494 setSizeMapFile(mapfile);
495 if (data->myUseNoTimeStep)
497 else if (data->myUseLastTimeStep)
498 setTimeStepRankLast();
501 setChosenTimeStepRank();
502 setRankTimeStep(data->myTimeStep, data->myRank);
504 /* Advanced options */
505 setWorkingDir(data->myWorkingDir);
506 checkDirPath(data->myWorkingDir);
507 setLogFile(data->myWorkingDir+defaultLogFile());
508 setVerbosityLevel(data->myVerboseLevel);
509 setRemoveOnSuccess(data->myRemoveLogOnSuccess);
510 setPrintLogInFile(data->myPrintLogInFile);
511 setKeepWorkingFiles(data->myKeepFiles);
516 void MgAdapt::checkDirPath(std::string& dirPath)
518 const char lastChar = *dirPath.rbegin();
520 if(lastChar != '\\') dirPath+='\\';
522 if(lastChar != '/') dirPath+='/';
525 //=============================================================================
526 void MgAdapt::setOptionValue(const std::string& optionName,
527 const std::string& optionValue)
528 throw (std::invalid_argument)
530 // INFOS("setOptionValue");
531 // std::cout << "optionName: " << optionName << ", optionValue: " << optionValue << std::endl;
532 TOptionValues::iterator op_val = _option2value.find(optionName);
533 if (op_val == _option2value.end())
535 op_val = _customOption2value.find( optionName );
536 _customOption2value[ optionName ] = optionValue;
540 if (op_val->second != optionValue)
542 std::string lowerOptionValue = toLowerStr(optionValue);
543 const char* ptr = lowerOptionValue.c_str();
544 // strip white spaces
545 while (ptr[0] == ' ')
548 while (i != 0 && ptr[i - 1] == ' ')
552 std::string typeName;
557 else if (_charOptions.count(optionName))
559 // do not check strings
561 else if (_doubleOptions.count(optionName))
563 // check if value is double
567 else if (_boolOptions.count(optionName))
569 // check if value is bool
570 toBool(ptr, &typeOk);
575 // check if value is int
577 typeName = "integer";
579 if ( typeOk ) // check some specific values ?
584 std::string msg = "Advanced option '" + optionName + "' = '" + optionValue + "' but must be " + typeName;
585 throw std::invalid_argument(msg);
587 std::string value( ptr, i );
588 // std::cout << "==> value: " << value << std::endl;
589 if ( _defaultOptionValues[ optionName ] == value ) value.clear();
591 // std::cout << "==> value: " << value << std::endl;
592 op_val->second = value;
595 //=============================================================================
596 //! Return option value. If isDefault provided, it can be a default value,
597 // then *isDefault == true. If isDefault is not provided, the value will be
598 // empty if it equals a default one.
599 std::string MgAdapt::getOptionValue(const std::string& optionName, bool* isDefault) const
600 throw (std::invalid_argument)
602 // INFOS("getOptionValue");
603 // std::cout << "optionName: " << optionName << ", isDefault: " << isDefault << std::endl;
604 TOptionValues::const_iterator op_val = _option2value.find(optionName);
605 if (op_val == _option2value.end())
607 op_val = _customOption2value.find(optionName);
608 if (op_val == _customOption2value.end())
610 std::string msg = "Unknown MG-Adapt option: <" + optionName + ">";
611 throw std::invalid_argument(msg);
614 std::string val = op_val->second;
615 if ( isDefault ) *isDefault = ( val.empty() );
617 if ( val.empty() && isDefault )
619 op_val = _defaultOptionValues.find( optionName );
620 if (op_val != _defaultOptionValues.end()) val = op_val->second;
622 // std::cout << "==> val: " << val << std::endl;
626 //================================================================================
628 * \brief Converts a string to a real value
630 //================================================================================
632 double MgAdapt::toDbl(const std::string& str, bool* isOk )
633 throw (std::invalid_argument)
635 if ( str.empty() ) throw std::invalid_argument("Empty value provided");
638 double val = strtod(&str[0], &endPtr);
639 bool ok = (&str[0] != endPtr);
641 if ( isOk ) *isOk = ok;
645 std::string msg = "Not a real value:'" + str + "'";
646 throw std::invalid_argument(msg);
650 //================================================================================
652 * \brief Converts a string to a lower
654 //================================================================================
655 std::string MgAdapt::toLowerStr(const std::string& str)
658 for ( size_t i = 0; i <= s.size(); ++i )
659 s[i] = tolower( s[i] );
662 //================================================================================
664 * \brief Converts a string to a bool
666 //================================================================================
668 bool MgAdapt::toBool(const std::string& str, bool* isOk )
669 throw (std::invalid_argument)
672 if ( isOk ) *isOk = true;
674 for ( size_t i = 0; i <= s.size(); ++i )
675 s[i] = tolower( s[i] );
677 if ( s == "1" || s == "true" || s == "active" || s == "yes" )
680 if ( s == "0" || s == "false" || s == "inactive" || s == "no" )
687 std::string msg = "Not a Boolean value:'" + str + "'";
688 throw std::invalid_argument(msg);
692 //================================================================================
694 * \brief Converts a string to a integer value
696 //================================================================================
698 int MgAdapt::toInt(const std::string& str, bool* isOk )
699 throw (std::invalid_argument)
701 if ( str.empty() ) throw std::invalid_argument("Empty value provided");
704 int val = (int)strtol( &str[0], &endPtr, 10);
705 bool ok = (&str[0] != endPtr);
707 if ( isOk ) *isOk = ok;
711 std::string msg = "Not an integer value:'" + str + "'";
712 throw std::invalid_argument(msg);
716 //=============================================================================
717 bool MgAdapt::hasOptionDefined( const std::string& optionName ) const
719 bool isDefault = false;
722 getOptionValue( optionName, &isDefault );
724 catch ( std::invalid_argument )
730 //================================================================================
732 * \brief Return command to run MG-Tetra mesher excluding file prefix (-f)
734 //================================================================================
736 std::string MgAdapt::getCommandToRun(MgAdapt* hyp)
738 return hyp ? hyp->getCommandToRun() : ToComment("error with hypothesis!");
743 int MgAdapt::compute(std::string& errStr)
745 std::string cmd = getCommandToRun();
746 // std::cout << cmd << std::endl;
749 execCmd( cmd.c_str(), err ); // run
753 errStr = ToComment("system(mg-adapt.exe ...) command failed with error: ") << strerror( errno );
757 convertMeshFile(meshFormatOutputMesh, solFormatOutput);
763 void MgAdapt::execCmd( const char* cmd, int& err)
766 std::array <char, 128> buffer;
768 outFileStream fileStream;
771 fileStream.open(logFile);
772 buf = fileStream.rdbuf();
776 buf = std::cout.rdbuf();
778 std::ostream logStream(buf);
780 std::unique_ptr <FILE, decltype(&pclose)> pipe(popen(cmd, "r"), pclose );
783 throw std::runtime_error("popen() failed!");
785 while(fgets(buffer.data(), buffer.size(), pipe.get()) !=nullptr )
787 logStream<<buffer.data() ;
792 * to delete tmp files .mesh, .sol and if needed
796 void MgAdapt::cleanUp()
800 if(toKeepWorkingFiles)
802 if(removeOnSuccess && printLogInFile)
803 tmpFilesToBeDeleted.push_back(logFile);
805 std::vector< std::string>::iterator it = tmpFilesToBeDeleted.begin();
806 for (; it!=tmpFilesToBeDeleted.end(); ++it)
808 errStr=removeFile(*it, notOk);
811 appendMsgToLogFile(errStr);
817 void MgAdapt::appendMsgToLogFile(std::string& msg)
819 std::ofstream logStream;
820 logStream.open(logFile, std::ofstream::out | std::ofstream::app);
824 //================================================================================
826 * \brief Return command to run MG-Tetra mesher excluding file prefix (-f)
828 //================================================================================
830 std::string MgAdapt::getCommandToRun()
833 || return system command with args and options
837 std::string cmd = getExeName();
838 std::string meshIn(""), sizeMapIn(""), solFileIn("");
839 updateTimeStepRank();
840 convertMedFile(meshIn, solFileIn, sizeMapIn);
841 if (!isFileExist(meshIn) || !isFileExist(solFileIn))
843 errStr = ToComment(" failed to find .mesh or .sol file from converter ")<< strerror( errno );
846 tmpFilesToBeDeleted.push_back(meshIn);
847 tmpFilesToBeDeleted.push_back(solFileIn);
848 if(useBackgroundMap && !isFileExist(sizeMapIn))
850 errStr = ToComment(" failed to find .mesh size map file from converter ")<< strerror( errno );
854 cmd+= " --in "+ meshIn;
855 meshFormatOutputMesh = getFileName()+".mesh";
856 tmpFilesToBeDeleted.push_back(meshFormatOutputMesh);
857 cmd+= " --out "+ meshFormatOutputMesh;
858 if (useLocalMap || useConstantValue) cmd+= " --sizemap "+ solFileIn;
859 else // (useBackgroundMap)
861 cmd+= " --background_mesh "+ sizeMapIn ;
862 cmd+= " --background_sizemap "+ solFileIn;
863 tmpFilesToBeDeleted.push_back(sizeMapIn);
867 //~// constant value TODO
869 // Check coherence between mesh dimension and option fo adaptation
870 checkDimensionOptionAdaptation();
872 // sizemap file is written only if level is higher than 3
873 if ( verbosityLevel > 3)
875 std::string solFileOut = getFileName()+".sol";
876 cmd+= " --write_sizemap "+ solFileOut;
877 solFormatOutput.push_back(solFileOut);
878 tmpFilesToBeDeleted.push_back(solFileOut);
881 std::string option, value;
883 const TOptionValues* options[] = { &_option2value, &_customOption2value };
884 for ( int iOp = 0; iOp < 2; ++iOp )
886 TOptionValues::const_iterator o2v = options[iOp]->begin();
887 for ( ; o2v != options[iOp]->end(); ++o2v )
890 value = getOptionValue( option, &isDefault );
894 if ( value.empty() )//value == NoValue() )
896 if ( _defaultOptionValues.count( option ))
897 continue; // non-custom option with no value
900 if ( strncmp( "no", option.c_str(), 2 ) == 0 ) // options w/o values: --no_*
902 if ( !value.empty() && toBool( value ) == false )
906 if ( option[0] != '-' )
910 // std::cout << "--- option: '" << option << ", value: '" << value <<"'"<< std::endl;
911 cmd += option + " " + value;
916 if (verbosityLevel != defaultVerboseLevel())
918 cmd+= " --verbose "+ ToComment(verbosityLevel);
925 // std::cout << "--- cmd :"<< std::endl;
926 // std::cout << cmd << std::endl;
931 bool MgAdapt::isFileExist(const std::string& fName)
934 if ( fName.empty() ) return false;
936 boost::system::error_code err;
937 bool res = boost::filesystem::exists( fName, err );
939 return err ? false : res;
941 //=======================================================================
942 //function : defaultMaximumMemory
943 //=======================================================================
947 #elif !defined(__APPLE__)
948 #include <sys/sysinfo.h>
951 double MgAdapt::defaultMaximumMemory()
954 // See http://msdn.microsoft.com/en-us/library/aa366589.aspx
955 MEMORYSTATUSEX statex;
956 statex.dwLength = sizeof (statex);
957 long err = GlobalMemoryStatusEx (&statex);
960 double totMB = (double)statex.ullAvailPhys / 1024. / 1024.;
961 return (double)( 0.7 * totMB );
963 #elif !defined(__APPLE__)
965 long err = sysinfo( &si );
968 long ramMB = si.totalram * si.mem_unit / 1024 / 1024;
969 return ( 0.7 * ramMB );
975 //=======================================================================
976 //function : defaultWorkingDirectory
977 //=======================================================================
979 std::string MgAdapt::defaultWorkingDirectory()
981 TCollection_AsciiString aTmpDir;
983 char *Tmp_dir = getenv("SALOME_TMP_DIR");
990 aTmpDir = TCollection_AsciiString("C:\\");
992 aTmpDir = TCollection_AsciiString("/tmp/");
995 return aTmpDir.ToCString();
997 //================================================================================
999 * \brief Return a unique file name
1001 //================================================================================
1003 std::string MgAdapt::getFileName() const
1005 std::string aTmpDir = workingDir;
1006 const char lastChar = *aTmpDir.rbegin();
1008 if(lastChar != '\\') aTmpDir+='\\';
1010 if(lastChar != '/') aTmpDir+='/';
1013 TCollection_AsciiString aGenericName = (char*)aTmpDir.c_str();
1014 aGenericName += "MgAdapt_";
1015 aGenericName += getpid();
1016 aGenericName += "_";
1017 aGenericName += Abs((Standard_Integer)(long) aGenericName.ToCString());
1019 return aGenericName.ToCString();
1021 //=======================================================================
1022 //function : defaultLogFile
1023 //=======================================================================
1025 std::string MgAdapt::defaultLogFile()
1027 std::string alogFile("MG_ADAPT.log");
1030 //=======================================================================
1031 //function : defaultUseConstantValue
1032 //=======================================================================
1034 bool MgAdapt::defaultUseConstantValue()
1038 //=======================================================================
1039 //function : defaultUseNoTimeStep
1040 //=======================================================================
1042 bool MgAdapt::defaultUseNoTimeStep()
1046 //=======================================================================
1047 //function : defaultRemoveLogOnSuccess
1048 //=======================================================================
1050 bool MgAdapt::defaultRemoveLogOnSuccess()
1054 //=======================================================================
1055 //function : defaultPrintLogInFile
1056 //=======================================================================
1058 bool MgAdapt::defaultPrintLogInFile()
1062 //=======================================================================
1063 //function : defaultUseChosenTimeStep
1064 //=======================================================================
1066 bool MgAdapt::defaultUseChosenTimeStep()
1070 //=======================================================================
1071 //function : UseLastTimeStep
1072 //=======================================================================
1074 bool MgAdapt::defaultUseLastTimeStep()
1078 //=======================================================================
1079 //function : defaultUseBackgroundMap
1080 //=======================================================================
1082 bool MgAdapt::defaultUseBackgroundMap()
1086 //=======================================================================
1087 //function : defaultKeepFiles
1088 //=======================================================================
1090 bool MgAdapt::defaultKeepFiles()
1094 //=======================================================================
1095 //function : defaultUseLocalMap
1096 //=======================================================================
1098 bool MgAdapt::defaultUseLocalMap()
1102 //=======================================================================
1103 //function : defaultPublish
1104 //=======================================================================
1106 bool MgAdapt::defaultPublish()
1110 //=======================================================================
1111 //function : defaultMeshOutMed
1112 //=======================================================================
1114 bool MgAdapt::defaultMeshOutMed()
1118 //=======================================================================
1119 //function : defaultFromMedFile
1120 //=======================================================================
1122 bool MgAdapt::defaultFromMedFile()
1126 //=======================================================================
1127 //function : defaultVerboseLevel
1128 //=======================================================================
1130 int MgAdapt::defaultVerboseLevel()
1134 std::string MgAdapt::getExeName()
1136 return "mg-adapt.exe";
1138 void MgAdapt::copyMgAdaptHypothesisData( const MgAdaptHypothesisData* from)
1140 data->myFileInDir = from->myFileInDir;
1141 data->myMeshFileIn = from->myMeshFileIn;
1142 data->myMeshFileBackground = from->myMeshFileBackground;
1143 data->myOutMeshName = from->myOutMeshName;
1144 data->myMeshFileOut = from->myMeshFileOut;
1145 data->myFileOutDir = from->myFileOutDir;
1146 data->myFileSizeMapDir = from->myFileSizeMapDir;
1147 data->myFieldName = from->myFieldName;
1148 data->fromMedFile = from->fromMedFile;
1149 data->myPublish = from->myPublish;
1150 data->myMeshOutMed = from->myMeshOutMed;
1151 data->myUseLocalMap = from->myUseLocalMap;
1152 data->myUseBackgroundMap = from->myUseBackgroundMap;
1153 data->myUseConstantValue = from->myUseConstantValue;
1154 data->myConstantValue = from->myConstantValue;
1155 data->myTimeStep = from->myTimeStep;
1156 data->myRank = from->myRank;
1157 data->myUseNoTimeStep = from->myUseNoTimeStep;
1158 data->myUseLastTimeStep = from->myUseLastTimeStep;
1159 data->myUseChosenTimeStep = from->myUseChosenTimeStep;
1160 data->myWorkingDir = from->myWorkingDir;
1161 data->myLogFile = from->myLogFile;
1162 data->myPrintLogInFile = from->myPrintLogInFile;
1163 data->myKeepFiles = from->myKeepFiles;
1164 data->myRemoveLogOnSuccess = from->myRemoveLogOnSuccess;
1165 data->myVerboseLevel = from->myVerboseLevel;
1168 std::vector<std::string> MgAdapt::getListFieldsNames(std::string fileIn)
1170 MEDCoupling::MCAuto<MEDCoupling::MEDFileData> mfd = MEDCoupling::MEDFileData::New(fileIn);
1171 std::vector<std::string> listFieldsNames(mfd->getFields()->getFieldsNames());
1172 return listFieldsNames ;
1175 void MgAdapt::checkDimensionOptionAdaptation()
1177 // Quand le maillage est 3D, tout est possible
1178 // Quand le maillage est 2D, il faut 'surface' sauf si carte de fonds 3D
1179 MEDCoupling::MCAuto<MEDCoupling::MEDFileData> mfd = MEDCoupling::MEDFileData::New(medFileIn);
1180 int meshdim = mfd->getMeshes()->getMeshAtPos(0)->getMeshDimension() ;
1181 // std::cout << "meshdim = " << meshdim << std::endl;
1185 std::string optionName = "adaptation";
1186 std::string optionValue = getOptionValue(optionName);
1187 // std::cout << "optionValue = '" << optionValue <<"'"<< std::endl;
1188 bool a_tester = false ;
1189 // carte locale ou constante : impératif d'avoir "surface"
1190 if ( useLocalMap || useConstantValue) a_tester = true ;
1191 // carte de fond : impératif d'avoir "surface" si le fonds est aussi 2D
1194 MEDCoupling::MCAuto<MEDCoupling::MEDFileData> mfdbg = MEDCoupling::MEDFileData::New(sizeMapFile);
1195 int meshdimbg = mfdbg->getMeshes()->getMeshAtPos(0)->getMeshDimension() ;
1196 // std::cout << "meshdimbg = " << meshdimbg << std::endl;
1197 if ( meshdimbg == 2 ) a_tester = true ;
1201 if ( optionValue == "" ) setOptionValue (optionName, "surface");
1204 if ( optionValue != "surface" )
1206 SALOME::ExceptionStruct es;
1207 es.type = SALOME::BAD_PARAM;
1208 std::string text = "Mesh dimension is 2; the option should be 'surface' instead of '" + optionValue + "'." ;
1209 es.text = CORBA::string_dup(text.c_str());
1210 throw SALOME::SALOME_Exception(es);
1217 void MgAdapt::checkFieldName(std::string fileIn)
1220 std::vector<std::string> listFieldsNames = getListFieldsNames(fileIn);
1221 std::size_t jaux(listFieldsNames.size());
1222 for(std::size_t j=0;j<jaux;j++)
1224 if ( fieldName == listFieldsNames[j] )
1232 std::cout << "Available field names:" << std::endl;
1233 for(std::size_t j=0;j<jaux;j++)
1234 { std::cout << listFieldsNames[j] << std::endl;}
1235 SALOME::ExceptionStruct es;
1236 es.type = SALOME::BAD_PARAM;
1237 std::string text = "Field " + fieldName + " is not found." ;
1238 es.text = CORBA::string_dup(text.c_str());
1239 throw SALOME::SALOME_Exception(es);
1243 void MgAdapt::checkTimeStepRank(std::string fileIn)
1246 MEDCoupling::MCAuto<MEDCoupling::MEDFileData> mfd = MEDCoupling::MEDFileData::New(fileIn);
1247 MEDCoupling::MCAuto<MEDCoupling::MEDFileAnyTypeFieldMultiTS> fts = dynamic_cast<MEDCoupling::MEDFileFieldMultiTS *>( mfd->getFields()->getFieldWithName(fieldName) );
1248 // std::cout << "--- timeStep " << timeStep << std::endl;
1249 // std::cout << "--- rank " << rank << std::endl;
1250 std::vector<double> timevalue;
1251 std::vector< std::pair<int,int> > timesteprank = fts->getTimeSteps(timevalue);
1252 std::size_t jaux(timesteprank.size());
1253 for(std::size_t j=0;j<jaux;j++)
1255 if ( ( timeStep == timesteprank[j].first ) & ( rank == timesteprank[j].second ) )
1263 std::cout << "Available (Time step, Rank):" << std::endl;
1264 for(std::size_t j=0;j<jaux;j++)
1265 { std::cout << "(Time step = " << timesteprank[j].first << ", Rank = " << timesteprank[j].second << ")" << std::endl;}
1266 SALOME::ExceptionStruct es;
1267 es.type = SALOME::BAD_PARAM;
1268 std::string text = "(Time step = " + std::to_string(timeStep) + ", Rank = " + std::to_string(rank) + ") is not found." ;
1269 es.text = CORBA::string_dup(text.c_str());
1270 throw SALOME::SALOME_Exception(es);
1274 void MgAdapt::convertMedFile(std::string& meshFormatMeshFileName, std::string& solFormatFieldFileName, std::string& meshFormatsizeMapFile)
1276 std::vector<std::string> fieldFileNames;
1277 MEDCoupling::MeshFormatWriter writer;
1278 MEDCoupling::MCAuto<MEDCoupling::MEDFileData> mfd = MEDCoupling::MEDFileData::New(medFileIn);
1279 MEDCoupling::MEDFileMeshes* meshes = mfd->getMeshes();
1280 MEDCoupling::MEDFileMesh* fileMesh = meshes->getMeshAtPos(0); // ok only one mesh in file!
1281 if (meshNameOut =="")
1282 meshNameOut = fileMesh->getName();
1283 storeGroupsAndFams(fileMesh);
1285 MEDCoupling::MCAuto<MEDCoupling::MEDFileFields> fields = MEDCoupling::MEDFileFields::New();
1286 solFormatFieldFileName = getFileName();
1287 solFormatFieldFileName+=".sol";
1288 fieldFileNames.push_back(solFormatFieldFileName);
1290 if (useBackgroundMap)
1292 checkFieldName(sizeMapFile) ;
1293 checkTimeStepRank(sizeMapFile) ;
1294 meshFormatsizeMapFile = getFileName();
1295 meshFormatsizeMapFile += ".mesh";
1296 buildBackGroundMeshAndSolFiles(fieldFileNames, meshFormatsizeMapFile);
1298 else if(useLocalMap)
1300 checkFieldName(medFileIn) ;
1301 checkTimeStepRank(medFileIn) ;
1302 MEDCoupling::MCAuto<MEDCoupling::MEDFileAnyTypeFieldMultiTS> fts = dynamic_cast<MEDCoupling::MEDFileFieldMultiTS *>( mfd->getFields()->getFieldWithName(fieldName) );
1303 MEDCoupling::MCAuto<MEDCoupling::MEDFileAnyTypeField1TS> f = fts->getTimeStep(timeStep, rank);
1304 MEDCoupling::MCAuto<MEDCoupling::MEDFileFieldMultiTS> tmFts = MEDCoupling::MEDFileFieldMultiTS::New();
1305 tmFts->pushBackTimeStep(f);
1307 fields->pushField(tmFts);
1309 writer.setFieldFileNames( fieldFileNames);
1313 MEDCoupling::MCAuto<MEDCoupling::MEDCouplingMesh> mesh = fileMesh->getMeshAtLevel(1); // nodes mesh
1314 MEDCoupling::MCAuto<MEDCoupling::MEDCouplingUMesh> umesh = mesh->buildUnstructured(); // nodes mesh
1315 int dim = umesh->getSpaceDimension();
1316 int version = sizeof(double) < 8 ? 1 : 2;
1317 mcIdType nbNodes = umesh->getNumberOfNodes();
1318 buildConstantSizeMapSolFile(solFormatFieldFileName, dim, version, nbNodes);
1321 mfd->setFields( fields );
1322 meshFormatMeshFileName = getFileName();
1323 meshFormatMeshFileName+=".mesh";
1324 writer.setMeshFileName(meshFormatMeshFileName);
1325 writer.setMEDFileDS( mfd);
1330 void MgAdapt::convertMeshFile(std::string& meshFormatIn, std::vector< std::string>& solFieldFileNames) const
1332 MEDCoupling::MeshFormatReader reader(meshFormatIn, solFieldFileNames);
1334 MEDCoupling::MCAuto<MEDCoupling::MEDFileData> mfd = reader.loadInMedFileDS();
1336 MEDCoupling::MEDFileMeshes* meshes = mfd->getMeshes();
1337 MEDCoupling::MEDFileMesh* fileMesh = meshes->getMeshAtPos(0); // ok only one mesh in file!
1338 fileMesh->setName(meshNameOut);
1339 restoreGroupsAndFams(fileMesh);
1340 mfd->write(medFileOut, 2);
1343 void MgAdapt::storeGroupsAndFams(MEDCoupling::MEDFileMesh* fileMesh)
1345 storefams(fileMesh);
1346 storeGroups(fileMesh);
1349 void MgAdapt::restoreGroupsAndFams(MEDCoupling::MEDFileMesh* fileMesh) const
1351 restorefams(fileMesh);
1352 restoreGroups(fileMesh);
1354 void MgAdapt::storeGroups(MEDCoupling::MEDFileMesh* fileMesh)
1356 std::map<std::string, std::vector<std::string> > grpFams = fileMesh->getGroupInfo();
1357 std::map<std::string, std::vector<std::string> >::iterator g2ff = grpFams.begin();
1359 for ( ; g2ff != grpFams.end(); ++g2ff )
1361 std::string groupName = g2ff->first;
1362 std::vector<std::string> famNames = g2ff->second;
1364 if ( famNames.empty() ) continue;
1366 std::vector< mcIdType> famListId;
1367 for ( size_t i = 0; i < famNames.size(); ++i )
1369 famListId.push_back( fileMesh->getFamilyId( famNames[i].c_str() ) );
1371 group grp(groupName, famListId, famNames);
1372 groupVec.push_back(grp);
1376 void MgAdapt::storefams(MEDCoupling::MEDFileMesh* fileMesh)
1378 std::map<std::string, mcIdType> grpFams = fileMesh->getFamilyInfo();
1379 std::map<std::string, mcIdType >::iterator f = grpFams.begin();
1381 for ( ; f != grpFams.end(); ++f )
1383 if(!f->second) continue; // FAMILLE_ZERO
1384 family fs(f->first, f->second);
1385 famVec.push_back(fs);
1390 void MgAdapt::restorefams(MEDCoupling::MEDFileMesh* fileMesh) const
1392 std::vector<family>::const_iterator fIt = famVec.begin();
1394 for (; fIt!=famVec.end(); ++fIt)
1398 std::string givenFamNameFromMeshGemConverter = fileMesh->getFamilyNameGivenId( std::abs(fIt->_famId) );
1399 fileMesh->changeFamilyId(std::abs(fIt->_famId), fIt->_famId);
1400 fileMesh->changeFamilyName(givenFamNameFromMeshGemConverter, fIt->_famName);
1402 catch (const std::exception& e)
1404 std::cerr<<e.what();
1409 void MgAdapt::restoreGroups(MEDCoupling::MEDFileMesh* fileMesh) const
1411 std::map<std::string, std::vector<std::string> > info;
1412 std::vector <group>::const_iterator grpFams = groupVec.begin();
1414 for (; grpFams!=groupVec.end(); ++grpFams)
1416 info.insert(std::pair <std::string, std::vector<std::string> > (grpFams->_name, grpFams->_famNames) );
1419 fileMesh->setGroupInfo(info);
1422 void MgAdapt::buildConstantSizeMapSolFile(const std::string& solFormatFieldFileName, const int dim, const int version, const mcIdType nbNodes) const
1424 MeshFormat::Localizer loc;
1425 MeshFormat::MeshFormatParser writer;
1426 int fileId = writer.GmfOpenMesh( solFormatFieldFileName.c_str(), GmfWrite, version, dim);
1427 int typTab[] = {GmfSca};
1428 writer.GmfSetKwd(fileId, MeshFormat::GmfSolAtVertices, (int)nbNodes, 1, typTab);
1429 for (mcIdType i = 0; i<nbNodes; i++)
1431 double valTab[1] = {constantValue};
1432 writer.GmfSetLin( fileId, MeshFormat::GmfSolAtVertices, valTab);
1434 writer.GmfCloseMesh(fileId);
1437 void MgAdapt::buildBackGroundMeshAndSolFiles(const std::vector<std::string>& fieldFileNames, const std::string& meshFormatsizeMapFile) const
1439 MEDCoupling::MCAuto<MEDCoupling::MEDFileData> tmpMfd = MEDCoupling::MEDFileData::New(sizeMapFile);
1440 MEDCoupling::MEDFileFields* tmpFields = tmpMfd->getFields();
1441 MEDCoupling::MEDFileAnyTypeFieldMultiTS* fts = tmpFields->getFieldWithName(fieldName);
1442 MEDCoupling::MCAuto<MEDCoupling::MEDFileFieldMultiTS> fts1 = dynamic_cast<MEDCoupling::MEDFileFieldMultiTS *>(fts);
1443 MEDCoupling::MCAuto<MEDCoupling::MEDFileAnyTypeField1TS> f = fts1->getTimeStep(timeStep, rank);
1444 MEDCoupling::MCAuto<MEDCoupling::MEDFileFieldMultiTS> tmFts = MEDCoupling::MEDFileFieldMultiTS::New();
1445 tmFts->pushBackTimeStep(f);
1447 MEDCoupling::MCAuto<MEDCoupling::MEDFileFields> tmp_fields = MEDCoupling::MEDFileFields::New();
1448 tmp_fields->pushField(tmFts);
1450 tmpMfd->setFields( tmp_fields );
1451 MEDCoupling::MeshFormatWriter tmpWriter;
1452 tmpWriter.setMeshFileName(meshFormatsizeMapFile);
1453 tmpWriter.setFieldFileNames( fieldFileNames);
1454 tmpWriter.setMEDFileDS(tmpMfd);
1457 // =======================================================================
1458 med_idt MgAdapt::openMedFile(const std::string aFile)
1459 // =======================================================================
1460 // renvoie le medId associe au fichier Med apres ouverture
1462 med_idt medIdt = MEDfileOpen(aFile.c_str(),MED_ACC_RDONLY);
1465 SALOME::ExceptionStruct es;
1466 es.type = SALOME::BAD_PARAM;
1467 std::string text = "\nThe med file " + aFile + " cannot be opened.\n" ;
1468 es.text = CORBA::string_dup(text.c_str());
1469 throw SALOME::SALOME_Exception(es);
1474 MgAdapt::Status MgAdapt::addMessage(const std::string& msg,
1475 const bool isFatal/*=false*/)
1478 _myErrorMessages.clear(); // warnings are useless if a fatal error encounters
1480 _myErrorMessages.push_back( msg );
1484 std::cout << msg << std::endl;
1486 return ( _myStatus = isFatal ? MgAdapt::DRS_FAIL : MgAdapt::DRS_WARN_SKIP_ELEM );
1489 // =======================================================================
1490 void MgAdapt::getTimeStepInfos(std::string aFile, med_int& numdt, med_int& numit)
1491 // =======================================================================
1493 // Il faut voir si plusieurs maillages
1499 // Ouverture du fichier
1500 //~SCRUTE(aFile.toStdString());
1501 medIdt = openMedFile(aFile);
1502 if ( medIdt < 0 ) return ;
1503 // Lecture du nombre de champs
1504 med_int ncha = MEDnField(medIdt) ;
1507 //~addMessage( ToComment(" error: there is no field in ") << aFile, /*fatal=*/true );
1510 // Lecture des caracteristiques du champs
1512 // Lecture du type du champ, des noms des composantes et du nom de l'unite
1513 char nomcha [MED_NAME_SIZE+1];
1514 strcpy(nomcha, fieldName.c_str());
1515 // Lecture du nombre de composantes
1516 med_int ncomp = MEDfieldnComponentByName(medIdt, nomcha);
1517 char meshname[MED_NAME_SIZE+1];
1518 char * comp = (char*) malloc(ncomp*MED_SNAME_SIZE+1);
1519 char * unit = (char*) malloc(ncomp*MED_SNAME_SIZE+1);
1520 char dtunit[MED_SNAME_SIZE+1];
1522 med_field_type typcha;
1524 erreur = MEDfieldInfoByName (medIdt, nomcha, meshname,&local,&typcha,comp,unit,dtunit, &nbofcstp);
1529 //~addMessage( ToComment(" error: error while reading field ") << nomcha << " in file " << aFile , /*fatal=*/true );
1534 med_int tmp_numdt, tmp_numit;
1536 //~med_int step = data->myUseLastTimeStep ? nbofcstp : data->myTimeStep+1;
1537 //~myPrint("step ", step);
1538 erreur = MEDfieldComputingStepInfo ( medIdt, nomcha, 1, &numdt, &numit, &dt );
1539 for(med_int step = 1; step <= nbofcstp; step++ )
1541 erreur = MEDfieldComputingStepInfo ( medIdt, nomcha, step, &tmp_numdt, &tmp_numit, &dt );
1542 if(tmp_numdt > numdt)
1550 //~addMessage( ToComment(" error: error while reading field ") << nomcha << "step (numdt, numit) = " <<"("<< numdt<< ", " \
1551 numit<< ")" <<" in file " << aFile , /*fatal=*/true );
1555 // Fermeture du fichier
1556 if ( medIdt > 0 ) MEDfileClose(medIdt);
1560 void MgAdapt::updateTimeStepRank()
1565 if (myUseNoTimeStep)
1569 setRankTimeStep((int)tmst, (int)arank);
1571 else if (myUseLastTimeStep)
1573 std::string fieldFile = useBackgroundMap ? sizeMapFile : medFileIn;
1574 getTimeStepInfos(fieldFile, tmst, arank);
1575 setRankTimeStep((int)tmst, (int)arank);