Merge pull request #23494 from marioalexis84/fem-calculix_default_time_increment

Fem: Use default CalculiX time increments for thermo-mechanical steady state analysis
This commit is contained in:
Chris Hennes
2025-09-07 20:31:06 -05:00
committed by GitHub
8 changed files with 188 additions and 181 deletions

View File

@@ -53,7 +53,7 @@ class SolverCalculiX(base_fempythonobject.BaseFemPythonObject):
_PropHelper(
type="App::PropertyEnumeration",
name="AnalysisType",
group="Solver",
group="AnalysisType",
doc="Type of the analysis",
value=["static", "frequency", "thermomech", "check", "buckling", "electromagnetic"],
)
@@ -106,10 +106,11 @@ class SolverCalculiX(base_fempythonobject.BaseFemPythonObject):
prop.append(
_PropHelper(
type="App::PropertyIntegerConstraint",
name="IterationsMaximum",
group="Solver",
doc="Maximum Number of iterations in each time step before stopping jobs",
value=2000,
name="IncrementsMaximum",
group="TimeIncrement",
doc="Maximum Number of increments in each CalculiX step.\n"
+ "Set to 0 to use CalculiX default value",
value={"value": 2000, "min": 0},
)
)
prop.append(
@@ -124,36 +125,36 @@ class SolverCalculiX(base_fempythonobject.BaseFemPythonObject):
prop.append(
_PropHelper(
type="App::PropertyTime",
name="TimeInitialStep",
group="Solver",
doc="Initial time steps",
value=0.01,
)
)
prop.append(
_PropHelper(
type="App::PropertyTime",
name="TimeEnd",
group="Solver",
doc="End time analysis",
name="TimeInitialIncrement",
group="TimeIncrement",
doc="Initial time increment",
value=1.0,
)
)
prop.append(
_PropHelper(
type="App::PropertyTime",
name="TimeMinimumStep",
group="Solver",
doc="Minimum time step",
name="TimePeriod",
group="TimeIncrement",
doc="Time period of the CalculiX step",
value=1.0,
)
)
prop.append(
_PropHelper(
type="App::PropertyTime",
name="TimeMinimumIncrement",
group="TimeIncrement",
doc="Minimum time increment",
value=0.00001,
)
)
prop.append(
_PropHelper(
type="App::PropertyTime",
name="TimeMaximumStep",
group="Solver",
doc="Maximum time step",
name="TimeMaximumIncrement",
group="TimeIncrement",
doc="Maximum time increment",
value=1.0,
)
)
@@ -161,7 +162,7 @@ class SolverCalculiX(base_fempythonobject.BaseFemPythonObject):
_PropHelper(
type="App::PropertyBool",
name="ThermoMechSteadyState",
group="Solver",
group="AnalysisType",
doc="Choose between steady state thermo mech or transient thermo mech analysis",
value=True,
)
@@ -225,21 +226,12 @@ class SolverCalculiX(base_fempythonobject.BaseFemPythonObject):
prop.append(
_PropHelper(
type="App::PropertyBool",
name="IterationsUserDefinedIncrementations",
group="Solver",
doc="Set to True to switch off the ccx automatic incrementation completely\n"
+ "(ccx parameter DIRECT). Use with care. Analysis may not converge!",
value=False,
)
)
prop.append(
_PropHelper(
type="App::PropertyBool",
name="IterationsUserDefinedTimeStepLength",
group="Solver",
doc="Set to True to use the user defined time steps.\n"
+ "They are set with TimeInitialStep, TimeEnd, TimeMinimum and TimeMaximum",
value=False,
name="AutomaticIncrementation",
group="TimeIncrement",
doc="If False, switch off automatic incrementation via `DIRECT`\n"
+ "parameter and ignore minimum and maximum time increments.\n"
+ "Analysis may not converge!",
value=True,
)
)
prop.append(
@@ -271,7 +263,7 @@ class SolverCalculiX(base_fempythonobject.BaseFemPythonObject):
_PropHelper(
type="App::PropertyBool",
name="BeamReducedIntegration",
group="Solver",
group="ElementModel",
doc="Set to True to use beam elements with reduced integration",
value=True,
)
@@ -289,7 +281,7 @@ class SolverCalculiX(base_fempythonobject.BaseFemPythonObject):
_PropHelper(
type="App::PropertyEnumeration",
name="ModelSpace",
group="Solver",
group="ElementModel",
doc="Type of model space",
value=["3D", "plane stress", "plane strain", "axisymmetric"],
)
@@ -298,7 +290,7 @@ class SolverCalculiX(base_fempythonobject.BaseFemPythonObject):
_PropHelper(
type="App::PropertyEnumeration",
name="ThermoMechType",
group="Solver",
group="AnalysisType",
doc="Type of thermomechanical analysis",
value=["coupled", "uncoupled", "pure heat transfer"],
)
@@ -316,7 +308,7 @@ class SolverCalculiX(base_fempythonobject.BaseFemPythonObject):
_PropHelper(
type="App::PropertyEnumeration",
name="ElectromagneticMode",
group="Solver",
group="AnalysisType",
doc="Electromagnetic mode",
value=["electrostatic"],
)
@@ -325,7 +317,7 @@ class SolverCalculiX(base_fempythonobject.BaseFemPythonObject):
_PropHelper(
type="App::PropertyBool",
name="ExcludeBendingStiffness",
group="Solver",
group="ElementModel",
doc="Exclude bending stiffness to replace shells with membranes or beams with trusses",
value=False,
)
@@ -348,3 +340,37 @@ class SolverCalculiX(base_fempythonobject.BaseFemPythonObject):
obj.getPropertyByName(prop.name)
except Base.PropertyError:
prop.add_to_object(obj)
# remove old properties
try:
obj.AutomaticIncrementation = not obj.getPropertyByName(
"IterationsUserDefinedIncrementations"
)
obj.setPropertyStatus("IterationsUserDefinedIncrementations", "-LockDynamic")
obj.removeProperty("IterationsUserDefinedIncrementations")
obj.setPropertyStatus("IterationsUserDefinedTimeStepLength", "-LockDynamic")
obj.removeProperty("IterationsUserDefinedTimeStepLength")
obj.TimeInitialIncrement = obj.getPropertyByName("TimeInitialStep")
obj.setPropertyStatus("TimeInitialStep", "-LockDynamic")
obj.removeProperty("TimeInitialStep")
obj.TimePeriod = obj.getPropertyByName("TimeEnd")
obj.setPropertyStatus("TimeEnd", "-LockDynamic")
obj.removeProperty("TimeEnd")
obj.TimeMaximumIncrement = obj.getPropertyByName("TimeMaximumStep")
obj.setPropertyStatus("TimeMaximumStep", "-LockDynamic")
obj.removeProperty("TimeMaximumStep")
obj.TimeMinimumIncrement = obj.getPropertyByName("TimeMinimumStep")
obj.setPropertyStatus("TimeMinimumStep", "-LockDynamic")
obj.removeProperty("TimeMinimumStep")
obj.IncrementsMaximum = obj.getPropertyByName("IterationsMaximum")
obj.setPropertyStatus("IterationsMaximum", "-LockDynamic")
obj.removeProperty("IterationsMaximum")
except Base.PropertyError:
# do nothing
pass

View File

@@ -29,13 +29,11 @@ __url__ = "https://www.freecad.org"
# \ingroup FEM
# \brief solver calculix ccx tools object
import FreeCAD
from . import base_fempythonobject
from femsolver.calculix.solver import _BaseSolverCalculix
from .base_fempythonobject import _PropHelper
from .solver_calculix import SolverCalculiX
class SolverCcxTools(base_fempythonobject.BaseFemPythonObject, _BaseSolverCalculix):
class SolverCcxTools(SolverCalculiX):
"""The Fem::FemSolver's Proxy python type, add solver specific properties"""
Type = "Fem::SolverCcxTools"
@@ -43,18 +41,26 @@ class SolverCcxTools(base_fempythonobject.BaseFemPythonObject, _BaseSolverCalcul
def __init__(self, obj):
super().__init__(obj)
# implemented in framework calculix solver module
self.add_attributes(obj)
def _get_properties(self):
prop = super()._get_properties()
obj.addProperty(
"App::PropertyPath",
"WorkingDir",
"Fem",
"Working directory for calculations, will only be used it is left blank in preferences",
# set analysis types supported by CcxTools solver
for p in prop:
if p.name == "AnalysisType":
p.value = ["static", "frequency", "thermomech", "check", "buckling"]
# remove unused properties
prop = list(filter(lambda p: p.name != "ElectromagneticMode", prop))
prop.append(
_PropHelper(
type="App::PropertyPath",
name="WorkingDir",
group="Solver",
doc="Working directory for calculations.\n"
+ "Will only be used it is left blank in preferences",
value="",
)
)
obj.setPropertyStatus("WorkingDir", "LockDynamic")
# the working directory is not set, the solver working directory is
# only used if the preferences working directory is left blank
def onDocumentRestored(self, obj):
self.on_restore_of_document(obj)
return prop