From b81b38e9b12381ce00dcae606286b864c8c1e2eb Mon Sep 17 00:00:00 2001 From: marioalexis Date: Thu, 19 Dec 2024 01:27:15 -0300 Subject: [PATCH 1/4] Fem: Add preference entry to set Netgen log verbosity --- src/Mod/Fem/CMakeLists.txt | 7 + .../Fem/Gui/Resources/ui/DlgSettingsNetgen.ui | 43 +++- src/Mod/Fem/InitGui.py | 3 +- src/Mod/Fem/femmesh/netgentools.py | 226 ++++++++++-------- src/Mod/Fem/fempreferencepages/__init__.py | 1 + .../fempreferencepages/dlg_settings_netgen.py | 61 +++++ 6 files changed, 234 insertions(+), 107 deletions(-) create mode 100644 src/Mod/Fem/fempreferencepages/__init__.py create mode 100644 src/Mod/Fem/fempreferencepages/dlg_settings_netgen.py diff --git a/src/Mod/Fem/CMakeLists.txt b/src/Mod/Fem/CMakeLists.txt index da61e3e816..d0847093b6 100755 --- a/src/Mod/Fem/CMakeLists.txt +++ b/src/Mod/Fem/CMakeLists.txt @@ -646,6 +646,11 @@ SET(FemGuiViewProvider_SRCS femviewprovider/view_solver_ccxtools.py ) +SET(FemGuiPreferencePages_SRCS + fempreferencepages/__init__.py + fempreferencepages/dlg_settings_netgen.py +) + SET(FemAllGuiScripts ${FemGuiBaseModules_SRCS} ${FemGuiObjects_SRCS} @@ -653,6 +658,7 @@ SET(FemAllGuiScripts ${FemGuiTests_SRCS} ${FemGuiUtils_SRCS} ${FemGuiViewProvider_SRCS} + ${FemGuiPreferencePages_SRCS} ) if(BUILD_GUI) @@ -669,4 +675,5 @@ if(BUILD_GUI) INSTALL(FILES ${FemGuiTests_SRCS} DESTINATION Mod/Fem/femtest/gui/) INSTALL(FILES ${FemGuiUtils_SRCS} DESTINATION Mod/Fem/femguiutils/) INSTALL(FILES ${FemGuiViewProvider_SRCS} DESTINATION Mod/Fem/femviewprovider/) + INSTALL(FILES ${FemGuiPreferencePages_SRCS} DESTINATION Mod/Fem/fempreferencepages/) endif(BUILD_GUI) diff --git a/src/Mod/Fem/Gui/Resources/ui/DlgSettingsNetgen.ui b/src/Mod/Fem/Gui/Resources/ui/DlgSettingsNetgen.ui index d803a33c5d..8e0699b552 100644 --- a/src/Mod/Fem/Gui/Resources/ui/DlgSettingsNetgen.ui +++ b/src/Mod/Fem/Gui/Resources/ui/DlgSettingsNetgen.ui @@ -1,7 +1,7 @@ - Gui::Dialog::DlgSettingsNetgen - + FemGui::DlgSettingsNetgen + 0 @@ -45,6 +45,45 @@ + + + + Options + + + + + + + + Log verbosity + + + + + + + Level of verbosity printed on the task panel + + + QComboBox::AdjustToContents + + + LogVerbosity + + + Mod/Fem/Netgen + + + + + + + + + + + diff --git a/src/Mod/Fem/InitGui.py b/src/Mod/Fem/InitGui.py index 0ec9b478bf..621a278f17 100644 --- a/src/Mod/Fem/InitGui.py +++ b/src/Mod/Fem/InitGui.py @@ -71,8 +71,9 @@ class FemWorkbench(Workbench): import Fem import FemGui import femcommands.commands + import fempreferencepages - FreeCADGui.addPreferencePage(":/ui/DlgSettingsNetgen.ui", "FEM") + FreeCADGui.addPreferencePage(fempreferencepages.DlgSettingsNetgen, "FEM") # dummy usage to get flake8 and lgtm quiet False if Fem.__name__ else True diff --git a/src/Mod/Fem/femmesh/netgentools.py b/src/Mod/Fem/femmesh/netgentools.py index f63a3a2f6e..1ed55efdfe 100644 --- a/src/Mod/Fem/femmesh/netgentools.py +++ b/src/Mod/Fem/femmesh/netgentools.py @@ -33,6 +33,7 @@ from PySide.QtCore import QProcess import FreeCAD import Fem +from freecad import utils try: from netgen import occ, meshing, config as ng_config @@ -95,16 +96,12 @@ class NetgenTools: geom_trans.Placement = global_pla self.brep_file = self.tmpdir + "/shape.brep" self.result_file = self.tmpdir + "/result.npy" + self.script_file = self.tmpdir + "/code.py" geom_trans.exportBrep(self.brep_file) - code = """ -from femmesh.netgentools import NetgenTools - -NetgenTools.run_netgen(**{params}) -""" - def prepare(self): self.write_geom() + grp = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Fem/Netgen") self.mesh_params = { "brep_file": self.brep_file, "threads": self.obj.Threads, @@ -114,117 +111,138 @@ NetgenTools.run_netgen(**{params}) "second_order_linear": self.obj.SecondOrderLinear, "result_file": self.result_file, "mesh_region": self.get_mesh_region(), + "verbosity": grp.GetInt("LogVerbosity", 2), } + with open(self.script_file, "w") as file: + file.write( + self.code.format( + kwds=self.mesh_params, + order_face=NetgenTools.order_face, + order_volume=NetgenTools.order_volume, + ) + ) + def compute(self): - code_str = self.code.format(params=self.mesh_params) - self.process.start(sys.executable, ["-c", code_str]) + self.process.start(utils.get_python_exe(), [self.script_file]) return self.process - @staticmethod - def run_netgen( - brep_file, - threads, - heal, - params, - second_order, - second_order_linear, - result_file, - mesh_region, - ): - geom = occ.OCCGeometry(brep_file) - ngcore.SetNumThreads(threads) + code = """ +from netgen import occ, meshing +import pyngcore as ngcore +import numpy as np - shape = geom.shape - for items, l in mesh_region: - for t, n in items: - if t == "Vertex": - shape.vertices.vertices[n - 1].maxh = l - elif t == "Edge": - shape.edges.edges[n - 1].maxh = l - elif t == "Face": - shape.faces.faces[n - 1].maxh = l - elif t == "Solid": - shape.solids.solids[n - 1].maxh = l +order_face = {order_face} +order_volume = {order_volume} - with ngcore.TaskManager(): - geom = occ.OCCGeometry(shape) - if heal: - geom.Heal() - mesh = geom.GenerateMesh(mp=meshing.MeshingParameters(**params)) +def run_netgen( + brep_file, + threads, + heal, + params, + second_order, + second_order_linear, + result_file, + mesh_region, + verbosity, +): + geom = occ.OCCGeometry(brep_file) + ngcore.SetNumThreads(threads) - result = { - "coords": [], - "Edges": [[], []], - "Faces": [[], []], - "Volumes": [[], []], - } - groups = {"Edges": [], "Faces": [], "Solids": []} + shape = geom.shape + for items, l in mesh_region: + for t, n in items: + if t == "Vertex": + shape.vertices.vertices[n - 1].maxh = l + elif t == "Edge": + shape.edges.edges[n - 1].maxh = l + elif t == "Face": + shape.faces.faces[n - 1].maxh = l + elif t == "Solid": + shape.solids.solids[n - 1].maxh = l - # save empty data if last step is geometry analysis - if params["perfstepsend"] == NetgenTools.meshing_step["AnalyzeGeometry"]: - np.save(result_file, [result, groups]) - return None + with ngcore.TaskManager(): + meshing.SetMessageImportance(verbosity) + geom = occ.OCCGeometry(shape) + if heal: + geom.Heal() + mesh = geom.GenerateMesh(mp=meshing.MeshingParameters(**params)) - if second_order: - if second_order_linear: - mesh.SetGeometry(None) - mesh.SecondOrder() - - coords = mesh.Coordinates() - - edges = mesh.Elements1D().NumPy() - faces = mesh.Elements2D().NumPy() - volumes = mesh.Elements3D().NumPy() - - nod_edges = edges["nodes"] - nod_faces = faces["nodes"] - nod_volumes = volumes["nodes"] - - np_edges = (nod_edges != 0).sum(axis=1).tolist() - np_faces = faces["np"].tolist() - np_volumes = volumes["np"].tolist() - - # set smesh node order - for i in range(faces.size): - nod_faces[i] = nod_faces[i][NetgenTools.order_face[np_faces[i]]] - - for i in range(volumes.size): - nod_volumes[i] = nod_volumes[i][NetgenTools.order_volume[np_volumes[i]]] - - flat_edges = nod_edges[nod_edges != 0].tolist() - flat_faces = nod_faces[nod_faces != 0].tolist() - flat_volumes = nod_volumes[nod_volumes != 0].tolist() - - result = { - "coords": coords, - "Edges": [flat_edges, np_edges], - "Faces": [flat_faces, np_faces], - "Volumes": [flat_volumes, np_volumes], - } - - # create groups - nb_edges = edges.size - nb_faces = faces.size - nb_volumes = volumes.size - - idx_edges = edges["index"] - idx_faces = faces["index"] - idx_volumes = volumes["index"] - - for i in np.unique(idx_edges): - edge_i = (np.nonzero(idx_edges == i)[0] + 1).tolist() - groups["Edges"].append([i, edge_i]) - for i in np.unique(idx_faces): - face_i = (np.nonzero(idx_faces == i)[0] + nb_edges + 1).tolist() - groups["Faces"].append([i, face_i]) - - for i in np.unique(idx_volumes): - volume_i = (np.nonzero(idx_volumes == i)[0] + nb_edges + nb_faces + 1).tolist() - groups["Solids"].append([i, volume_i]) + result = {{ + "coords": [], + "Edges": [[], []], + "Faces": [[], []], + "Volumes": [[], []], + }} + groups = {{"Edges": [], "Faces": [], "Solids": []}} + # save empty data if last step is geometry analysis + if params["perfstepsend"] == 1: np.save(result_file, [result, groups]) + return None + + if second_order: + if second_order_linear: + mesh.SetGeometry(None) + mesh.SecondOrder() + + coords = mesh.Coordinates() + + edges = mesh.Elements1D().NumPy() + faces = mesh.Elements2D().NumPy() + volumes = mesh.Elements3D().NumPy() + + nod_edges = edges["nodes"] + nod_faces = faces["nodes"] + nod_volumes = volumes["nodes"] + + np_edges = (nod_edges != 0).sum(axis=1).tolist() + np_faces = faces["np"].tolist() + np_volumes = volumes["np"].tolist() + + # set smesh node order + for i in range(faces.size): + nod_faces[i] = nod_faces[i][order_face[np_faces[i]]] + + for i in range(volumes.size): + nod_volumes[i] = nod_volumes[i][order_volume[np_volumes[i]]] + + flat_edges = nod_edges[nod_edges != 0].tolist() + flat_faces = nod_faces[nod_faces != 0].tolist() + flat_volumes = nod_volumes[nod_volumes != 0].tolist() + + result = {{ + "coords": coords, + "Edges": [flat_edges, np_edges], + "Faces": [flat_faces, np_faces], + "Volumes": [flat_volumes, np_volumes], + }} + + # create groups + nb_edges = edges.size + nb_faces = faces.size + nb_volumes = volumes.size + + idx_edges = edges["index"] + idx_faces = faces["index"] + idx_volumes = volumes["index"] + + for i in np.unique(idx_edges): + edge_i = (np.nonzero(idx_edges == i)[0] + 1).tolist() + groups["Edges"].append([i, edge_i]) + for i in np.unique(idx_faces): + face_i = (np.nonzero(idx_faces == i)[0] + nb_edges + 1).tolist() + groups["Faces"].append([i, face_i]) + + for i in np.unique(idx_volumes): + volume_i = (np.nonzero(idx_volumes == i)[0] + nb_edges + nb_faces + 1).tolist() + groups["Solids"].append([i, volume_i]) + + np.save(result_file, [result, groups]) + +run_netgen(**{kwds}) + """ def fem_mesh_from_result(self): fem_mesh = Fem.FemMesh() diff --git a/src/Mod/Fem/fempreferencepages/__init__.py b/src/Mod/Fem/fempreferencepages/__init__.py new file mode 100644 index 0000000000..983152cd5c --- /dev/null +++ b/src/Mod/Fem/fempreferencepages/__init__.py @@ -0,0 +1 @@ +from .dlg_settings_netgen import DlgSettingsNetgen diff --git a/src/Mod/Fem/fempreferencepages/dlg_settings_netgen.py b/src/Mod/Fem/fempreferencepages/dlg_settings_netgen.py new file mode 100644 index 0000000000..a5186dd105 --- /dev/null +++ b/src/Mod/Fem/fempreferencepages/dlg_settings_netgen.py @@ -0,0 +1,61 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later + +# *************************************************************************** +# * Copyright (c) 2024 Mario Passaglia * +# * * +# * This file is part of FreeCAD. * +# * * +# * FreeCAD is free software: you can redistribute it and/or modify it * +# * under the terms of the GNU Lesser General Public License as * +# * published by the Free Software Foundation, either version 2.1 of the * +# * License, or (at your option) any later version. * +# * * +# * FreeCAD is distributed in the hope that it will be useful, but * +# * WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * +# * Lesser General Public License for more details. * +# * * +# * You should have received a copy of the GNU Lesser General Public * +# * License along with FreeCAD. If not, see * +# * . * +# * * +# *************************************************************************** + +__title__ = "Netgen preference page class" +__author__ = "Mario Passaglia" +__url__ = "https://www.freecad.org" + +import FreeCAD +import FreeCADGui + + +class DlgSettingsNetgen: + + def __init__(self): + self.form = FreeCADGui.PySideUic.loadUi(":ui/DlgSettingsNetgen.ui") + self.grp = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Fem/Netgen") + + def loadSettings(self): + self.form.ckb_legacy.setChecked(self.grp.GetBool("UseLegacyNetgen", True)) + self.populate_log_verbosity() + + def saveSettings(self): + self.grp.SetBool("UseLegacyNetgen", self.form.ckb_legacy.isChecked()) + self.grp.SetInt("LogVerbosity", self.form.cb_log_verbosity.currentData()) + + def populate_log_verbosity(self): + values = { + "None": 0, + "Least": 1, + "Little": 2, + "Moderate": 3, + "Much": 4, + "Most": 5, + } + + for v in values: + self.form.cb_log_verbosity.addItem(v, values[v]) + + current = self.grp.GetInt("LogVerbosity", 2) + index = self.form.cb_log_verbosity.findData(current) + self.form.cb_log_verbosity.setCurrentIndex(index) From 397adf8fa897cc46b453b26a25a21b22d8dd55bd Mon Sep 17 00:00:00 2001 From: marioalexis Date: Thu, 19 Dec 2024 14:34:59 -0300 Subject: [PATCH 2/4] Fem: Add preference entry to set Netgen number of threads --- .../Fem/Gui/Resources/ui/DlgSettingsNetgen.ui | 31 +++++++++++++++++++ src/Mod/Fem/femmesh/netgentools.py | 10 +++--- src/Mod/Fem/femobjects/mesh_netgen.py | 9 ------ .../fempreferencepages/dlg_settings_netgen.py | 4 +++ 4 files changed, 40 insertions(+), 14 deletions(-) diff --git a/src/Mod/Fem/Gui/Resources/ui/DlgSettingsNetgen.ui b/src/Mod/Fem/Gui/Resources/ui/DlgSettingsNetgen.ui index 8e0699b552..95d00eb5dc 100644 --- a/src/Mod/Fem/Gui/Resources/ui/DlgSettingsNetgen.ui +++ b/src/Mod/Fem/Gui/Resources/ui/DlgSettingsNetgen.ui @@ -79,6 +79,32 @@ + + + + Number of threads + + + + + + + Qt::AlignLeft|Qt::AlignTrailing|Qt::AlignVCenter + + + Number of threads used for meshing + + + 1 + + + NumOfThreads + + + Mod/Fem/Netgen + + + @@ -99,6 +125,11 @@ QCheckBox
Gui/PrefWidgets.h
+ + Gui::PrefSpinBox + QSpinBox +
Gui/PrefWidgets.h
+
diff --git a/src/Mod/Fem/femmesh/netgentools.py b/src/Mod/Fem/femmesh/netgentools.py index 1ed55efdfe..488f996771 100644 --- a/src/Mod/Fem/femmesh/netgentools.py +++ b/src/Mod/Fem/femmesh/netgentools.py @@ -29,7 +29,7 @@ import numpy as np import shutil import sys import tempfile -from PySide.QtCore import QProcess +from PySide.QtCore import QProcess, QThread import FreeCAD import Fem @@ -84,6 +84,7 @@ class NetgenTools: self.tmpdir = "" self.process = QProcess() self.mesh_params = {} + self.param_grp = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Fem/Netgen") def write_geom(self): if not self.tmpdir: @@ -101,17 +102,16 @@ class NetgenTools: def prepare(self): self.write_geom() - grp = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Fem/Netgen") self.mesh_params = { "brep_file": self.brep_file, - "threads": self.obj.Threads, + "threads": self.param_grp.GetInt("NumOfThreads", QThread.idealThreadCount()), "heal": self.obj.HealShape, "params": self.get_meshing_parameters(), "second_order": self.obj.SecondOrder, "second_order_linear": self.obj.SecondOrderLinear, "result_file": self.result_file, "mesh_region": self.get_mesh_region(), - "verbosity": grp.GetInt("LogVerbosity", 2), + "verbosity": self.param_grp.GetInt("LogVerbosity", 2), } with open(self.script_file, "w") as file: @@ -319,7 +319,7 @@ run_netgen(**{kwds}) "inverttrigs": self.obj.InvertTrigs, "autozrefine": self.obj.AutoZRefine, "parallel_meshing": self.obj.ParallelMeshing, - "nthreads": self.obj.Threads, + "nthreads": self.param_grp.GetInt("NumOfThreads", QThread.idealThreadCount()), "closeedgefac": self.obj.CloseEdgeFactor, } diff --git a/src/Mod/Fem/femobjects/mesh_netgen.py b/src/Mod/Fem/femobjects/mesh_netgen.py index a437cdaedd..9d7048a4d9 100644 --- a/src/Mod/Fem/femobjects/mesh_netgen.py +++ b/src/Mod/Fem/femobjects/mesh_netgen.py @@ -485,15 +485,6 @@ class MeshNetgen(base_fempythonobject.BaseFemPythonObject): value=True, ) ) - prop.append( - _PropHelper( - type="App::PropertyInteger", - name="Threads", - group="Mesh Parameters", - doc="Number of threads for parallel meshing", - value=4, - ) - ) prop.append( _PropHelper( type="App::PropertyBool", diff --git a/src/Mod/Fem/fempreferencepages/dlg_settings_netgen.py b/src/Mod/Fem/fempreferencepages/dlg_settings_netgen.py index a5186dd105..695f7252c2 100644 --- a/src/Mod/Fem/fempreferencepages/dlg_settings_netgen.py +++ b/src/Mod/Fem/fempreferencepages/dlg_settings_netgen.py @@ -25,6 +25,8 @@ __title__ = "Netgen preference page class" __author__ = "Mario Passaglia" __url__ = "https://www.freecad.org" +from PySide.QtCore import QThread + import FreeCAD import FreeCADGui @@ -37,11 +39,13 @@ class DlgSettingsNetgen: def loadSettings(self): self.form.ckb_legacy.setChecked(self.grp.GetBool("UseLegacyNetgen", True)) + self.form.sb_threads.setValue(self.grp.GetInt("NumOfThreads", QThread.idealThreadCount())) self.populate_log_verbosity() def saveSettings(self): self.grp.SetBool("UseLegacyNetgen", self.form.ckb_legacy.isChecked()) self.grp.SetInt("LogVerbosity", self.form.cb_log_verbosity.currentData()) + self.grp.SetInt("NumOfThreads", self.form.sb_threads.value()) def populate_log_verbosity(self): values = { From a1b1c8231076e0eb82493c7f0075c57e3d5da191 Mon Sep 17 00:00:00 2001 From: marioalexis Date: Thu, 19 Dec 2024 14:36:12 -0300 Subject: [PATCH 3/4] Fem: Add preference entry to set Gmsh number of threads --- src/Mod/Fem/Gui/DlgSettingsFemGmsh.ui | 31 +++++++++++++++++++++++ src/Mod/Fem/Gui/DlgSettingsFemGmshImp.cpp | 7 +++++ src/Mod/Fem/femmesh/gmshtools.py | 13 +++++----- 3 files changed, 45 insertions(+), 6 deletions(-) diff --git a/src/Mod/Fem/Gui/DlgSettingsFemGmsh.ui b/src/Mod/Fem/Gui/DlgSettingsFemGmsh.ui index e6981dc9f2..eceddf9a99 100644 --- a/src/Mod/Fem/Gui/DlgSettingsFemGmsh.ui +++ b/src/Mod/Fem/Gui/DlgSettingsFemGmsh.ui @@ -151,6 +151,32 @@ + + + + Number of threads + + + + + + + Qt::AlignLeft|Qt::AlignTrailing|Qt::AlignVCenter + + + Number of threads used for meshing + + + 1 + + + NumOfThreads + + + Mod/Fem/Gmsh + + + @@ -193,6 +219,11 @@ QComboBox
Gui/PrefWidgets.h
+ + Gui::PrefSpinBox + QSpinBox +
Gui/PrefWidgets.h
+
diff --git a/src/Mod/Fem/Gui/DlgSettingsFemGmshImp.cpp b/src/Mod/Fem/Gui/DlgSettingsFemGmshImp.cpp index 3c0f8b6d91..c5b789f117 100644 --- a/src/Mod/Fem/Gui/DlgSettingsFemGmshImp.cpp +++ b/src/Mod/Fem/Gui/DlgSettingsFemGmshImp.cpp @@ -25,6 +25,7 @@ #include "PreCompiled.h" #ifndef _PreComp_ #include +#include #endif #include @@ -53,6 +54,7 @@ void DlgSettingsFemGmshImp::saveSettings() ui->cb_gmsh_binary_std->onSave(); ui->fc_gmsh_binary_path->onSave(); ui->cb_log_verbosity->onSave(); + ui->sb_threads->onSave(); } void DlgSettingsFemGmshImp::loadSettings() @@ -60,6 +62,11 @@ void DlgSettingsFemGmshImp::loadSettings() ui->cb_gmsh_binary_std->onRestore(); ui->fc_gmsh_binary_path->onRestore(); + ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath( + "User parameter:BaseApp/Preferences/Mod/Fem/Gmsh"); + // determine number of CPU threads + ui->sb_threads->setValue(hGrp->GetInt("NumOfThreads", QThread::idealThreadCount())); + populateLogVerbosity(); ui->cb_log_verbosity->onRestore(); } diff --git a/src/Mod/Fem/femmesh/gmshtools.py b/src/Mod/Fem/femmesh/gmshtools.py index 33093165b2..1ea5a11813 100644 --- a/src/Mod/Fem/femmesh/gmshtools.py +++ b/src/Mod/Fem/femmesh/gmshtools.py @@ -30,7 +30,7 @@ __url__ = "https://www.freecad.org" import os import re import subprocess -from PySide.QtCore import QProcess +from PySide.QtCore import QProcess, QThread import FreeCAD from FreeCAD import Console @@ -737,11 +737,12 @@ class GmshTools: geo.write("// geo file for meshing with Gmsh meshing software created by FreeCAD\n") geo.write("\n") - cpu_count = os.cpu_count() - if cpu_count is not None and cpu_count > 1: - geo.write("// enable multi-core processing\n") - geo.write(f"General.NumThreads = {cpu_count};\n") - geo.write("\n") + cpu_count = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Fem/Gmsh").GetInt( + "NumOfThreads", QThread.idealThreadCount() + ) + geo.write("// enable multi-core processing\n") + geo.write(f"General.NumThreads = {cpu_count};\n") + geo.write("\n") geo.write("// open brep geometry\n") # explicit use double quotes in geo file From 590733ea2cb0d95eb37c873cf212b7b9ad034d97 Mon Sep 17 00:00:00 2001 From: marioalexis Date: Thu, 19 Dec 2024 14:38:12 -0300 Subject: [PATCH 4/4] Fem: Set default CalculiX number of threads to Qt idealThreadCount --- src/Mod/Fem/Gui/DlgSettingsFemCcx.ui | 4 ++-- src/Mod/Fem/Gui/DlgSettingsFemCcxImp.cpp | 8 +++++--- src/Mod/Fem/femtaskpanels/task_solver_ccxtools.py | 7 ++----- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/Mod/Fem/Gui/DlgSettingsFemCcx.ui b/src/Mod/Fem/Gui/DlgSettingsFemCcx.ui index 9289ba959a..bde7af6c61 100644 --- a/src/Mod/Fem/Gui/DlgSettingsFemCcx.ui +++ b/src/Mod/Fem/Gui/DlgSettingsFemCcx.ui @@ -301,10 +301,10 @@ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - Set to zero to automatically use maximum number of available cores + Number of threads used for analysis - 0 + 1 AnalysisNumCPUs diff --git a/src/Mod/Fem/Gui/DlgSettingsFemCcxImp.cpp b/src/Mod/Fem/Gui/DlgSettingsFemCcxImp.cpp index bea9df709f..e70b285702 100644 --- a/src/Mod/Fem/Gui/DlgSettingsFemCcxImp.cpp +++ b/src/Mod/Fem/Gui/DlgSettingsFemCcxImp.cpp @@ -45,9 +45,6 @@ DlgSettingsFemCcxImp::DlgSettingsFemCcxImp(QWidget* parent) // set ranges ui->dsb_ccx_analysis_time->setMaximum(FLOAT_MAX); ui->dsb_ccx_initial_time_step->setMaximum(FLOAT_MAX); - // determine number of CPU cores - int processor_count = QThread::idealThreadCount(); - ui->sb_ccx_numcpu->setMaximum(processor_count); connect(ui->fc_ccx_binary_path, &Gui::PrefFileChooser::fileNameChanged, @@ -117,6 +114,11 @@ void DlgSettingsFemCcxImp::loadSettings() ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath( "User parameter:BaseApp/Preferences/Mod/Fem/Ccx"); + + // determine number of CPU threads + int processor_count = hGrp->GetInt("AnalysisNumCPUs", QThread::idealThreadCount()); + ui->sb_ccx_numcpu->setValue(processor_count); + int index = hGrp->GetInt("Solver", 0); if (index > -1) { ui->cmb_solver->setCurrentIndex(index); diff --git a/src/Mod/Fem/femtaskpanels/task_solver_ccxtools.py b/src/Mod/Fem/femtaskpanels/task_solver_ccxtools.py index 55162bdb05..a55c7c9790 100644 --- a/src/Mod/Fem/femtaskpanels/task_solver_ccxtools.py +++ b/src/Mod/Fem/femtaskpanels/task_solver_ccxtools.py @@ -381,11 +381,8 @@ class _TaskPanel: # Set up for multi-threading. Note: same functionality as ccx_tools.py/start_ccx() ccx_prefs = FreeCAD.ParamGet(self.PREFS_PATH) env = QtCore.QProcessEnvironment.systemEnvironment() - num_cpu_pref = ccx_prefs.GetInt("AnalysisNumCPUs", 0) - if num_cpu_pref >= 1: - env.insert("OMP_NUM_THREADS", str(num_cpu_pref)) - else: - env.insert("OMP_NUM_THREADS", str(QtCore.QThread.idealThreadCount())) + num_cpu_pref = ccx_prefs.GetInt("AnalysisNumCPUs", QtCore.QThread.idealThreadCount()) + env.insert("OMP_NUM_THREADS", str(num_cpu_pref)) self.Calculix.setProcessEnvironment(env) self.cwd = QtCore.QDir.currentPath()