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:
@@ -302,16 +302,16 @@
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="l_ccx_initial_time_step">
|
||||
<widget class="QLabel" name="l_ccx_initial_time_increment">
|
||||
<property name="text">
|
||||
<string>Initial time step</string>
|
||||
<string>Initial time increment</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="l_ccx_analysis_time">
|
||||
<widget class="QLabel" name="l_ccx_time_period">
|
||||
<property name="text">
|
||||
<string>End time</string>
|
||||
<string>Time period</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -427,38 +427,10 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="2">
|
||||
<widget class="Gui::PrefDoubleSpinBox" name="dsb_ccx_maximum_time_step">
|
||||
<widget class="Gui::PrefDoubleSpinBox" name="dsb_ccx_maximum_time_increment">
|
||||
<property name="contextMenuPolicy">
|
||||
<enum>Qt::DefaultContextMenu</enum>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string notr="true"> s</string>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>0.000000001000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
<property name="prefEntry" stdset="0">
|
||||
<cstring>AnalysisTimeMaximumStep</cstring>
|
||||
</property>
|
||||
<property name="prefPath" stdset="0">
|
||||
<cstring>Mod/Fem/Ccx</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="2">
|
||||
<widget class="Gui::PrefDoubleSpinBox" name="dsb_ccx_analysis_time">
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
@@ -478,7 +450,35 @@
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
<property name="prefEntry" stdset="0">
|
||||
<cstring>AnalysisTime</cstring>
|
||||
<cstring>TimeMaximumIncrement</cstring>
|
||||
</property>
|
||||
<property name="prefPath" stdset="0">
|
||||
<cstring>Mod/Fem/Ccx</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="2">
|
||||
<widget class="Gui::PrefDoubleSpinBox" name="dsb_ccx_time_period">
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string notr="true"> s</string>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>0.000000001000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
<property name="prefEntry" stdset="0">
|
||||
<cstring>TimePeriod</cstring>
|
||||
</property>
|
||||
<property name="prefPath" stdset="0">
|
||||
<cstring>Mod/Fem/Ccx</cstring>
|
||||
@@ -516,16 +516,16 @@
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="l_ccx_max_iterations">
|
||||
<widget class="QLabel" name="l_ccx_max_increments">
|
||||
<property name="text">
|
||||
<string>Maximum number of iterations</string>
|
||||
<string>Maximum number of increments</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="l_ccx_minimum_time_step">
|
||||
<widget class="QLabel" name="l_ccx_minimum_time_increment">
|
||||
<property name="text">
|
||||
<string>Minimum time step</string>
|
||||
<string>Minimum time increment</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -543,7 +543,7 @@
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="7" column="2">
|
||||
<widget class="Gui::PrefDoubleSpinBox" name="dsb_ccx_minimum_time_step">
|
||||
<widget class="Gui::PrefDoubleSpinBox" name="dsb_ccx_minimum_time_increment">
|
||||
<property name="contextMenuPolicy">
|
||||
<enum>Qt::DefaultContextMenu</enum>
|
||||
</property>
|
||||
@@ -566,7 +566,7 @@
|
||||
<double>0.000010000000000</double>
|
||||
</property>
|
||||
<property name="prefEntry" stdset="0">
|
||||
<cstring>AnalysisTimeMinimumStep</cstring>
|
||||
<cstring>TimeMinimumIncrement</cstring>
|
||||
</property>
|
||||
<property name="prefPath" stdset="0">
|
||||
<cstring>Mod/Fem/Ccx</cstring>
|
||||
@@ -590,7 +590,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="2">
|
||||
<widget class="Gui::PrefDoubleSpinBox" name="dsb_ccx_initial_time_step">
|
||||
<widget class="Gui::PrefDoubleSpinBox" name="dsb_ccx_initial_time_increment">
|
||||
<property name="contextMenuPolicy">
|
||||
<enum>Qt::DefaultContextMenu</enum>
|
||||
</property>
|
||||
@@ -610,10 +610,10 @@
|
||||
<double>0.010000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>0.010000000000000</double>
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
<property name="prefEntry" stdset="0">
|
||||
<cstring>AnalysisTimeInitialStep</cstring>
|
||||
<cstring>TimeInitialIncrement</cstring>
|
||||
</property>
|
||||
<property name="prefPath" stdset="0">
|
||||
<cstring>Mod/Fem/Ccx</cstring>
|
||||
@@ -628,7 +628,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="2">
|
||||
<widget class="Gui::PrefSpinBox" name="sb_ccx_max_iterations">
|
||||
<widget class="Gui::PrefSpinBox" name="sb_ccx_max_increments">
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
@@ -645,7 +645,7 @@
|
||||
<number>2000</number>
|
||||
</property>
|
||||
<property name="prefEntry" stdset="0">
|
||||
<cstring>AnalysisMaxIterations</cstring>
|
||||
<cstring>StepMaxIncrements</cstring>
|
||||
</property>
|
||||
<property name="prefPath" stdset="0">
|
||||
<cstring>Mod/Fem/Ccx</cstring>
|
||||
@@ -653,9 +653,9 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="l_ccx_maximum_time_step">
|
||||
<widget class="QLabel" name="l_ccx_maximum_time_increment">
|
||||
<property name="text">
|
||||
<string>Maximum time step</string>
|
||||
<string>Maximum time increment</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
@@ -43,8 +43,8 @@ DlgSettingsFemCcxImp::DlgSettingsFemCcxImp(QWidget* parent)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
// set ranges
|
||||
ui->dsb_ccx_analysis_time->setMaximum(std::numeric_limits<float>::max());
|
||||
ui->dsb_ccx_initial_time_step->setMaximum(std::numeric_limits<float>::max());
|
||||
ui->dsb_ccx_time_period->setMaximum(std::numeric_limits<float>::max());
|
||||
ui->dsb_ccx_initial_time_increment->setMaximum(std::numeric_limits<float>::max());
|
||||
|
||||
connect(ui->fc_ccx_binary_path,
|
||||
&Gui::PrefFileChooser::fileNameChanged,
|
||||
@@ -67,11 +67,11 @@ void DlgSettingsFemCcxImp::saveSettings()
|
||||
ui->cb_use_iterations_param->onSave();
|
||||
|
||||
ui->cb_static->onSave();
|
||||
ui->sb_ccx_max_iterations->onSave(); // Max number of iterations
|
||||
ui->dsb_ccx_initial_time_step->onSave(); // Initial time step
|
||||
ui->dsb_ccx_analysis_time->onSave(); // Analysis time
|
||||
ui->dsb_ccx_minimum_time_step->onSave(); // Minimum time step
|
||||
ui->dsb_ccx_maximum_time_step->onSave(); // Maximum time step
|
||||
ui->sb_ccx_max_increments->onSave(); // Max number of increments
|
||||
ui->dsb_ccx_initial_time_increment->onSave(); // Initial time increment
|
||||
ui->dsb_ccx_time_period->onSave(); // Step time period
|
||||
ui->dsb_ccx_minimum_time_increment->onSave(); // Minimum time increment
|
||||
ui->dsb_ccx_maximum_time_increment->onSave(); // Maximum time increment
|
||||
ui->ckb_pipeline_result->onSave();
|
||||
ui->ckb_result_format->onSave();
|
||||
|
||||
@@ -96,11 +96,11 @@ void DlgSettingsFemCcxImp::loadSettings()
|
||||
ui->cb_use_iterations_param->onRestore();
|
||||
|
||||
ui->cb_static->onRestore();
|
||||
ui->sb_ccx_max_iterations->onRestore(); // Max number of iterations
|
||||
ui->dsb_ccx_initial_time_step->onRestore(); // Initial time step
|
||||
ui->dsb_ccx_analysis_time->onRestore(); // Analysis time
|
||||
ui->dsb_ccx_minimum_time_step->onRestore(); // Minimum time step
|
||||
ui->dsb_ccx_maximum_time_step->onRestore(); // Maximum time step
|
||||
ui->sb_ccx_max_increments->onRestore(); // Max number of increments
|
||||
ui->dsb_ccx_initial_time_increment->onRestore(); // Initial time increment
|
||||
ui->dsb_ccx_time_period->onRestore(); // Step time period
|
||||
ui->dsb_ccx_minimum_time_increment->onRestore(); // Minimum time increment
|
||||
ui->dsb_ccx_maximum_time_increment->onRestore(); // Maximum time increment
|
||||
ui->ckb_pipeline_result->onRestore();
|
||||
ui->ckb_result_format->onRestore();
|
||||
|
||||
|
||||
@@ -962,26 +962,26 @@ class _SolverCalculixContextManager:
|
||||
)
|
||||
)
|
||||
FreeCADGui.doCommand(
|
||||
"{}.IterationsMaximum = {}".format(
|
||||
self.cli_name, ccx_prefs.GetInt("AnalysisMaxIterations", 2000)
|
||||
"{}.IncrementsMaximum = {}".format(
|
||||
self.cli_name, ccx_prefs.GetInt("StepMaxIncrements", 2000)
|
||||
)
|
||||
)
|
||||
FreeCADGui.doCommand(
|
||||
"{}.TimeInitialStep = {}".format(
|
||||
self.cli_name, ccx_prefs.GetFloat("AnalysisTimeInitialStep", 1.0)
|
||||
"{}.TimeInitialIncrement = {}".format(
|
||||
self.cli_name, ccx_prefs.GetFloat("TimeInitialIncrement", 1.0)
|
||||
)
|
||||
)
|
||||
FreeCADGui.doCommand(
|
||||
"{}.TimeEnd = {}".format(self.cli_name, ccx_prefs.GetFloat("AnalysisTime", 1.0))
|
||||
"{}.TimePeriod = {}".format(self.cli_name, ccx_prefs.GetFloat("TimePeriod", 1.0))
|
||||
)
|
||||
FreeCADGui.doCommand(
|
||||
"{}.TimeMinimumStep = {}".format(
|
||||
self.cli_name, ccx_prefs.GetFloat("AnalysisTimeMinimumStep", 0.00001)
|
||||
"{}.TimeMinimumIncrement = {}".format(
|
||||
self.cli_name, ccx_prefs.GetFloat("TimeMinimumIncrement", 0.00001)
|
||||
)
|
||||
)
|
||||
FreeCADGui.doCommand(
|
||||
"{}.TimeMaximumStep = {}".format(
|
||||
self.cli_name, ccx_prefs.GetFloat("AnalysisTimeMaximumStep", 1.0)
|
||||
"{}.TimeMaximumIncrement = {}".format(
|
||||
self.cli_name, ccx_prefs.GetFloat("TimeMaximumIncrement", 1.0)
|
||||
)
|
||||
)
|
||||
FreeCADGui.doCommand(
|
||||
|
||||
@@ -146,7 +146,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# solver_obj.MatrixSolverType = "default"
|
||||
solver_obj.MatrixSolverType = "spooles" # thomas
|
||||
solver_obj.SplitInputWriter = False
|
||||
solver_obj.IterationsMaximum = 2000
|
||||
solver_obj.IncrementsMaximum = 2000
|
||||
# solver_obj.IterationsControlParameterTimeUse = True # thermomech spine
|
||||
analysis.addObject(solver_obj)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -37,7 +37,7 @@ def write_step_equation(f, ccxwriter):
|
||||
# build STEP line
|
||||
step = "*STEP"
|
||||
if ccxwriter.solver_obj.GeometricalNonlinearity == "nonlinear":
|
||||
if ccxwriter.analysis_type == "static" or ccxwriter.analysis_type == "thermomech":
|
||||
if ccxwriter.analysis_type in ["static", "thermomech"]:
|
||||
# https://www.comsol.com/blogs/what-is-geometric-nonlinearity
|
||||
step += ", NLGEOM"
|
||||
elif ccxwriter.analysis_type == "frequency":
|
||||
@@ -45,12 +45,11 @@ def write_step_equation(f, ccxwriter):
|
||||
"Analysis type frequency and geometrical nonlinear "
|
||||
"analysis are not allowed together, linear is used instead!\n"
|
||||
)
|
||||
if ccxwriter.solver_obj.IterationsMaximum:
|
||||
if ccxwriter.analysis_type == "thermomech" or ccxwriter.analysis_type == "static":
|
||||
step += f", INC={ccxwriter.solver_obj.IterationsMaximum}"
|
||||
elif ccxwriter.analysis_type == "frequency" or ccxwriter.analysis_type == "buckling":
|
||||
# parameter is for thermomechanical analysis only, see ccx manual *STEP
|
||||
pass
|
||||
|
||||
if ccxwriter.solver_obj.IncrementsMaximum:
|
||||
if ccxwriter.analysis_type in ["static", "thermomech", "electromagnetic"]:
|
||||
step += f", INC={ccxwriter.solver_obj.IncrementsMaximum}"
|
||||
|
||||
# write STEP line
|
||||
f.write(step + "\n")
|
||||
|
||||
@@ -63,6 +62,7 @@ def write_step_equation(f, ccxwriter):
|
||||
|
||||
# ANALYSIS type line
|
||||
# analysis line --> analysis type
|
||||
analysis_type = ""
|
||||
if ccxwriter.analysis_type == "static":
|
||||
analysis_type = "*STATIC"
|
||||
elif ccxwriter.analysis_type == "frequency":
|
||||
@@ -74,12 +74,16 @@ def write_step_equation(f, ccxwriter):
|
||||
analysis_type = "*UNCOUPLED TEMPERATURE-DISPLACEMENT"
|
||||
elif ccxwriter.solver_obj.ThermoMechType == "pure heat transfer":
|
||||
analysis_type = "*HEAT TRANSFER"
|
||||
if ccxwriter.solver_obj.ThermoMechSteadyState:
|
||||
analysis_type += ", STEADY STATE"
|
||||
elif ccxwriter.analysis_type == "check":
|
||||
analysis_type = "*NO ANALYSIS"
|
||||
elif ccxwriter.analysis_type == "buckling":
|
||||
analysis_type = "*BUCKLE"
|
||||
elif ccxwriter.analysis_type == "electromagnetic":
|
||||
analysis_type = "*HEAT TRANSFER, STEADY STATE"
|
||||
if ccxwriter.solver_obj.ElectromagneticMode == "electrostatic":
|
||||
analysis_type = "*HEAT TRANSFER, STEADY STATE"
|
||||
|
||||
# analysis line --> solver type
|
||||
# https://forum.freecad.org/viewtopic.php?f=18&t=43178
|
||||
if ccxwriter.solver_obj.MatrixSolverType == "default":
|
||||
@@ -94,45 +98,22 @@ def write_step_equation(f, ccxwriter):
|
||||
analysis_type += ", SOLVER=ITERATIVE SCALING"
|
||||
elif ccxwriter.solver_obj.MatrixSolverType == "iterativecholesky":
|
||||
analysis_type += ", SOLVER=ITERATIVE CHOLESKY"
|
||||
# analysis line --> user defined incrementations --> parameter DIRECT
|
||||
# --> completely switch off ccx automatic incrementation
|
||||
if ccxwriter.solver_obj.IterationsUserDefinedIncrementations:
|
||||
|
||||
# analysis line --> automatic incrementation --> parameter DIRECT
|
||||
# completely switch off ccx automatic incrementation
|
||||
if not ccxwriter.solver_obj.AutomaticIncrementation:
|
||||
if ccxwriter.analysis_type in ["static", "thermomech", "electromagnetic"]:
|
||||
analysis_type += ", DIRECT"
|
||||
elif ccxwriter.analysis_type == "frequency":
|
||||
FreeCAD.Console.PrintMessage(
|
||||
"Analysis type frequency and IterationsUserDefinedIncrementations "
|
||||
"are not allowed together, it is ignored\n"
|
||||
)
|
||||
# analysis line --> steadystate --> thermomech only
|
||||
if ccxwriter.solver_obj.ThermoMechSteadyState:
|
||||
# bernd: I do not know if STEADY STATE is allowed with DIRECT
|
||||
# but since time steps are 1.0 it makes no sense IMHO
|
||||
if ccxwriter.analysis_type == "thermomech":
|
||||
analysis_type += ", STEADY STATE"
|
||||
# Set time to 1 and ignore user inputs for steady state
|
||||
ccxwriter.solver_obj.TimeInitialStep = 1.0
|
||||
ccxwriter.solver_obj.TimeEnd = 1.0
|
||||
elif (
|
||||
ccxwriter.analysis_type == "static"
|
||||
or ccxwriter.analysis_type == "frequency"
|
||||
or ccxwriter.analysis_type == "buckling"
|
||||
):
|
||||
pass # not supported for static and frequency!
|
||||
|
||||
# ANALYSIS parameter line
|
||||
analysis_parameter = ""
|
||||
if ccxwriter.analysis_type == "static" or ccxwriter.analysis_type == "check":
|
||||
if (
|
||||
ccxwriter.solver_obj.IterationsUserDefinedIncrementations is True
|
||||
or ccxwriter.solver_obj.IterationsUserDefinedTimeStepLength is True
|
||||
):
|
||||
analysis_parameter = "{},{},{},{}".format(
|
||||
ccxwriter.solver_obj.TimeInitialStep.getValueAs("s").Value,
|
||||
ccxwriter.solver_obj.TimeEnd.getValueAs("s").Value,
|
||||
ccxwriter.solver_obj.TimeMinimumStep.getValueAs("s").Value,
|
||||
ccxwriter.solver_obj.TimeMaximumStep.getValueAs("s").Value,
|
||||
)
|
||||
if ccxwriter.analysis_type in ["static", "thermomech", "electromagnetic"]:
|
||||
analysis_parameter = "{},{},{},{}".format(
|
||||
ccxwriter.solver_obj.TimeInitialIncrement.getValueAs("s").Value,
|
||||
ccxwriter.solver_obj.TimePeriod.getValueAs("s").Value,
|
||||
ccxwriter.solver_obj.TimeMinimumIncrement.getValueAs("s").Value,
|
||||
ccxwriter.solver_obj.TimeMaximumIncrement.getValueAs("s").Value,
|
||||
)
|
||||
elif ccxwriter.analysis_type == "frequency":
|
||||
if (
|
||||
ccxwriter.solver_obj.EigenmodeLowLimit == 0.0
|
||||
@@ -145,19 +126,13 @@ def write_step_equation(f, ccxwriter):
|
||||
ccxwriter.solver_obj.EigenmodeLowLimit.getValueAs("Hz").Value,
|
||||
ccxwriter.solver_obj.EigenmodeHighLimit.getValueAs("Hz").Value,
|
||||
)
|
||||
elif ccxwriter.analysis_type == "thermomech":
|
||||
# OvG: 1.0 increment, total time 1 for steady state will cut back automatically
|
||||
analysis_parameter = "{},{},{},{}".format(
|
||||
ccxwriter.solver_obj.TimeInitialStep.getValueAs("s").Value,
|
||||
ccxwriter.solver_obj.TimeEnd.getValueAs("s").Value,
|
||||
ccxwriter.solver_obj.TimeMinimumStep.getValueAs("s").Value,
|
||||
ccxwriter.solver_obj.TimeMaximumStep.getValueAs("s").Value,
|
||||
)
|
||||
elif ccxwriter.analysis_type == "buckling":
|
||||
analysis_parameter = "{},{}".format(
|
||||
ccxwriter.solver_obj.BucklingFactors,
|
||||
ccxwriter.solver_obj.BucklingAccuracy,
|
||||
)
|
||||
elif ccxwriter.analysis_type == "check":
|
||||
analysis_parameter = ""
|
||||
|
||||
# write analysis type line, analysis parameter line
|
||||
f.write(analysis_type + "\n")
|
||||
|
||||
@@ -7087,7 +7087,7 @@ Nall,273.0
|
||||
***********************************************************
|
||||
** At least one step is needed to run an CalculiX analysis of FreeCAD
|
||||
*STEP, INC=2000
|
||||
*COUPLED TEMPERATURE-DISPLACEMENT, SOLVER=SPOOLES, STEADY STATE
|
||||
*COUPLED TEMPERATURE-DISPLACEMENT, STEADY STATE, SOLVER=SPOOLES
|
||||
1.0,1.0,1e-05,1.0
|
||||
|
||||
***********************************************************
|
||||
|
||||
Reference in New Issue
Block a user