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

@@ -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")