Skip to content

Commit 5736c29

Browse files
committed
Fem: Remove dependency of calculix solver classes on user parameters - fixes FreeCAD#13383
1 parent 5ca6eab commit 5736c29

File tree

3 files changed

+451
-394
lines changed

3 files changed

+451
-394
lines changed

src/Mod/Fem/femcommands/commands.py

+132-25
Original file line numberDiff line numberDiff line change
@@ -1044,6 +1044,110 @@ def Activated(self):
10441044
import femresult.resulttools as resulttools
10451045
resulttools.purge_results(self.active_analysis)
10461046

1047+
class _SolverCalculixContextManager:
1048+
1049+
def __init__(self, make_name, cli_obj_ref_name):
1050+
self.make_name = make_name
1051+
self.cli_name = cli_obj_ref_name
1052+
1053+
def __enter__(self):
1054+
ccx_prefs = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Fem/Ccx")
1055+
FreeCAD.ActiveDocument.openTransaction("Create SolverCalculix")
1056+
FreeCADGui.addModule("ObjectsFem")
1057+
FreeCADGui.addModule("FemGui")
1058+
FreeCADGui.doCommand(
1059+
"{} = ObjectsFem.{}(FreeCAD.ActiveDocument)".format(
1060+
self.cli_name, self.make_name
1061+
)
1062+
)
1063+
FreeCADGui.doCommand(
1064+
"{}.AnalysisType = {}".format(
1065+
self.cli_name, ccx_prefs.GetInt("AnalysisType", 0)
1066+
)
1067+
)
1068+
FreeCADGui.doCommand(
1069+
"{}.EigenmodesCount = {}".format(
1070+
self.cli_name, ccx_prefs.GetInt("EigenmodesCount", 10)
1071+
)
1072+
)
1073+
FreeCADGui.doCommand(
1074+
"{}.EigenmodeLowLimit = {}".format(
1075+
self.cli_name, ccx_prefs.GetFloat("EigenmodeLowLimit", 0.0)
1076+
)
1077+
)
1078+
FreeCADGui.doCommand(
1079+
"{}.EigenmodeHighLimit = {}".format(
1080+
self.cli_name, ccx_prefs.GetFloat("EigenmodeHighLimit", 1000000.0)
1081+
)
1082+
)
1083+
FreeCADGui.doCommand(
1084+
"{}.IterationsMaximum = {}".format(
1085+
self.cli_name, ccx_prefs.GetInt("AnalysisMaxIterations", 2000)
1086+
)
1087+
)
1088+
FreeCADGui.doCommand(
1089+
"{}.TimeInitialStep = {}".format(
1090+
self.cli_name, ccx_prefs.GetFloat("AnalysisTimeInitialStep", 1.0)
1091+
)
1092+
)
1093+
FreeCADGui.doCommand(
1094+
"{}.TimeEnd = {}".format(
1095+
self.cli_name, ccx_prefs.GetFloat("AnalysisTime", 1.0)
1096+
)
1097+
)
1098+
FreeCADGui.doCommand(
1099+
"{}.TimeMinimumStep = {}".format(
1100+
self.cli_name, ccx_prefs.GetFloat("AnalysisTimeMinimumStep", 0.00001)
1101+
)
1102+
)
1103+
FreeCADGui.doCommand(
1104+
"{}.TimeMaximumStep = {}".format(
1105+
self.cli_name, ccx_prefs.GetFloat("AnalysisTimeMaximumStep", 1.0)
1106+
)
1107+
)
1108+
FreeCADGui.doCommand(
1109+
"{}.ThermoMechSteadyState = {}".format(
1110+
self.cli_name, ccx_prefs.GetBool("StaticAnalysis", True)
1111+
)
1112+
)
1113+
FreeCADGui.doCommand(
1114+
"{}.IterationsControlParameterTimeUse = {}".format(
1115+
self.cli_name, ccx_prefs.GetInt("UseNonCcxIterationParam", False)
1116+
)
1117+
)
1118+
FreeCADGui.doCommand(
1119+
"{}.SplitInputWriter = {}".format(
1120+
self.cli_name, ccx_prefs.GetBool("SplitInputWriter", False)
1121+
)
1122+
)
1123+
FreeCADGui.doCommand(
1124+
"{}.MatrixSolverType = {}".format(
1125+
self.cli_name, ccx_prefs.GetInt("Solver", 0)
1126+
)
1127+
)
1128+
FreeCADGui.doCommand(
1129+
"{}.BeamShellResultOutput3D = {}".format(
1130+
self.cli_name, ccx_prefs.GetBool("BeamShellOutput", True)
1131+
)
1132+
)
1133+
FreeCADGui.doCommand(
1134+
"{}.GeometricalNonlinearity = \"{}\"".format(
1135+
self.cli_name,
1136+
"nonlinear" if ccx_prefs.GetBool("NonlinearGeometry", False) else "linear"
1137+
)
1138+
)
1139+
1140+
return self
1141+
1142+
def __exit__(self, exc_type, exc_value, trace):
1143+
FreeCADGui.doCommand(
1144+
"FemGui.getActiveAnalysis().addObject({})".format(self.cli_name)
1145+
)
1146+
FreeCAD.ActiveDocument.commitTransaction()
1147+
# expand analysis object in tree view
1148+
expandParentObject()
1149+
FreeCAD.ActiveDocument.recompute()
1150+
10471151

10481152
class _SolverCcxTools(CommandManager):
10491153
"The FEM_SolverCalculix ccx tools command definition"
@@ -1063,29 +1167,19 @@ def __init__(self):
10631167
self.is_active = "with_analysis"
10641168

10651169
def Activated(self):
1066-
has_nonlinear_material_obj = False
1067-
for m in self.active_analysis.Group:
1068-
if is_of_type(m, "Fem::MaterialMechanicalNonlinear"):
1069-
has_nonlinear_material_obj = True
1070-
FreeCAD.ActiveDocument.openTransaction("Create SolverCalculix")
1071-
FreeCADGui.addModule("ObjectsFem")
1072-
FreeCADGui.addModule("FemGui")
1073-
if has_nonlinear_material_obj:
1074-
FreeCADGui.doCommand(
1075-
"solver = ObjectsFem.makeSolverCalculiXCcxTools(FreeCAD.ActiveDocument)"
1076-
)
1077-
FreeCADGui.doCommand("solver.GeometricalNonlinearity = 'nonlinear'")
1078-
FreeCADGui.doCommand("solver.MaterialNonlinearity = 'nonlinear'")
1079-
FreeCADGui.doCommand("FemGui.getActiveAnalysis().addObject(solver)")
1080-
else:
1081-
FreeCADGui.doCommand(
1082-
"FemGui.getActiveAnalysis().addObject(ObjectsFem."
1083-
"makeSolverCalculiXCcxTools(FreeCAD.ActiveDocument))"
1084-
)
1085-
FreeCAD.ActiveDocument.commitTransaction()
1086-
# expand analysis object in tree view
1087-
expandParentObject()
1088-
FreeCAD.ActiveDocument.recompute()
1170+
with _SolverCalculixContextManager("makeSolverCalculiXCcxTools", "solver") as cm:
1171+
has_nonlinear_material_obj = False
1172+
for m in self.active_analysis.Group:
1173+
if is_of_type(m, "Fem::MaterialMechanicalNonlinear"):
1174+
has_nonlinear_material_obj = True
1175+
1176+
if has_nonlinear_material_obj:
1177+
FreeCADGui.doCommand(
1178+
"{}.GeometricalNonlinearity = 'nonlinear'".format(cm.cli_name)
1179+
)
1180+
FreeCADGui.doCommand(
1181+
"{}.MaterialNonlinearity = 'nonlinear'".format(cm.cli_name)
1182+
)
10891183

10901184

10911185
class _SolverCalculix(CommandManager):
@@ -1104,8 +1198,21 @@ def __init__(self):
11041198
"Creates a FEM solver CalculiX new framework (less result error handling)"
11051199
)
11061200
self.is_active = "with_analysis"
1107-
self.is_active = "with_analysis"
1108-
self.do_activated = "add_obj_on_gui_expand_noset_edit"
1201+
1202+
def Activated(self):
1203+
with _SolverCalculixContextManager("makeSolverCalculix", "solver") as cm:
1204+
has_nonlinear_material_obj = False
1205+
for m in self.active_analysis.Group:
1206+
if is_of_type(m, "Fem::MaterialMechanicalNonlinear"):
1207+
has_nonlinear_material_obj = True
1208+
1209+
if has_nonlinear_material_obj:
1210+
FreeCADGui.doCommand(
1211+
"{}.GeometricalNonlinearity = 'nonlinear'".format(cm.cli_name)
1212+
)
1213+
FreeCADGui.doCommand(
1214+
"{}.MaterialNonlinearity = 'nonlinear'".format(cm.cli_name)
1215+
)
11091216

11101217

11111218
class _SolverControl(CommandManager):

src/Mod/Fem/femobjects/solver_ccxtools.py

+4-12
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,10 @@
3232
import FreeCAD
3333

3434
from . import base_fempythonobject
35-
from femsolver.calculix.solver import add_attributes
36-
from femsolver.calculix.solver import on_restore_of_document
35+
from femsolver.calculix.solver import _BaseSolverCalculix
3736

3837

39-
class SolverCcxTools(base_fempythonobject.BaseFemPythonObject):
38+
class SolverCcxTools(base_fempythonobject.BaseFemPythonObject, _BaseSolverCalculix):
4039
"""The Fem::FemSolver's Proxy python type, add solver specific properties
4140
"""
4241

@@ -45,11 +44,8 @@ class SolverCcxTools(base_fempythonobject.BaseFemPythonObject):
4544
def __init__(self, obj):
4645
super(SolverCcxTools, self).__init__(obj)
4746

48-
ccx_prefs = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Fem/Ccx")
49-
50-
# add attributes
5147
# implemented in framework calculix solver module
52-
add_attributes(obj, ccx_prefs)
48+
self.add_attributes(obj)
5349

5450
obj.addProperty(
5551
"App::PropertyPath",
@@ -62,8 +58,4 @@ def __init__(self, obj):
6258
# only used if the preferences working directory is left blank
6359

6460
def onDocumentRestored(self, obj):
65-
66-
ccx_prefs = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Fem/Ccx")
67-
68-
# implemented in framework calculix solver module
69-
on_restore_of_document(obj, ccx_prefs)
61+
self.on_restore_of_document(obj)

0 commit comments

Comments
 (0)