FEM: solver calculix, add buckling analysis
Implementation of buckling analysis between the solver Calculix and FreeCAD
This commit is contained in:
committed by
Bernd Hahnebach
parent
09f441c93e
commit
8e25fe33dc
@@ -61,7 +61,28 @@
|
||||
<property name="bottomMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<item row="2" column="0">
|
||||
<widget class="Gui::PrefRadioButton" name="rb_thermomech_analysis">
|
||||
<property name="text">
|
||||
<string>Thermo mechanical</string>
|
||||
</property>
|
||||
</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="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_static_analysis">
|
||||
<property name="text">
|
||||
<string>Static</string>
|
||||
@@ -71,24 +92,10 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="Gui::PrefRadioButton" name="rb_frequency_analysis">
|
||||
<item row="3" column="0">
|
||||
<widget class="Gui::PrefRadioButton" name="rb_buckling_analysis">
|
||||
<property name="text">
|
||||
<string>Frequency</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="Gui::PrefRadioButton" name="rb_thermomech_analysis">
|
||||
<property name="text">
|
||||
<string>Thermo mechanical</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="Gui::PrefRadioButton" name="rb_check_mesh">
|
||||
<property name="text">
|
||||
<string>Check Mesh</string>
|
||||
<string>Buckling</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
@@ -41,7 +41,7 @@ from femtools import femutils
|
||||
if FreeCAD.GuiUp:
|
||||
import FemGui
|
||||
|
||||
ANALYSIS_TYPES = ["static", "frequency", "thermomech", "check"]
|
||||
ANALYSIS_TYPES = ["static", "frequency", "thermomech", "check", "buckling"]
|
||||
|
||||
|
||||
def create(doc, name="SolverCalculiX"):
|
||||
@@ -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",
|
||||
|
||||
@@ -880,7 +880,7 @@ class FemInputWriterCcx(writerbase.FemInputWriter):
|
||||
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
|
||||
@@ -914,7 +914,7 @@ class FemInputWriterCcx(writerbase.FemInputWriter):
|
||||
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
|
||||
@@ -963,7 +963,7 @@ class FemInputWriterCcx(writerbase.FemInputWriter):
|
||||
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
|
||||
@@ -1176,7 +1176,7 @@ class FemInputWriterCcx(writerbase.FemInputWriter):
|
||||
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
|
||||
@@ -1197,6 +1197,8 @@ class FemInputWriterCcx(writerbase.FemInputWriter):
|
||||
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":
|
||||
@@ -1228,7 +1230,7 @@ class FemInputWriterCcx(writerbase.FemInputWriter):
|
||||
# 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 = ""
|
||||
@@ -1255,6 +1257,9 @@ class FemInputWriterCcx(writerbase.FemInputWriter):
|
||||
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")
|
||||
@@ -1818,6 +1823,7 @@ class FemInputWriterCcx(writerbase.FemInputWriter):
|
||||
|
||||
# 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"]
|
||||
|
||||
@@ -114,6 +114,11 @@ class _TaskPanel:
|
||||
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()"),
|
||||
@@ -161,6 +166,8 @@ class _TaskPanel:
|
||||
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"):
|
||||
@@ -386,3 +393,7 @@ class _TaskPanel:
|
||||
|
||||
def select_check_mesh(self):
|
||||
self.select_analysis_type("check")
|
||||
|
||||
def select_buckling_analysis(self):
|
||||
self.select_analysis_type("buckling")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user