Fem: Change CalculiX time and frequency properties to quantites
This commit is contained in:
committed by
Benjamin Nauck
parent
7d57569eb4
commit
ab1e4384f1
@@ -31,16 +31,294 @@ __url__ = "https://www.freecad.org"
|
||||
# \brief solver CalculiX object
|
||||
|
||||
from . import base_fempythonobject
|
||||
from femsolver.calculix.solver import _BaseSolverCalculix
|
||||
|
||||
_PropHelper = base_fempythonobject._PropHelper
|
||||
|
||||
|
||||
class SolverCalculiX(base_fempythonobject.BaseFemPythonObject, _BaseSolverCalculix):
|
||||
class SolverCalculiX(base_fempythonobject.BaseFemPythonObject):
|
||||
|
||||
Type = "Fem::SolverCalculiX"
|
||||
|
||||
def __init__(self, obj):
|
||||
super().__init__(obj)
|
||||
self.add_attributes(obj)
|
||||
|
||||
def onDocumentRestored(self, obj):
|
||||
self.on_restore_of_document(obj)
|
||||
for prop in self._get_properties():
|
||||
prop.add_to_object(obj)
|
||||
|
||||
def _get_properties(self):
|
||||
prop = []
|
||||
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyEnumeration",
|
||||
name="AnalysisType",
|
||||
group="Solver",
|
||||
doc="Type of the analysis",
|
||||
value=["static", "frequency", "thermomech", "check", "buckling", "electromagnetic"],
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyEnumeration",
|
||||
name="GeometricalNonlinearity",
|
||||
group="Solver",
|
||||
doc="Set geometrical nonlinearity",
|
||||
value=["linear", "nonlinear"],
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyEnumeration",
|
||||
name="MaterialNonlinearity",
|
||||
group="Solver",
|
||||
doc="Set material nonlinearity",
|
||||
value=["linear", "nonlinear"],
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyIntegerConstraint",
|
||||
name="EigenmodesCount",
|
||||
group="Solver",
|
||||
doc="Number of modes for frequency calculations",
|
||||
value=(10, 1, 100, 1),
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyFrequency",
|
||||
name="EigenmodeLowLimit",
|
||||
group="Solver",
|
||||
doc="Low frequency limit for eigenmode calculations",
|
||||
value=0.0,
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyFrequency",
|
||||
name="EigenmodeHighLimit",
|
||||
group="Solver",
|
||||
doc="High frequency limit for eigenmode calculations",
|
||||
value=1000000.0,
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyIntegerConstraint",
|
||||
name="IterationsMaximum",
|
||||
group="Solver",
|
||||
doc="Maximum Number of iterations in each time step before stopping jobs",
|
||||
value=2000,
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyIntegerConstraint",
|
||||
name="BucklingFactors",
|
||||
group="Solver",
|
||||
doc="Calculates the lowest buckling modes to the corresponding buckling factors",
|
||||
value=1,
|
||||
)
|
||||
)
|
||||
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",
|
||||
value=1.0,
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyTime",
|
||||
name="TimeMinimumStep",
|
||||
group="Solver",
|
||||
doc="Minimum time step",
|
||||
value=0.00001,
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyTime",
|
||||
name="TimeMaximumStep",
|
||||
group="Solver",
|
||||
doc="Maximum time step",
|
||||
value=1.0,
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyBool",
|
||||
name="ThermoMechSteadyState",
|
||||
group="Solver",
|
||||
doc="Choose between steady state thermo mech or transient thermo mech analysis",
|
||||
value=True,
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyBool",
|
||||
name="IterationsControlParameterTimeUse",
|
||||
group="Solver",
|
||||
doc="Use the user defined time incrementation control parameter",
|
||||
value=False,
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyBool",
|
||||
name="SplitInputWriter",
|
||||
group="Solver",
|
||||
doc="Split writing of ccx input file",
|
||||
value=False,
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyString",
|
||||
name="IterationsControlParameterIter",
|
||||
group="Solver",
|
||||
doc="User defined time incrementation iterations control parameter",
|
||||
value="{I_0},{I_R},{I_P},{I_C},{I_L},{I_G},{I_S},{I_A},{I_J},{I_T}".format(
|
||||
I_0=4,
|
||||
I_R=8,
|
||||
I_P=9,
|
||||
I_C=200, # ccx default = 16
|
||||
I_L=10,
|
||||
I_G=400, # ccx default = 4
|
||||
I_S="",
|
||||
I_A=200, # ccx default = 5
|
||||
I_J="",
|
||||
I_T="",
|
||||
),
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyString",
|
||||
name="IterationsControlParameterCutb",
|
||||
group="Solver",
|
||||
doc="User defined time incrementation cutbacks control parameter",
|
||||
value="{D_f},{D_C},{D_B},{D_A},{D_S},{D_H},{D_D},{W_G}".format(
|
||||
D_f=0.25,
|
||||
D_C=0.5,
|
||||
D_B=0.75,
|
||||
D_A=0.85,
|
||||
D_S="",
|
||||
D_H="",
|
||||
D_D=1.5,
|
||||
W_G="",
|
||||
),
|
||||
)
|
||||
)
|
||||
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,
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyEnumeration",
|
||||
name="MatrixSolverType",
|
||||
group="Solver",
|
||||
doc="Type of solver to use",
|
||||
value=[
|
||||
"default",
|
||||
"pastix",
|
||||
"pardiso",
|
||||
"spooles",
|
||||
"iterativescaling",
|
||||
"iterativecholesky",
|
||||
],
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyBool",
|
||||
name="BeamShellResultOutput3D",
|
||||
group="Solver",
|
||||
doc="Output 3D results for 1D and 2D analysis ",
|
||||
value=True,
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyBool",
|
||||
name="BeamReducedIntegration",
|
||||
group="Solver",
|
||||
doc="Set to True to use beam elements with reduced integration",
|
||||
value=True,
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyIntegerConstraint",
|
||||
name="OutputFrequency",
|
||||
group="Solver",
|
||||
doc="Set the output frequency in increments",
|
||||
value=1,
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyEnumeration",
|
||||
name="ModelSpace",
|
||||
group="Solver",
|
||||
doc="Type of model space",
|
||||
value=["3D", "plane stress", "plane strain", "axisymmetric"],
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyEnumeration",
|
||||
name="ThermoMechType",
|
||||
group="Solver",
|
||||
doc="Type of thermomechanical analysis",
|
||||
value=["coupled", "uncoupled", "pure heat transfer"],
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyFloatConstraint",
|
||||
name="BucklingAccuracy",
|
||||
group="Solver",
|
||||
doc="Accuracy for buckling analysis",
|
||||
value=0.01,
|
||||
)
|
||||
)
|
||||
prop.append(
|
||||
_PropHelper(
|
||||
type="App::PropertyEnumeration",
|
||||
name="ElectromagneticMode",
|
||||
group="Solver",
|
||||
doc="Electromagnetic mode",
|
||||
value=["electrostatic"],
|
||||
)
|
||||
)
|
||||
|
||||
return prop
|
||||
|
||||
@@ -109,25 +109,43 @@ class _BaseSolverCalculix:
|
||||
)
|
||||
obj.EigenmodesCount = (10, 1, 100, 1)
|
||||
|
||||
low_limit = 0.0
|
||||
if (
|
||||
hasattr(obj, "EigenmodeLowLimit")
|
||||
and obj.getTypeIdOfProperty("EigenmodeLowLimit") == "App::PropertyFloatConstraint"
|
||||
):
|
||||
low_limit = obj.EigenmodeLowLimit
|
||||
obj.setPropertyStatus("EigenmodeLowLimit", "-LockDynamic")
|
||||
obj.removeProperty("EigenmodeLowLimit")
|
||||
|
||||
if not hasattr(obj, "EigenmodeLowLimit"):
|
||||
obj.addProperty(
|
||||
"App::PropertyFloatConstraint",
|
||||
"App::PropertyFrequency",
|
||||
"EigenmodeLowLimit",
|
||||
"Fem",
|
||||
"Low frequency limit for eigenmode calculations",
|
||||
locked=True,
|
||||
)
|
||||
obj.EigenmodeLowLimit = (0.0, 0.0, 1000000.0, 10000.0)
|
||||
obj.EigenmodeLowLimit = low_limit
|
||||
|
||||
high_limit = 1000000.0
|
||||
if (
|
||||
hasattr(obj, "EigenmodeHighLimit")
|
||||
and obj.getTypeIdOfProperty("EigenmodeHighLimit") == "App::PropertyFloatConstraint"
|
||||
):
|
||||
high_limit = obj.EigenmodeHighLimit
|
||||
obj.setPropertyStatus("EigenmodeHighLimit", "-LockDynamic")
|
||||
obj.removeProperty("EigenmodeHighLimit")
|
||||
|
||||
if not hasattr(obj, "EigenmodeHighLimit"):
|
||||
obj.addProperty(
|
||||
"App::PropertyFloatConstraint",
|
||||
"App::PropertyFrequency",
|
||||
"EigenmodeHighLimit",
|
||||
"Fem",
|
||||
"High frequency limit for eigenmode calculations",
|
||||
locked=True,
|
||||
)
|
||||
obj.EigenmodeHighLimit = (1000000.0, 0.0, 1000000.0, 10000.0)
|
||||
obj.EigenmodeHighLimit = high_limit
|
||||
|
||||
if not hasattr(obj, "IterationsMaximum"):
|
||||
help_string_IterationsMaximum = (
|
||||
@@ -156,41 +174,75 @@ class _BaseSolverCalculix:
|
||||
)
|
||||
obj.BucklingFactors = 1
|
||||
|
||||
time_initial_step = 0.01
|
||||
if (
|
||||
hasattr(obj, "TimeInitialStep")
|
||||
and obj.getTypeIdOfProperty("TimeInitialStep") == "App::PropertyFloatConstraint"
|
||||
):
|
||||
time_initial_step = obj.TimeInitialStep
|
||||
obj.setPropertyStatus("TimeInitialStep", "-LockDynamic")
|
||||
obj.removeProperty("TimeInitialStep")
|
||||
|
||||
if not hasattr(obj, "TimeInitialStep"):
|
||||
obj.addProperty(
|
||||
"App::PropertyFloatConstraint",
|
||||
"App::PropertyTime",
|
||||
"TimeInitialStep",
|
||||
"Fem",
|
||||
"Initial time steps",
|
||||
locked=True,
|
||||
)
|
||||
obj.TimeInitialStep = 0.01
|
||||
obj.TimeInitialStep = time_initial_step
|
||||
|
||||
time_end = 1.0
|
||||
if (
|
||||
hasattr(obj, "TimeEnd")
|
||||
and obj.getTypeIdOfProperty("TimeEnd") == "App::PropertyFloatConstraint"
|
||||
):
|
||||
time_end = obj.TimeEnd
|
||||
obj.setPropertyStatus("TimeEnd", "-LockDynamic")
|
||||
obj.removeProperty("TimeEnd")
|
||||
|
||||
if not hasattr(obj, "TimeEnd"):
|
||||
obj.addProperty(
|
||||
"App::PropertyFloatConstraint", "TimeEnd", "Fem", "End time analysis", locked=True
|
||||
)
|
||||
obj.TimeEnd = 1.0
|
||||
obj.addProperty("App::PropertyTime", "TimeEnd", "Fem", "End time analysis", locked=True)
|
||||
obj.TimeEnd = time_end
|
||||
|
||||
time_minimum_step = 0.00001
|
||||
if (
|
||||
hasattr(obj, "TimeMinimumStep")
|
||||
and obj.getTypeIdOfProperty("TimeMinimumStep") == "App::PropertyFloatConstraint"
|
||||
):
|
||||
time_minimum_step = obj.TimeMinimumStep
|
||||
obj.setPropertyStatus("TimeMinimumStep", "-LockDynamic")
|
||||
obj.removeProperty("TimeMinimumStep")
|
||||
|
||||
if not hasattr(obj, "TimeMinimumStep"):
|
||||
obj.addProperty(
|
||||
"App::PropertyFloatConstraint",
|
||||
"App::PropertyTime",
|
||||
"TimeMinimumStep",
|
||||
"Fem",
|
||||
"Minimum time step",
|
||||
locked=True,
|
||||
)
|
||||
obj.TimeMinimumStep = 0.00001
|
||||
obj.TimeMinimumStep = time_minimum_step
|
||||
|
||||
time_maximum_step = 1.0
|
||||
if (
|
||||
hasattr(obj, "TimeMaximumStep")
|
||||
and obj.getTypeIdOfProperty("TimeMaximumStep") == "App::PropertyFloatConstraint"
|
||||
):
|
||||
time_maximum_step = obj.TimeMaximumStep
|
||||
obj.setPropertyStatus("TimeMaximumStep", "-LockDynamic")
|
||||
obj.removeProperty("TimeMaximumStep")
|
||||
|
||||
if not hasattr(obj, "TimeMaximumStep"):
|
||||
obj.addProperty(
|
||||
"App::PropertyFloatConstraint",
|
||||
"App::PropertyTime",
|
||||
"TimeMaximumStep",
|
||||
"Fem",
|
||||
"Maximum time step",
|
||||
locked=True,
|
||||
)
|
||||
obj.TimeMaximumStep = 1.0
|
||||
obj.TimeMaximumStep = time_maximum_step
|
||||
|
||||
if not hasattr(obj, "ThermoMechSteadyState"):
|
||||
obj.addProperty(
|
||||
|
||||
@@ -128,10 +128,10 @@ def write_step_equation(f, ccxwriter):
|
||||
or ccxwriter.solver_obj.IterationsUserDefinedTimeStepLength is True
|
||||
):
|
||||
analysis_parameter = "{},{},{},{}".format(
|
||||
ccxwriter.solver_obj.TimeInitialStep,
|
||||
ccxwriter.solver_obj.TimeEnd,
|
||||
ccxwriter.solver_obj.TimeMinimumStep,
|
||||
ccxwriter.solver_obj.TimeMaximumStep,
|
||||
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 == "frequency":
|
||||
if (
|
||||
@@ -142,16 +142,16 @@ def write_step_equation(f, ccxwriter):
|
||||
else:
|
||||
analysis_parameter = "{},{},{}\n".format(
|
||||
ccxwriter.solver_obj.EigenmodesCount,
|
||||
ccxwriter.solver_obj.EigenmodeLowLimit,
|
||||
ccxwriter.solver_obj.EigenmodeHighLimit,
|
||||
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,
|
||||
ccxwriter.solver_obj.TimeEnd,
|
||||
ccxwriter.solver_obj.TimeMinimumStep,
|
||||
ccxwriter.solver_obj.TimeMaximumStep,
|
||||
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(
|
||||
|
||||
Reference in New Issue
Block a user