diff --git a/src/Mod/Fem/CMakeLists.txt b/src/Mod/Fem/CMakeLists.txt index b1049e25eccf..bad64aa37f4e 100755 --- a/src/Mod/Fem/CMakeLists.txt +++ b/src/Mod/Fem/CMakeLists.txt @@ -51,6 +51,9 @@ SET(FemExamples_SRCS femexamples/ccx_cantilever_base_edge.py femexamples/ccx_cantilever_base_face.py femexamples/ccx_cantilever_base_solid.py + femexamples/ccx_cantilever_beam_circle.py + femexamples/ccx_cantilever_beam_pipe.py + femexamples/ccx_cantilever_beam_rect.py femexamples/ccx_cantilever_ele_hexa20.py femexamples/ccx_cantilever_ele_quad4.py femexamples/ccx_cantilever_ele_quad8.py diff --git a/src/Mod/Fem/femexamples/ccx_cantilever_base_edge.py b/src/Mod/Fem/femexamples/ccx_cantilever_base_edge.py index f1bb01361cc9..0731a1dbba94 100644 --- a/src/Mod/Fem/femexamples/ccx_cantilever_base_edge.py +++ b/src/Mod/Fem/femexamples/ccx_cantilever_base_edge.py @@ -59,6 +59,7 @@ def setup_cantilever_base_edge(doc=None, solvertype="ccxtools"): doc.recompute() if FreeCAD.GuiUp: + load_line.ViewObject.Visibility = False geom_obj.ViewObject.Document.activeView().viewAxonometric() geom_obj.ViewObject.Document.activeView().fitAll() diff --git a/src/Mod/Fem/femexamples/ccx_cantilever_beam_circle.py b/src/Mod/Fem/femexamples/ccx_cantilever_beam_circle.py new file mode 100644 index 000000000000..f4e26bdc68c3 --- /dev/null +++ b/src/Mod/Fem/femexamples/ccx_cantilever_beam_circle.py @@ -0,0 +1,110 @@ +# *************************************************************************** +# * Copyright (c) 2021 Bernd Hahnebach * +# * * +# * This file is part of the FreeCAD CAx development system. * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * This program is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** + +import FreeCAD + +from . import manager +from .ccx_cantilever_base_edge import setup_cantilever_base_edge +from .manager import init_doc + + +def get_information(): + return { + "name": "CCX cantilever beam circle", + "meshtype": "edge", + "meshelement": "Seg3", + "constraints": ["fixed", "force"], + "solvers": ["calculix"], + "material": "solid", + "equation": "mechanical" + } + + +def get_explanation(header=""): + return header + """ + +To run the example from Python console use: +from femexamples.ccx_cantilever_beam_circle import setup +setup() + + +See forum topic post: +https://forum.freecadweb.org/viewtopic.php?f=18&t=16044 + +CalculiX cantilever: +- modeled with seg3 beam elements + +CrossSection: +- circle +- diameter 1000 mm + +max deflection: +doc = App.ActiveDocument +len = doc.CantileverLine.Shape.Length +iyy = doc.CrossSectionFace.Shape.MatrixOfInertia.A22 # Iyy +force = doc.ConstraintForce.Force +from FreeCAD import Units +ym = Units.Quantity(doc.MechanicalMaterial.Material["YoungsModulus"]).getValueAs("MPa") +w = force * len**3 / (3 * ym * iyy) +w # should print 149.0 mm + +CalculiX FEM max deflection: +- 146.7 mm +- Delta ca. 1.5 % + +""" + + +def setup(doc=None, solvertype="ccxtools"): + + # init FreeCAD document + if doc is None: + doc = init_doc() + + # explanation object + # just keep the following line and change text string in get_explanation method + manager.add_explanation_obj(doc, get_explanation(manager.get_header(get_information()))) + + diameter = 1000 + cs_wire = doc.addObject("Part::Circle", "WireOfCrossSection") + cs_wire.Radius = diameter / 2 + cs_wire.Placement = FreeCAD.Placement( + FreeCAD.Vector(0, 500, 500), + FreeCAD.Rotation(0, 90, 0), + FreeCAD.Vector(0, 0, 0), + ) + doc.recompute() + cs_face = doc.addObject("Part::Face", "CrossSectionFace") + cs_face.Sources = cs_wire + doc.recompute() + + # setup CalculiX cantilever + doc = setup_cantilever_base_edge(doc, solvertype) + beamsection_obj = doc.getObject("BeamCrossSection") + + # change cross section to a circular section + beamsection_obj.SectionType = "Circular" + beamsection_obj.CircDiameter = diameter + + doc.recompute() + return doc diff --git a/src/Mod/Fem/femexamples/ccx_cantilever_beam_pipe.py b/src/Mod/Fem/femexamples/ccx_cantilever_beam_pipe.py new file mode 100644 index 000000000000..0fb9b85e78da --- /dev/null +++ b/src/Mod/Fem/femexamples/ccx_cantilever_beam_pipe.py @@ -0,0 +1,119 @@ +# *************************************************************************** +# * Copyright (c) 2021 Bernd Hahnebach * +# * * +# * This file is part of the FreeCAD CAx development system. * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * This program is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** + +import FreeCAD + +from . import manager +from .ccx_cantilever_base_edge import setup_cantilever_base_edge +from .manager import init_doc + + +def get_information(): + return { + "name": "CCX cantilever beam pipe", + "meshtype": "edge", + "meshelement": "Seg3", + "constraints": ["fixed", "force"], + "solvers": ["calculix"], + "material": "solid", + "equation": "mechanical" + } + + +def get_explanation(header=""): + return header + """ + +To run the example from Python console use: +from femexamples.ccx_cantilever_beam_pipe import setup +setup() + + +See forum topic post: +https://forum.freecadweb.org/viewtopic.php?f=18&t=16044 + +CalculiX cantilever: +- modeled with seg3 beam elements + +CrossSection: +- pipe +- outer diameter 1000 mm +- thickness 100 mm +- inner diameter = 1000 - 2x100 = 800 +- inner radius = 1000/2 - 100 = 400 + +max deflection: +doc = App.ActiveDocument +len = doc.CantileverLine.Shape.Length +iyy = doc.CrossSectionFace.Shape.MatrixOfInertia.A22 # Iyy +force = doc.ConstraintForce.Force +from FreeCAD import Units +ym = Units.Quantity(doc.MechanicalMaterial.Material["YoungsModulus"]).getValueAs("MPa") +w = force * len**3 / (3 * ym * iyy) +w # should print 252.4 mm + +CalculiX FEM max deflection: +- edit the solver input: element type B32R instead B32R +- 249.8 mm +- Delta ca. 1.0 % + +""" + + +def setup(doc=None, solvertype="ccxtools"): + + # init FreeCAD document + if doc is None: + doc = init_doc() + + # explanation object + # just keep the following line and change text string in get_explanation method + manager.add_explanation_obj(doc, get_explanation(manager.get_header(get_information()))) + + diameter = 1000 + thickness = 100 + cs_wire_outer = doc.addObject("Part::Circle", "OuterWireOfCrossSection") + cs_wire_outer.Radius = diameter / 2 + cs_wire_outer.Placement = FreeCAD.Placement( + FreeCAD.Vector(0, 500, 500), + FreeCAD.Rotation(0, 90, 0), + FreeCAD.Vector(0, 0, 0), + ) + cs_wire_inner = doc.addObject("Part::Circle", "InnerWireOfCrossSection") + cs_wire_inner.Radius = (diameter / 2) - thickness + cs_wire_inner.Placement = cs_wire_outer.Placement + doc.recompute() + cs_face = doc.addObject("Part::Face", "CrossSectionFace") + cs_face.Sources = [cs_wire_outer, cs_wire_inner] + doc.recompute() + + # setup CalculiX cantilever + doc = setup_cantilever_base_edge(doc, solvertype) + beamsection_obj = doc.getObject("BeamCrossSection") + + # change cross section to a pipe section + beamsection_obj.SectionType = "Pipe" + beamsection_obj.PipeDiameter = diameter + beamsection_obj.PipeThickness = thickness + + doc.recompute() + return doc diff --git a/src/Mod/Fem/femexamples/ccx_cantilever_beam_rect.py b/src/Mod/Fem/femexamples/ccx_cantilever_beam_rect.py new file mode 100644 index 000000000000..6ac31dd33a9f --- /dev/null +++ b/src/Mod/Fem/femexamples/ccx_cantilever_beam_rect.py @@ -0,0 +1,111 @@ +# *************************************************************************** +# * Copyright (c) 2021 Bernd Hahnebach * +# * * +# * This file is part of the FreeCAD CAx development system. * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * This program is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** + +import FreeCAD + +from . import manager +from .ccx_cantilever_base_edge import setup_cantilever_base_edge +from .manager import init_doc + + +def get_information(): + return { + "name": "CCX cantilever beam rectangle", + "meshtype": "edge", + "meshelement": "Seg3", + "constraints": ["fixed", "force"], + "solvers": ["calculix"], + "material": "solid", + "equation": "mechanical" + } + + +def get_explanation(header=""): + return header + """ + +To run the example from Python console use: +from femexamples.ccx_cantilever_beam_rect import setup +setup() + + +See forum topic post: +https://forum.freecadweb.org/viewtopic.php?f=18&t=16044 + +CalculiX cantilever: +- modeled with seg3 beam elements + +CrossSection: +- rectangle +- width = 400 mm +- height = 1250 mm + +max deflection: +doc = App.ActiveDocument +len = doc.CantileverLine.Shape.Length +iyy = doc.CrossSectionFace.Shape.MatrixOfInertia.A22 # Iyy +force = doc.ConstraintForce.Force +from FreeCAD import Units +ym = Units.Quantity(doc.MechanicalMaterial.Material["YoungsModulus"]).getValueAs("MPa") +w = force * len**3 / (3 * ym * iyy) +w # should print 112.3 mm + +CalculiX FEM max deflection: +- 112.2 mm +- but the rotation seams 90 degree rotated (FIXME) + +""" + + +def setup(doc=None, solvertype="ccxtools"): + + # init FreeCAD document + if doc is None: + doc = init_doc() + + # explanation object + # just keep the following line and change text string in get_explanation method + manager.add_explanation_obj(doc, get_explanation(manager.get_header(get_information()))) + + width = 400 + height = 1250 + cs_face = doc.addObject("Part::Plane", "CrossSectionFace") + cs_face.Width = width + cs_face.Length = height + cs_face.Placement = FreeCAD.Placement( + FreeCAD.Vector(0, 500 - 0.5 * width, 500 + 0.5 * height), + FreeCAD.Rotation(0, 90, 0), + FreeCAD.Vector(0, 0, 0), + ) + doc.recompute() + + # setup CalculiX cantilever + doc = setup_cantilever_base_edge(doc, solvertype) + beamsection_obj = doc.getObject("BeamCrossSection") + + # change cross section to a circular section + beamsection_obj.SectionType = "Rectangular" + beamsection_obj.RectWidth = width + beamsection_obj.RectHeight = height + + doc.recompute() + return doc