[FEM] Elmer: fixes for the simulation parameters

- output equation-specific values only if this equation is used
- use Elmer's default for BDF order as default for FC too and allow to change it
- don't hardcode to Steady State. Transient must be possible too, this way add parameters to run a transient analysis
This commit is contained in:
Uwe
2022-08-06 04:32:18 +02:00
parent 550ef7ca80
commit 3818534cd6
8 changed files with 111 additions and 30 deletions

View File

@@ -53,9 +53,9 @@ class Proxy(nonlinear.Proxy, equationbase.HeatProxy):
"Heat",
""
)
obj.Bubbles = True
obj.Stabilize = False
obj.Priority = 20

View File

@@ -47,6 +47,7 @@ from femtools import femutils
if FreeCAD.GuiUp:
import FemGui
SIMULATION_TYPE = ["Scanning", "Steady State", "Transient"]
def create(doc, name="ElmerSolver"):
return femutils.createObject(
@@ -70,19 +71,60 @@ class Proxy(solverbase.Proxy):
def __init__(self, obj):
super(Proxy, self).__init__(obj)
obj.addProperty(
"App::PropertyIntegerConstraint",
"BDFOrder",
"Timestepping",
"Order of time stepping method 'BDF'"
)
# according to the Elmer manual recommended is order 2
# possible ranage is 1 - 5
obj.BDFOrder = (2, 1, 5, 1)
obj.addProperty(
"App::PropertyIntegerConstraint",
"TimestepIntervals",
"Timestepping",
"Maximum optimization rounds if 'Simulation Type'\nis either 'Scanning' or 'Transient'"
)
obj.addProperty(
"App::PropertyFloatConstraint",
"TimestepSizes",
"Timestepping",
"Time step of optimization if 'Simulation Type'\nis either 'Scanning' or 'Transient'"
)
# there is no universal default, it all depends on the analysis, however
# we have to set something and set 10 seconds in steps of 0.1s
# since the Emler manual lacks proper info, here a link to a forum thread:
# http://www.elmerfem.org/forum/viewtopic.php?p=18057&sid=73169c4ec544fd7f181f85178bbc8ffe#p18057
# -----
# Set maximum to 1e8 because on Win the max int is always 32bit (4.29e9)
# for TimestepSizes also 1e8 just to set something
obj.TimestepIntervals = (100, 1, int(1e8), 10)
obj.TimestepSizes = (0.1, 1e-8, 1e8, 0.1)
obj.addProperty(
"App::PropertyEnumeration",
"SimulationType",
"Type",
""
)
obj.SimulationType = SIMULATION_TYPE
obj.SimulationType = "Steady State"
obj.addProperty(
"App::PropertyInteger",
"SteadyStateMaxIterations",
"Steady State",
""
"Type",
"Maximal steady state iterations"
)
obj.SteadyStateMaxIterations = 1
obj.addProperty(
"App::PropertyInteger",
"SteadyStateMinIterations",
"Steady State",
""
"Type",
"Minimal steady state iterations"
)
obj.SteadyStateMinIterations = 0

View File

@@ -309,23 +309,72 @@ class Writer(object):
)
def _handleSimulation(self):
# check if we need to update the equation
self._updateSimulation(self.solver)
# output the equation parameters
# first check what equations we have
hasHeat = False
for equation in self.solver.Group:
if femutils.is_of_type(equation, "Fem::EquationElmerHeat"):
hasHeat = True
if hasHeat:
self._simulation("BDF Order", self.solver.BDFOrder)
self._simulation("Coordinate System", "Cartesian 3D")
self._simulation("Coordinate Mapping", (1, 2, 3))
# Elmer uses SI base units, but our mesh is in mm, therefore we must tell
# the solver that we have another scale
self._simulation("Coordinate Scaling", 0.001)
self._simulation("Simulation Type", "Steady state")
self._simulation("Steady State Max Iterations", 1)
self._simulation("Output Intervals", 1)
self._simulation("Timestepping Method", "BDF")
self._simulation("BDF Order", 1)
self._simulation("Simulation Type",
self.solver.SimulationType)
if self.solver.SimulationType == "Steady State":
self._simulation(
"Steady State Max Iterations", self.solver.SteadyStateMaxIterations)
self._simulation(
"Steady State Min Iterations", self.solver.SteadyStateMinIterations)
if (self.solver.SimulationType == "Scanning") \
or (self.solver.SimulationType == "Transient"):
self._simulation("Timestep Intervals", self.solver.TimestepIntervals)
self._simulation("Timestep Sizes", self.solver.TimestepSizes)
if hasHeat:
self._simulation("Timestepping Method", "BDF")
self._simulation("Use Mesh Names", True)
self._simulation(
"Steady State Max Iterations",
self.solver.SteadyStateMaxIterations)
self._simulation(
"Steady State Min Iterations",
self.solver.SteadyStateMinIterations)
def _updateSimulation(self, solver):
# updates older simulations
if not hasattr(self.solver, "BDFOrder"):
solver.addProperty(
"App::PropertyIntegerConstraint",
"BDFOrder",
"Timestepping",
"Order of time stepping method 'BDF'"
)
solver.BDFOrder = (2, 1, 5, 1)
if not hasattr(self.solver, "SimulationType"):
solver.addProperty(
"App::PropertyEnumeration",
"SimulationType",
"Type",
""
)
solver.SimulationType = ["Scanning", "Steady State", "Transient"]
solver.SimulationType = "Steady State"
if not hasattr(self.solver, "TimestepIntervals"):
solver.addProperty(
"App::PropertyIntegerConstraint",
"TimestepIntervals",
"Timestepping",
"Maximum optimization rounds if 'Simulation Type'\nis either 'Scanning' or 'Transient'"
)
solver.TimestepIntervals = (100, 1, int(1e8), 10)
if not hasattr(self.solver, "TimestepSizes"):
solver.addProperty(
"App::PropertyFloatConstraint",
"TimestepSizes",
"Timestepping",
"Time step of optimization if 'Simulation Type'\nis either 'Scanning' or 'Transient'"
)
solver.TimestepSizes = (0.1, 1e-8, 1e8, 0.1)
def _handleHeat(self):
activeIn = []

View File

@@ -24,15 +24,13 @@ Solver 1
End
Simulation
BDF Order = Integer 1
Coordinate Mapping(3) = Integer 1 2 3
Coordinate Scaling = Real 0.001
Coordinate System = String "Cartesian 3D"
Output Intervals = Integer 1
Simulation Type = String "Steady state"
Simulation Type = String "Steady State"
Steady State Max Iterations = Integer 1
Steady State Min Iterations = Integer 0
Timestepping Method = String "BDF"
Use Mesh Names = Logical True
End

View File

@@ -24,15 +24,13 @@ Solver 1
End
Simulation
BDF Order = Integer 1
Coordinate Mapping(3) = Integer 1 2 3
Coordinate Scaling = Real 0.001
Coordinate System = String "Cartesian 3D"
Output Intervals = Integer 1
Simulation Type = String "Steady state"
Simulation Type = String "Steady State"
Steady State Max Iterations = Integer 1
Steady State Min Iterations = Integer 0
Timestepping Method = String "BDF"
Use Mesh Names = Logical True
End

View File

@@ -24,15 +24,13 @@ Solver 1
End
Simulation
BDF Order = Integer 1
Coordinate Mapping(3) = Integer 1 2 3
Coordinate Scaling = Real 0.001
Coordinate System = String "Cartesian 3D"
Output Intervals = Integer 1
Simulation Type = String "Steady state"
Simulation Type = String "Steady State"
Steady State Max Iterations = Integer 1
Steady State Min Iterations = Integer 0
Timestepping Method = String "BDF"
Use Mesh Names = Logical True
End

View File

@@ -24,15 +24,13 @@ Solver 1
End
Simulation
BDF Order = Integer 1
Coordinate Mapping(3) = Integer 1 2 3
Coordinate Scaling = Real 0.001
Coordinate System = String "Cartesian 3D"
Output Intervals = Integer 1
Simulation Type = String "Steady state"
Simulation Type = String "Steady State"
Steady State Max Iterations = Integer 1
Steady State Min Iterations = Integer 0
Timestepping Method = String "BDF"
Use Mesh Names = Logical True
End

View File

@@ -24,15 +24,13 @@ Solver 1
End
Simulation
BDF Order = Integer 1
Coordinate Mapping(3) = Integer 1 2 3
Coordinate Scaling = Real 0.001
Coordinate System = String "Cartesian 3D"
Output Intervals = Integer 1
Simulation Type = String "Steady state"
Simulation Type = String "Steady State"
Steady State Max Iterations = Integer 1
Steady State Min Iterations = Integer 0
Timestepping Method = String "BDF"
Use Mesh Names = Logical True
End