From e90347e3f72808f754abf2ec5bde8b02bf26c8f2 Mon Sep 17 00:00:00 2001 From: Uwe Date: Sat, 25 Mar 2023 19:50:58 +0100 Subject: [PATCH] [FEM] fix binary check - the current implementation only considers explicitly given binaries (with full path) and ignores the setting to check the environment paths - also remove 2 trailing whitespaces --- src/Mod/Fem/App/FemTools.cpp | 42 ++++++++++++++++++++ src/Mod/Fem/App/FemTools.h | 7 ++++ src/Mod/Fem/App/PreCompiled.h | 1 + src/Mod/Fem/Gui/DlgSettingsFemGeneralImp.cpp | 26 +++++------- src/Mod/Fem/Gui/Workbench.cpp | 24 ++++------- src/Mod/Fem/femsolver/elmer/tasks.py | 4 +- 6 files changed, 69 insertions(+), 35 deletions(-) diff --git a/src/Mod/Fem/App/FemTools.cpp b/src/Mod/Fem/App/FemTools.cpp index 60e56c8622..d622862fcf 100644 --- a/src/Mod/Fem/App/FemTools.cpp +++ b/src/Mod/Fem/App/FemTools.cpp @@ -23,6 +23,8 @@ #include "PreCompiled.h" #ifndef _PreComp_ +# include + # include # include # include @@ -41,6 +43,8 @@ # include #endif +#include + #include "FemTools.h" @@ -278,3 +282,41 @@ gp_XYZ Fem::Tools::getDirection(const TopoDS_Edge& edge) return dir; } + +// function to determine 3rd-party binaries used by the FEM WB +std::string Fem::Tools::checkIfBinaryExists(std::string prefSection, + std::string prefBinaryName, + std::string binaryName) +{ + // if "Search in known binary directories" is set in the preferences, we ignore custom path + auto paramPath = "User parameter:BaseApp/Preferences/Mod/Fem/" + prefSection; + auto knownDirectoriesString = "UseStandard" + prefSection + "Location"; + ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(paramPath.c_str()); + bool knownDirectories = hGrp->GetBool(knownDirectoriesString.c_str(), true); + + if (knownDirectories) { +#if defined(FC_OS_WIN32) + binaryName = binaryName + ".exe"; +#endif + // first check the environment paths by QFileInfo + if (QFileInfo::exists(QString::fromLatin1(binaryName.c_str()))) { + return binaryName; + } + // check the folder of the FreeCAD binary + else { + auto homePathBinary = App::Application::getHomePath() + "bin/" + binaryName; + if (QFileInfo::exists(QString::fromLatin1(homePathBinary.c_str()))) + return binaryName; + } + } + else { + auto binaryPathString = prefBinaryName + "BinaryPath"; + ParameterGrp::handle hGrp = + App::GetApplication().GetParameterGroupByPath(paramPath.c_str()); + auto binaryPath = hGrp->GetASCII(binaryPathString.c_str(), ""); + QFileInfo::exists(QString::fromLatin1(binaryPath.c_str())); + if (QFileInfo::exists(QString::fromLatin1(binaryPath.c_str()))) + return binaryPath; + } + return ""; +} diff --git a/src/Mod/Fem/App/FemTools.h b/src/Mod/Fem/App/FemTools.h index ebfa3e9a1f..628923570b 100644 --- a/src/Mod/Fem/App/FemTools.h +++ b/src/Mod/Fem/App/FemTools.h @@ -67,6 +67,13 @@ public: @see isPlanar */ static gp_XYZ getDirection(const TopoDS_Face&); + /*! + function to determine 3rd-party binaries used by the FEM WB + The result is either the full path if available or just the binary + name if it was found in a system path + */ + static std::string checkIfBinaryExists(std::string prefSection, std::string prefBinaryPath, + std::string prefBinaryName); }; } //namespace Fem diff --git a/src/Mod/Fem/App/PreCompiled.h b/src/Mod/Fem/App/PreCompiled.h index f73b8cd3e8..17c6982089 100644 --- a/src/Mod/Fem/App/PreCompiled.h +++ b/src/Mod/Fem/App/PreCompiled.h @@ -53,6 +53,7 @@ #include #include +#include // Salomesh #include diff --git a/src/Mod/Fem/Gui/DlgSettingsFemGeneralImp.cpp b/src/Mod/Fem/Gui/DlgSettingsFemGeneralImp.cpp index b2d869872a..adf05bc409 100644 --- a/src/Mod/Fem/Gui/DlgSettingsFemGeneralImp.cpp +++ b/src/Mod/Fem/Gui/DlgSettingsFemGeneralImp.cpp @@ -25,6 +25,7 @@ #include "PreCompiled.h" #include +#include #include "DlgSettingsFemGeneralImp.h" #include "ui_DlgSettingsFemGeneral.h" @@ -42,25 +43,16 @@ DlgSettingsFemGeneralImp::DlgSettingsFemGeneralImp(QWidget* parent) ui->cmb_def_solver->clear(); std::vector Solvers = {"None"}; - ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath( - "User parameter:BaseApp/Preferences/Mod/Fem/Ccx"); - auto ccxBinaryPath = hGrp->GetASCII("ccxBinaryPath", ""); - if (!ccxBinaryPath.empty()) + if (!Fem::Tools::checkIfBinaryExists("CCX", "ccx", "ccx").empty()) Solvers.push_back("CalculiX"); - hGrp = App::GetApplication().GetParameterGroupByPath( - "User parameter:BaseApp/Preferences/Mod/Fem/Elmer"); - auto elmerBinaryPath = hGrp->GetASCII("elmerBinaryPath", ""); - if (!elmerBinaryPath.empty()) + if (!Fem::Tools::checkIfBinaryExists("Elmer", "elmer", "ElmerSolver").empty()) Solvers.push_back("Elmer"); - hGrp = App::GetApplication().GetParameterGroupByPath( - "User parameter:BaseApp/Preferences/Mod/Fem/mystran"); - auto MystranBinaryPath = hGrp->GetASCII("MystranBinaryPath", ""); - if (!MystranBinaryPath.empty()) + // also check the multi-CPU Elmer build + else if (!Fem::Tools::checkIfBinaryExists("Elmer", "elmer", "ElmerSolver_mpi").empty()) + Solvers.push_back("Elmer"); + if (!Fem::Tools::checkIfBinaryExists("Mystran", "mystran", "mystran").empty()) Solvers.push_back("Mystran"); - hGrp = App::GetApplication().GetParameterGroupByPath( - "User parameter:BaseApp/Preferences/Mod/Fem/Z88"); - auto z88BinaryPath = hGrp->GetASCII("z88BinaryPath", ""); - if (!z88BinaryPath.empty()) + if (!Fem::Tools::checkIfBinaryExists("Z88", "z88", "z88r").empty()) Solvers.push_back("Z88"); QStringList solversList; @@ -71,7 +63,7 @@ DlgSettingsFemGeneralImp::DlgSettingsFemGeneralImp(QWidget* parent) // if the "DefaultSolver" parameter is not yet set and there is only // one available solver, set this solver - hGrp = App::GetApplication().GetParameterGroupByPath( + ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath( "User parameter:BaseApp/Preferences/Mod/Fem/General"); auto DefaultSolver = hGrp->GetInt("DefaultSolver", 0); if (!DefaultSolver && ui->cmb_def_solver->count() == 2) diff --git a/src/Mod/Fem/Gui/Workbench.cpp b/src/Mod/Fem/Gui/Workbench.cpp index 657364d907..7741fb53cb 100755 --- a/src/Mod/Fem/Gui/Workbench.cpp +++ b/src/Mod/Fem/Gui/Workbench.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include "Workbench.h" @@ -175,25 +176,16 @@ Gui::ToolBarItem* Workbench::setupToolBars() const Gui::ToolBarItem* solve = new Gui::ToolBarItem(root); solve->setCommand("Solve"); - ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath( - "User parameter:BaseApp/Preferences/Mod/Fem/Ccx"); - auto ccxBinaryPath = hGrp->GetASCII("ccxBinaryPath", ""); - if (!ccxBinaryPath.empty()) + if (!Fem::Tools::checkIfBinaryExists("CCX", "ccx", "ccx").empty()) *solve << "FEM_SolverCalculixCxxtools"; - hGrp = App::GetApplication().GetParameterGroupByPath( - "User parameter:BaseApp/Preferences/Mod/Fem/Elmer"); - auto elmerBinaryPath = hGrp->GetASCII("elmerBinaryPath", ""); - if (!elmerBinaryPath.empty()) + if (!Fem::Tools::checkIfBinaryExists("Elmer", "elmer", "ElmerSolver").empty()) *solve << "FEM_SolverElmer"; - hGrp = App::GetApplication().GetParameterGroupByPath( - "User parameter:BaseApp/Preferences/Mod/Fem/mystran"); - auto MystranBinaryPath = hGrp->GetASCII("MystranBinaryPath", ""); - if (!MystranBinaryPath.empty()) + // also check the multi-CPU Elmer build + else if (!Fem::Tools::checkIfBinaryExists("Elmer", "elmer", "ElmerSolver_mpi").empty()) + *solve << "FEM_SolverElmer"; + if (!Fem::Tools::checkIfBinaryExists("Mystran", "mystran", "mystran").empty()) *solve << "FEM_SolverMystran"; - hGrp = App::GetApplication().GetParameterGroupByPath( - "User parameter:BaseApp/Preferences/Mod/Fem/Z88"); - auto z88BinaryPath = hGrp->GetASCII("z88BinaryPath", ""); - if (!z88BinaryPath.empty()) + if (!Fem::Tools::checkIfBinaryExists("Z88", "z88", "z88r").empty()) *solve << "FEM_SolverZ88"; *solve << "Separator" << "FEM_CompMechEquations" diff --git a/src/Mod/Fem/femsolver/elmer/tasks.py b/src/Mod/Fem/femsolver/elmer/tasks.py index 46000d800e..efc10addec 100644 --- a/src/Mod/Fem/femsolver/elmer/tasks.py +++ b/src/Mod/Fem/femsolver/elmer/tasks.py @@ -248,7 +248,7 @@ class Results(run.Results): self._handleStedyStateResult() else: self._handleTransientResults() - + def _handleStedyStateResult(self): if self.solver.ElmerResult is None: self._createResults() @@ -351,7 +351,7 @@ class Results(run.Results): ) self.solver.ElmerTimeResults = tmplist self._finishTimeResults(time, counter-1) - + def _finishTimeResults(self, time, counter): # we purposely use the decimal dot in the label self.solver.ElmerTimeResults[counter].Label\