here we recently had a short discussion about the general beam section (CalculiX features) that allows users to define beam elements with arbitrary cross-sections: https://forum.freecadweb.org/viewtopic. ... 4&start=20
In my opinion, it could be very useful so I'd like to continue this topic and move on to the potential implementation.
Let's start from what is required by CalculiX (apart from standard definitions) to use this feature (source: http://www.dhondt.de/ccx_2.17.pdf):
Code: Select all
*ELEMENT, TYPE=U1, ...
...
*USER ELEMENT, TYPE=U1, NODES=2, INTEGRATION POINTS=2, MAXDOF=6
*BEAM SECTION,SECTION=GENERAL, ...
A, I_11, I_12, I_22, k
uv_x, uv_y, uv_z
Now let's get to my implementation attempt. Please keep in mind that it's my first time trying to add code to FreeCAD so I may make some mistakes.
From what I've found, at least 3 files have to be edited to add new section type. Below are the links to those files in github repository together with my suggestion of what to add to them:
write_femelement_geometry.py
https://github.com/FreeCAD/FreeCAD/blob ... eometry.py
Code: Select all
if beamsec_obj.SectionType == "General":
area = beamsec_obj.GenArea.getValueAs("mm^2").Value
in11 = beamsec_obj.GenIn11.getValueAs("mm^4").Value
in12 = 0
in22 = beamsec_obj.GenIn22.getValueAs("mm^4").Value
k = beamsec_obj.GenK.getValueAs("mm^4").Value
section_type = ", SECTION=GEN"
section_geo = "{:.13G},{:.13G},{:.13G},{:.13G},{:.13G}\n".format(area, in11, 0 , in22, k)
section_def = "*BEAM SECTION, {}{}{}\n".format(
elsetdef,
material,
section_type
)
element_geometry1D.py
https://github.com/FreeCAD/FreeCAD/blob ... metry1D.py
Code: Select all
Type = "Fem::ElementGeometry1D"
known_beam_types = ["Rectangular", "Circular", "Pipe", "General"]
def __init__(self, obj):
super(ElementGeometry1D, self).__init__(obj)
obj.addProperty(
"App::PropertyLength",
"GenArea",
"GenBeamSection",
"set area of the general beam elements"
)
obj.addProperty(
"App::PropertyLength",
"GenIn11",
"GenBeamSection",
"set I_11 of the general beam elements"
)
obj.addProperty(
"App::PropertyLength",
"GenIn22",
"GenBeamSection",
"set I_22 of the general beam elements"
)
obj.addProperty(
"App::PropertyLength",
"GenK",
"GenBeamSection",
"set Timoshenko shear coefficient of the general beam elements"
)
https://github.com/FreeCAD/FreeCAD/blob ... metry1D.py
Code: Select all
QtCore.QObject.connect(
self.parameterWidget.if_gen_area,
QtCore.SIGNAL("valueChanged(Base::Quantity)"),
self.gen_area_changed
)
QtCore.QObject.connect(
self.parameterWidget.if_gen_in11,
QtCore.SIGNAL("valueChanged(Base::Quantity)"),
self.gen_in11_changed
)
QtCore.QObject.connect(
self.parameterWidget.if_gen_in22,
QtCore.SIGNAL("valueChanged(Base::Quantity)"),
self.gen_in22_changed
)
QtCore.QObject.connect(
self.parameterWidget.if_gen_k,
QtCore.SIGNAL("valueChanged(Base::Quantity)"),
self.gen_k_changed
)
...
...
...
def get_beamsection_props(self):
self.GenArea = self.obj.GenArea
self.GenIn11 = self.obj.GenIn11
self.GenIn22 = self.obj.GenIn22
self.GenK = self.obj.GenK
def set_beamsection_props(self):
self.GenArea = self.obj.GenArea
self.GenIn11 = self.obj.GenIn11
self.GenIn22 = self.obj.GenIn22
self.GenK = self.obj.GenK
def updateParameterWidget(self):
"fills the widgets"
index_crosssectiontype = self.parameterWidget.cb_crosssectiontype.findText(
self.SectionType
)
self.parameterWidget.cb_crosssectiontype.setCurrentIndex(index_crosssectiontype)
self.parameterWidget.if_gen_area.setText(self.GenArea.UserString)
self.parameterWidget.if_gen_in11.setText(self.GenIn11.UserString)
self.parameterWidget.if_gen_in22.setText(self.GenIn22.UserString)
self.parameterWidget.if_gen_k.setText(self.GenK.UserString)
...
...
...
def gen_area_changed(self, base_quantity_value):
self.GenArea = base_quantity_value
def gen_in11_changed(self, base_quantity_value):
self.GenIn11 = base_quantity_value
def gen_in22_changed(self, base_quantity_value):
self.GenIn22 = base_quantity_value
def gen_k_changed(self, base_quantity_value):
self.GenK = base_quantity_value
- I wasn't sure what to specify in
Code: Select all
k = beamsec_obj.GenK.getValueAs("mm^4").Value
- I_12 must be always zero so I didn't include it in the input parameters, but I don't know if I specified its value properly in the first file
- offset1 and offset2 parameters also have to be zero for this section but I didn't notice them anywhere in FEM module so it's probably not a problem at this point
- two additional changes to the input file have to be made when general section is used (mentioned above: *USER ELEMENT and *ELEMENT, TYPE=U1) - the first one requires adding a whole new keyword after *ELEMENT while the second one requires changing existing parameter from B31 or B32 to U1. Unfortunately, I don't know how to do it yet.
- I hope those are all the necessary files and parts of code that have to be edited to introduce this new functionality
- I'm not sure if the second line of *BEAM SECTION keyword (orientation) is always added in FreeCAD (I hope it is). As I've mentioned, in this case it's required.
- CalculiX also offers box sections, maybe we could add them too.
I will be very grateful for your comments and help with that.