FEM: examples and unit tests calculix solver, add ccx cantilever with quad8 elements

This commit is contained in:
Bernd Hahnebach
2021-07-29 07:58:18 +02:00
parent 1ea0d9a9e0
commit d6568c8303
6 changed files with 309 additions and 0 deletions

View File

@@ -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

View File

@@ -0,0 +1,99 @@
# ***************************************************************************
# * Copyright (c) 2021 Bernd Hahnebach <bernd@bimstatik.org> *
# * *
# * 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

View File

@@ -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

View File

@@ -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

View File

@@ -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
**

View File

@@ -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'