diff --git a/src/Mod/Fem/CMakeLists.txt b/src/Mod/Fem/CMakeLists.txt index 83c9cd5511..70f41b4bc0 100755 --- a/src/Mod/Fem/CMakeLists.txt +++ b/src/Mod/Fem/CMakeLists.txt @@ -53,6 +53,7 @@ SET(FemExamples_SRCS femexamples/ccx_cantilever_base_solid.py femexamples/ccx_cantilever_ele_hexa20.py femexamples/ccx_cantilever_ele_quad4.py + femexamples/ccx_cantilever_ele_quad8.py femexamples/ccx_cantilever_ele_tetra4.py femexamples/ccx_cantilever_ele_tria3.py femexamples/ccx_cantilever_ele_tria6.py @@ -96,6 +97,7 @@ SET(FemExampleMeshes_SRCS femexamples/meshes/mesh_buckling_plate_tria6.py femexamples/meshes/mesh_canticcx_hexa20.py femexamples/meshes/mesh_canticcx_quad4.py + femexamples/meshes/mesh_canticcx_quad8.py femexamples/meshes/mesh_canticcx_seg2.py femexamples/meshes/mesh_canticcx_seg3.py femexamples/meshes/mesh_canticcx_tetra10.py @@ -303,6 +305,7 @@ SET(FemTestsCcx_SRCS femtest/data/calculix/ccx_cantilever_faceload.inp femtest/data/calculix/ccx_cantilever_ele_hexa20.inp femtest/data/calculix/ccx_cantilever_ele_quad4.inp + femtest/data/calculix/ccx_cantilever_ele_quad8.inp femtest/data/calculix/ccx_cantilever_ele_seg2.inp femtest/data/calculix/ccx_cantilever_ele_seg3.inp femtest/data/calculix/ccx_cantilever_ele_tria3.inp diff --git a/src/Mod/Fem/femexamples/ccx_cantilever_ele_quad8.py b/src/Mod/Fem/femexamples/ccx_cantilever_ele_quad8.py new file mode 100644 index 0000000000..f4231bc465 --- /dev/null +++ b/src/Mod/Fem/femexamples/ccx_cantilever_ele_quad8.py @@ -0,0 +1,99 @@ +# *************************************************************************** +# * 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 + +import Fem + +from . import manager +from .ccx_cantilever_base_face import setup_cantilever_base_face +from .manager import get_meshname +from .manager import init_doc + + +def get_information(): + return { + "name": "CCX cantilever quad8 face elements", + "meshtype": "face", + "meshelement": "Quad8", + "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_ele_quad8 import setup +setup() + + +See forum topic post: + + +CalculiX cantilever modeled with quad8 face elements + +""" + + +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()))) + + # setup CalculiX cantilever + doc = setup_cantilever_base_face(doc, solvertype) + femmesh_obj = doc.getObject(get_meshname()) + + # load the quad8 mesh + from .meshes.mesh_canticcx_quad8 import create_nodes, create_elements + new_fem_mesh = Fem.FemMesh() + control = create_nodes(new_fem_mesh) + if not control: + FreeCAD.Console.PrintError("Error on creating nodes.\n") + control = create_elements(new_fem_mesh) + if not control: + FreeCAD.Console.PrintError("Error on creating elements.\n") + + # overwrite mesh with the quad8 mesh + femmesh_obj.FemMesh = new_fem_mesh + + # set mesh obj parameter + femmesh_obj.SecondOrderLinear = False + femmesh_obj.ElementDimension = "2D" + femmesh_obj.ElementOrder = "1st" + femmesh_obj.CharacteristicLengthMax = "4000.0 mm" + femmesh_obj.CharacteristicLengthMin = "4000.0 mm" + femmesh_obj.RecombinationAlgorithm = "Blossom full-quad" + femmesh_obj.RecombineAll = True + + doc.recompute() + return doc diff --git a/src/Mod/Fem/femexamples/meshes/mesh_canticcx_quad8.py b/src/Mod/Fem/femexamples/meshes/mesh_canticcx_quad8.py new file mode 100644 index 0000000000..6b43efaa00 --- /dev/null +++ b/src/Mod/Fem/femexamples/meshes/mesh_canticcx_quad8.py @@ -0,0 +1,37 @@ +def create_nodes(femmesh): + # nodes + femmesh.addNode(0.0, 500.0, 0.0, 1) + femmesh.addNode(0.0, 500.00000000000324, 1000.0, 2) + femmesh.addNode(8000.0, 500.0, 0.0, 3) + femmesh.addNode(8000.0, 500.00000000000324, 1000.0, 4) + femmesh.addNode(0.0, 500.0000000000001, 500.0, 5) + femmesh.addNode(0.0, 500.00000000000006, 250.0, 6) + femmesh.addNode(0.0, 500.00000000000017, 750.0, 7) + femmesh.addNode(4000.0, 500.0, 0.0, 8) + femmesh.addNode(2000.0, 500.0, 0.0, 9) + femmesh.addNode(6000.0, 500.0, 0.0, 10) + femmesh.addNode(8000.0, 500.0000000000001, 500.0, 11) + femmesh.addNode(8000.0, 500.00000000000006, 250.0, 12) + femmesh.addNode(8000.0, 500.00000000000017, 750.0, 13) + femmesh.addNode(4000.0, 500.0000000000002, 1000.0, 14) + femmesh.addNode(2000.0, 500.0000000000002, 1000.0, 15) + femmesh.addNode(6000.0, 500.0000000000002, 1000.0, 16) + femmesh.addNode(4000.0, 500.0000000000001, 500.0, 17) + femmesh.addNode(2000.0, 500.0000000000001, 500.0, 18) + femmesh.addNode(4000.0, 500.00000000000017, 750.0, 19) + femmesh.addNode(2000.0, 500.00000000000017, 750.0, 20) + femmesh.addNode(6000.0, 500.0000000000001, 500.0, 21) + femmesh.addNode(6000.0, 500.00000000000017, 750.0, 22) + femmesh.addNode(4000.0, 500.00000000000006, 250.0, 23) + femmesh.addNode(6000.0, 500.00000000000006, 250.0, 24) + femmesh.addNode(2000.0, 500.00000000000006, 250.0, 25) + return True + + +def create_elements(femmesh): + # elements + femmesh.addFace([1, 5, 17, 8, 6, 18, 23, 9], 1) + femmesh.addFace([5, 2, 14, 17, 7, 15, 19, 18], 2) + femmesh.addFace([17, 14, 4, 11, 19, 16, 13, 21], 3) + femmesh.addFace([8, 17, 11, 3, 23, 21, 12, 10], 4) + return True diff --git a/src/Mod/Fem/femtest/app/test_solver_calculix.py b/src/Mod/Fem/femtest/app/test_solver_calculix.py index 7c0cd65d82..0ef7cf24d0 100644 --- a/src/Mod/Fem/femtest/app/test_solver_calculix.py +++ b/src/Mod/Fem/femtest/app/test_solver_calculix.py @@ -127,6 +127,14 @@ class TestSolverCalculix(unittest.TestCase): setup(self.document, "calculix") self.input_file_writing_test(get_namefromdef("test_")) + # ******************************************************************************************** + def test_ccx_cantilever_ele_quad8( + self + ): + from femexamples.ccx_cantilever_ele_quad8 import setup + setup(self.document, "calculix") + self.input_file_writing_test(get_namefromdef("test_")) + # ******************************************************************************************** def test_ccx_cantilever_ele_seg2( self diff --git a/src/Mod/Fem/femtest/data/calculix/ccx_cantilever_ele_quad8.inp b/src/Mod/Fem/femtest/data/calculix/ccx_cantilever_ele_quad8.inp new file mode 100644 index 0000000000..d45840a47b --- /dev/null +++ b/src/Mod/Fem/femtest/data/calculix/ccx_cantilever_ele_quad8.inp @@ -0,0 +1,156 @@ +** written by FreeCAD inp file writer for CalculiX,Abaqus meshes +** highest dimension mesh elements only. + +** Nodes +*Node, NSET=Nall +1, 0, 500, 0 +2, 0, 500, 1000 +3, 8000, 500, 0 +4, 8000, 500, 1000 +5, 0, 500, 500 +6, 0, 500, 250 +7, 0, 500, 750 +8, 4000, 500, 0 +9, 2000, 500, 0 +10, 6000, 500, 0 +11, 8000, 500, 500 +12, 8000, 500, 250 +13, 8000, 500, 750 +14, 4000, 500, 1000 +15, 2000, 500, 1000 +16, 6000, 500, 1000 +17, 4000, 500, 500 +18, 2000, 500, 500 +19, 4000, 500, 750 +20, 2000, 500, 750 +21, 6000, 500, 500 +22, 6000, 500, 750 +23, 4000, 500, 250 +24, 6000, 500, 250 +25, 2000, 500, 250 + + +** Face elements +*Element, TYPE=S8, ELSET=Efaces +1, 1, 5, 17, 8, 6, 18, 23, 9 +2, 5, 2, 14, 17, 7, 15, 19, 18 +3, 17, 14, 4, 11, 19, 16, 13, 21 +4, 8, 17, 11, 3, 23, 21, 12, 10 + +** Define element set Eall +*ELSET, ELSET=Eall +Efaces + + + +*********************************************************** +** Element sets for materials and FEM element type (solid, shell, beam, fluid) +*ELSET,ELSET=MechanicalMaterialThickness +Efaces + +*********************************************************** +** constraints fixed node sets +** ConstraintFixed +*NSET,NSET=ConstraintFixed +1, +2, +5, +6, +7, + +*********************************************************** +** Materials +** see information about units at file end +** FreeCAD material name: Calculix-Steel +** MechanicalMaterial +*MATERIAL, NAME=MechanicalMaterial +*ELASTIC +210000,0.3 + +*********************************************************** +** Sections +*SHELL SECTION, ELSET=MechanicalMaterialThickness, MATERIAL=MechanicalMaterial +1000 + +*********************************************************** +** At least one step is needed to run an CalculiX analysis of FreeCAD +*STEP +*STATIC + + +*********************************************************** +** Fixed Constraints +** ConstraintFixed +*BOUNDARY +ConstraintFixed,1 +ConstraintFixed,2 +ConstraintFixed,3 +ConstraintFixed,4 +ConstraintFixed,5 +ConstraintFixed,6 + + +*********************************************************** +** constraints force node loads +*CLOAD +** ConstraintForce +** node loads on shape: CanileverPlate:Edge3 +3,2,-1.6653345369377E-10 +3,3,-7.5000000000000E+05 +4,2,-1.6653345369377E-10 +4,3,-7.5000000000000E+05 +11,2,-3.3306690738755E-10 +11,3,-1.5000000000000E+06 +12,2,-6.6613381477509E-10 +12,3,-3.0000000000000E+06 +13,2,-6.6613381477509E-10 +13,3,-3.0000000000000E+06 + + + +*********************************************************** +** Outputs --> frd file +*NODE FILE, OUTPUT=2d +U +*EL FILE +S, E +** outputs --> dat file +** reaction forces for Constraint fixed +*NODE PRINT, NSET=ConstraintFixed, TOTALS=ONLY +RF + + +*********************************************************** +*END STEP + +*********************************************************** +** CalculiX Input file +** written by --> FreeCAD 0.20.25343 (Git) +** written on --> Thu Jul 29 13:06:02 2021 +** file name --> ccx_cantilever_ele_quad8.FCStd +** analysis name --> Analysis +** +** +*********************************************************** +** About units: +** See ccx manual, ccx does not know about any unit. +** Golden rule: The user must make sure that the numbers he provides have consistent units. +** The user is the FreeCAD calculix writer module ;-) +** +** The unit system which is used at Guido Dhondt's company: mm, N, s, K +** Since Length and Mass are connected by Force, if Length is mm the Mass is in t to get N +** The following units are used to write to inp file: +** +** Length: mm (this includes the mesh geometry) +** Mass: t +** TimeSpan: s +** Temperature: K +** +** This leads to: +** Force: N +** Pressure: N/mm^2 == MPa (Young's Modulus has unit Pressure) +** Density: t/mm^3 +** Gravity: mm/s^2 +** Thermal conductivity: t*mm/K/s^3 == as W/m/K == kW/mm/K +** Specific Heat: mm^2/s^2/K = J/kg/K == kJ/t/K +** diff --git a/src/Mod/Fem/femtest/test_commands.sh b/src/Mod/Fem/femtest/test_commands.sh index a2ab5d0d5a..2ed62a697f 100644 --- a/src/Mod/Fem/femtest/test_commands.sh +++ b/src/Mod/Fem/femtest/test_commands.sh @@ -81,6 +81,7 @@ make -j 4 && ./bin/FreeCADCmd -t femtest.app.test_solver_calculix.TestSolverCalc make -j 4 && ./bin/FreeCADCmd -t femtest.app.test_solver_calculix.TestSolverCalculix.test_ccx_cantilever_faceload make -j 4 && ./bin/FreeCADCmd -t femtest.app.test_solver_calculix.TestSolverCalculix.test_ccx_cantilever_ele_hexa20 make -j 4 && ./bin/FreeCADCmd -t femtest.app.test_solver_calculix.TestSolverCalculix.test_ccx_cantilever_ele_quad4 +make -j 4 && ./bin/FreeCADCmd -t femtest.app.test_solver_calculix.TestSolverCalculix.test_ccx_cantilever_ele_quad8 make -j 4 && ./bin/FreeCADCmd -t femtest.app.test_solver_calculix.TestSolverCalculix.test_ccx_cantilever_ele_seg2 make -j 4 && ./bin/FreeCADCmd -t femtest.app.test_solver_calculix.TestSolverCalculix.test_ccx_cantilever_ele_seg3 make -j 4 && ./bin/FreeCADCmd -t femtest.app.test_solver_calculix.TestSolverCalculix.test_ccx_cantilever_ele_tria3 @@ -328,6 +329,11 @@ unittest.TextTestRunner().run(unittest.TestLoader().loadTestsFromName( 'femtest.app.test_solver_calculix.TestSolverCalculix.test_ccx_cantilever_ele_quad4' )) +import unittest +unittest.TextTestRunner().run(unittest.TestLoader().loadTestsFromName( + 'femtest.app.test_solver_calculix.TestSolverCalculix.test_ccx_cantilever_ele_quad8' +)) + import unittest unittest.TextTestRunner().run(unittest.TestLoader().loadTestsFromName( 'femtest.app.test_solver_calculix.TestSolverCalculix.test_ccx_cantilever_ele_seg2'