Skip to content

Commit

Permalink
FEM: solver calculix, add buckling analysis
Browse files Browse the repository at this point in the history
Implementation of buckling analysis between the solver Calculix and FreeCAD
  • Loading branch information
twangrt authored and berndhahnebach committed Jun 9, 2021
1 parent 09f441c commit 8e25fe3
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 17 deletions.
29 changes: 18 additions & 11 deletions src/Mod/Fem/Gui/Resources/ui/SolverCalculix.ui
Expand Up @@ -61,34 +61,41 @@
<property name="bottomMargin">
<number>9</number>
</property>
<item row="0" column="0">
<widget class="Gui::PrefRadioButton" name="rb_static_analysis">
<item row="2" column="0">
<widget class="Gui::PrefRadioButton" name="rb_thermomech_analysis">
<property name="text">
<string>Static</string>
<string>Thermo mechanical</string>
</property>
<property name="checked">
<bool>true</bool>
</widget>
</item>
<item row="2" column="2">
<widget class="Gui::PrefRadioButton" name="rb_check_mesh">
<property name="text">
<string>Check Mesh</string>
</property>
</widget>
</item>
<item row="0" column="1">
<item row="1" column="2">
<widget class="Gui::PrefRadioButton" name="rb_frequency_analysis">
<property name="text">
<string>Frequency</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="Gui::PrefRadioButton" name="rb_thermomech_analysis">
<widget class="Gui::PrefRadioButton" name="rb_static_analysis">
<property name="text">
<string>Thermo mechanical</string>
<string>Static</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="Gui::PrefRadioButton" name="rb_check_mesh">
<item row="3" column="0">
<widget class="Gui::PrefRadioButton" name="rb_buckling_analysis">
<property name="text">
<string>Check Mesh</string>
<string>Buckling</string>
</property>
</widget>
</item>
Expand Down
11 changes: 10 additions & 1 deletion src/Mod/Fem/femsolver/calculix/solver.py
Expand Up @@ -41,7 +41,7 @@
if FreeCAD.GuiUp:
import FemGui

ANALYSIS_TYPES = ["static", "frequency", "thermomech", "check"]
ANALYSIS_TYPES = ["static", "frequency", "thermomech", "check", "buckling"]


def create(doc, name="SolverCalculiX"):
Expand Down Expand Up @@ -165,6 +165,15 @@ def add_attributes(obj, ccx_prefs):
niter = ccx_prefs.GetInt("AnalysisMaxIterations", 200)
obj.IterationsThermoMechMaximum = niter

obj.addProperty(
"App::PropertyIntegerConstraint",
"BucklingFactors",
"Fem",
"Calculates the lowest buckling modes to the corresponding buckling factors"
)
bckl = ccx_prefs.GetInt("BucklingFactors", 1)
obj.BucklingFactors = bckl

obj.addProperty(
"App::PropertyFloatConstraint",
"TimeInitialStep",
Expand Down
16 changes: 11 additions & 5 deletions src/Mod/Fem/femsolver/calculix/writer.py
Expand Up @@ -880,7 +880,7 @@ def write_constraints_initialtemperature(self, f):
def write_constraints_selfweight(self, f):
if not self.selfweight_objects:
return
if not (self.analysis_type == "static" or self.analysis_type == "thermomech"):
if not (self.analysis_type == "static" or self.analysis_type == "thermomech" or self.analysis_type == "buckling"):
return

# write constraint to file
Expand Down Expand Up @@ -914,7 +914,7 @@ def write_constraints_selfweight(self, f):
def write_constraints_force(self, f, inpfile_split=None):
if not self.force_objects:
return
if not (self.analysis_type == "static" or self.analysis_type == "thermomech"):
if not (self.analysis_type == "static" or self.analysis_type == "thermomech" or self.analysis_type == "buckling"):
return

# check shape type of reference shape and get node loads
Expand Down Expand Up @@ -963,7 +963,7 @@ def write_nodeloads_constraints_force(self, f):
def write_constraints_pressure(self, f, inpfile_split=None):
if not self.pressure_objects:
return
if not (self.analysis_type == "static" or self.analysis_type == "thermomech"):
if not (self.analysis_type == "static" or self.analysis_type == "thermomech" or self.analysis_type == "buckling"):
return

# get the faces and face numbers
Expand Down Expand Up @@ -1176,7 +1176,7 @@ def write_step_begin(self, f):
if self.solver_obj.IterationsThermoMechMaximum:
if self.analysis_type == "thermomech":
step += ", INC=" + str(self.solver_obj.IterationsThermoMechMaximum)
elif self.analysis_type == "static" or self.analysis_type == "frequency":
elif self.analysis_type == "static" or self.analysis_type == "frequency" or self.analysis_type == "buckling":
# parameter is for thermomechanical analysis only, see ccx manual *STEP
pass
# write step line
Expand All @@ -1197,6 +1197,8 @@ def write_step_begin(self, f):
analysis_type = "*COUPLED TEMPERATURE-DISPLACEMENT"
elif self.analysis_type == "check":
analysis_type = "*NO ANALYSIS"
elif self.analysis_type == "buckling":
analysis_type = "*BUCKLE"
# analysis line --> solver type
# https://forum.freecadweb.org/viewtopic.php?f=18&t=43178
if self.solver_obj.MatrixSolverType == "default":
Expand Down Expand Up @@ -1228,7 +1230,7 @@ def write_step_begin(self, f):
# Set time to 1 and ignore user inputs for steady state
self.solver_obj.TimeInitialStep = 1.0
self.solver_obj.TimeEnd = 1.0
elif self.analysis_type == "static" or self.analysis_type == "frequency":
elif self.analysis_type == "static" or self.analysis_type == "frequency" or self.analysis_type == "buckling":
pass # not supported for static and frequency!
# ANALYSIS parameter line
analysis_parameter = ""
Expand All @@ -1255,6 +1257,9 @@ def write_step_begin(self, f):
self.solver_obj.TimeInitialStep,
self.solver_obj.TimeEnd
)
elif self.analysis_type == "buckling":
analysis_parameter = "{}\n".format(self.solver_obj.BucklingFactors)

# write analysis type line, analysis parameter line
f.write(analysis_type + "\n")
f.write(analysis_parameter + "\n")
Expand Down Expand Up @@ -1818,6 +1823,7 @@ def write_materials(self, f):

# nonlinear material properties
if self.solver_obj.MaterialNonlinearity == "nonlinear":

for nlfemobj in self.material_nonlinear_objects:
# femobj --> dict, FreeCAD document object is nlfemobj["Object"]
nl_mat_obj = nlfemobj["Object"]
Expand Down
11 changes: 11 additions & 0 deletions src/Mod/Fem/femtaskpanels/task_solver_ccxtools.py
Expand Up @@ -114,6 +114,11 @@ def __init__(self, solver_object):
QtCore.SIGNAL("clicked()"),
self.select_check_mesh
)
QtCore.QObject.connect(
self.form.rb_buckling_analysis,
QtCore.SIGNAL("clicked()"),
self.select_buckling_analysis
)
QtCore.QObject.connect(
self.Calculix,
QtCore.SIGNAL("started()"),
Expand Down Expand Up @@ -161,6 +166,8 @@ def update(self):
self.form.rb_thermomech_analysis.setChecked(True)
elif self.fea.solver.AnalysisType == "check":
self.form.rb_check_mesh.setChecked(True)
elif self.fea.solver.AnalysisType == "buckling":
self.form.rb_buckling_analysis.setChecked(True)
return

def femConsoleMessage(self, message="", color="#000000"):
Expand Down Expand Up @@ -386,3 +393,7 @@ def select_thermomech_analysis(self):

def select_check_mesh(self):
self.select_analysis_type("check")

def select_buckling_analysis(self):
self.select_analysis_type("buckling")

0 comments on commit 8e25fe3

Please sign in to comment.