FEM: code formating, max line length < 100, fem test modules
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -35,7 +35,10 @@ from os.path import join
|
||||
class TestFemCommon(unittest.TestCase):
|
||||
fcc_print('import TestFemCommon')
|
||||
|
||||
def setUp(self):
|
||||
# ********************************************************************************************
|
||||
def setUp(
|
||||
self
|
||||
):
|
||||
# init, is executed before every test
|
||||
self.doc_name = "TestsFemCommon"
|
||||
try:
|
||||
@@ -46,23 +49,34 @@ class TestFemCommon(unittest.TestCase):
|
||||
FreeCAD.setActiveDocument(self.doc_name)
|
||||
self.active_doc = FreeCAD.ActiveDocument
|
||||
|
||||
def test_adding_refshaps(self):
|
||||
# ********************************************************************************************
|
||||
def test_adding_refshaps(
|
||||
self
|
||||
):
|
||||
doc = self.active_doc
|
||||
slab = doc.addObject("Part::Plane", "Face")
|
||||
slab.Length = 500.00
|
||||
slab.Width = 500.00
|
||||
cf = ObjectsFem.makeConstraintFixed(doc)
|
||||
ref_eles = []
|
||||
# FreeCAD list property seam not to support append, thus we need some workaround, which is on many elements even much faster
|
||||
# FreeCAD list property seam not to support append,
|
||||
# thus we need some workaround
|
||||
# which is on many elements even much faster
|
||||
for i, face in enumerate(slab.Shape.Edges):
|
||||
ref_eles.append("Edge%d" % (i + 1))
|
||||
cf.References = [(slab, ref_eles)]
|
||||
doc.recompute()
|
||||
expected_reflist = [(slab, ('Edge1', 'Edge2', 'Edge3', 'Edge4'))]
|
||||
assert_err_message = 'Adding reference shapes did not result in expected list ' + str(cf.References) + ' != ' + str(expected_reflist)
|
||||
assert_err_message = (
|
||||
'Adding reference shapes did not result in expected list {} != {}'
|
||||
.format(cf.References, expected_reflist)
|
||||
)
|
||||
self.assertEqual(cf.References, expected_reflist, assert_err_message)
|
||||
|
||||
def test_pyimport_all_FEM_modules(self):
|
||||
# ********************************************************************************************
|
||||
def test_pyimport_all_FEM_modules(
|
||||
self
|
||||
):
|
||||
# we're going to try to import all python modules from FreeCAD Fem
|
||||
pymodules = []
|
||||
|
||||
@@ -76,7 +90,8 @@ class TestFemCommon(unittest.TestCase):
|
||||
pymodules += testtools.collect_python_modules('femtest')
|
||||
pymodules += testtools.collect_python_modules('femtools')
|
||||
pymodules += testtools.collect_python_modules('femsolver')
|
||||
# TODO test with join on windows, the use of os.path.join in following code seams to make problems on windws os
|
||||
# TODO test with join on windows, the use of os.path.join
|
||||
# in following code seams to make problems on windws os
|
||||
pymodules += testtools.collect_python_modules('femsolver/elmer')
|
||||
pymodules += testtools.collect_python_modules('femsolver/elmer/equations')
|
||||
pymodules += testtools.collect_python_modules('femsolver/z88')
|
||||
@@ -94,10 +109,14 @@ class TestFemCommon(unittest.TestCase):
|
||||
except:
|
||||
im = False
|
||||
if not im:
|
||||
__import__('{0}'.format(mod)) # to get an error message what was going wrong
|
||||
# to get an error message what was going wrong
|
||||
__import__('{0}'.format(mod))
|
||||
self.assertTrue(im, 'Problem importing {0}'.format(mod))
|
||||
|
||||
def tearDown(self):
|
||||
# ********************************************************************************************
|
||||
def tearDown(
|
||||
self
|
||||
):
|
||||
# clearance, is executed after every test
|
||||
FreeCAD.closeDocument(self.doc_name)
|
||||
pass
|
||||
|
||||
@@ -33,7 +33,10 @@ from os.path import join
|
||||
class TestMaterialUnits(unittest.TestCase):
|
||||
fcc_print('import TestMaterialUnits')
|
||||
|
||||
def setUp(self):
|
||||
# ********************************************************************************************
|
||||
def setUp(
|
||||
self
|
||||
):
|
||||
# init, is executed before every test
|
||||
self.doc_name = "TestMaterialUnits"
|
||||
try:
|
||||
@@ -44,7 +47,10 @@ class TestMaterialUnits(unittest.TestCase):
|
||||
FreeCAD.setActiveDocument(self.doc_name)
|
||||
self.active_doc = FreeCAD.ActiveDocument
|
||||
|
||||
def test_known_quantity_units(self):
|
||||
# ********************************************************************************************
|
||||
def test_known_quantity_units(
|
||||
self
|
||||
):
|
||||
from materialtools.cardutils import get_known_material_quantity_parameter as knownquant
|
||||
known_quantity_parameter = knownquant()
|
||||
from materialtools.cardutils import check_parm_unit as checkparamunit
|
||||
@@ -52,17 +58,27 @@ class TestMaterialUnits(unittest.TestCase):
|
||||
fcc_print('{}'.format(param))
|
||||
self.assertTrue(
|
||||
checkparamunit(param),
|
||||
'Unit of quantity material parameter {} is not known by FreeCAD unit system.'
|
||||
'Unit of quantity material parameter {} '
|
||||
'is not known by FreeCAD unit system.'
|
||||
.format(param)
|
||||
)
|
||||
|
||||
def test_material_card_quantities(self):
|
||||
# test the value and unit of known quantity parameter from solid build in material cards
|
||||
# ********************************************************************************************
|
||||
def test_material_card_quantities(
|
||||
self
|
||||
):
|
||||
# test the value and unit of known quantity parameter
|
||||
# from solid build in material cards
|
||||
# keep in mind only if FreeCAD is installed all materials are copied
|
||||
# TODO Fluid materials (are they installed?)
|
||||
|
||||
# get build in materials
|
||||
builtin_solid_mat_dir = join(FreeCAD.getResourceDir(), "Mod", "Material", "StandardMaterial")
|
||||
builtin_solid_mat_dir = join(
|
||||
FreeCAD.getResourceDir(),
|
||||
"Mod",
|
||||
"Material",
|
||||
"StandardMaterial"
|
||||
)
|
||||
fcc_print('{}'.format(builtin_solid_mat_dir))
|
||||
from materialtools.cardutils import add_cards_from_a_dir as addmats
|
||||
materials, cards, icons = addmats({}, {}, {}, builtin_solid_mat_dir, '')
|
||||
@@ -84,7 +100,10 @@ class TestMaterialUnits(unittest.TestCase):
|
||||
.format(value, param)
|
||||
)
|
||||
|
||||
def tearDown(self):
|
||||
# ********************************************************************************************
|
||||
def tearDown(
|
||||
self
|
||||
):
|
||||
# clearance, is executed after every test
|
||||
FreeCAD.closeDocument(self.doc_name)
|
||||
pass
|
||||
|
||||
@@ -35,7 +35,10 @@ from os.path import join
|
||||
class TestMeshCommon(unittest.TestCase):
|
||||
fcc_print('import TestMeshCommon')
|
||||
|
||||
def setUp(self):
|
||||
# ********************************************************************************************
|
||||
def setUp(
|
||||
self
|
||||
):
|
||||
# init, is executed before every test
|
||||
self.doc_name = "TestMeshCommon"
|
||||
try:
|
||||
@@ -46,7 +49,10 @@ class TestMeshCommon(unittest.TestCase):
|
||||
FreeCAD.setActiveDocument(self.doc_name)
|
||||
self.active_doc = FreeCAD.ActiveDocument
|
||||
|
||||
def test_mesh_seg2_python(self):
|
||||
# ********************************************************************************************
|
||||
def test_mesh_seg2_python(
|
||||
self
|
||||
):
|
||||
seg2 = Fem.FemMesh()
|
||||
seg2.addNode(0, 0, 0, 1)
|
||||
seg2.addNode(2, 0, 0, 2)
|
||||
@@ -54,14 +60,40 @@ class TestMeshCommon(unittest.TestCase):
|
||||
seg2.addEdge([1, 2])
|
||||
seg2.addEdge([2, 3], 2)
|
||||
|
||||
node_data = [seg2.NodeCount, seg2.Nodes]
|
||||
edge_data = [seg2.EdgeCount, seg2.Edges[0], seg2.getElementNodes(seg2.Edges[0]), seg2.Edges[1], seg2.getElementNodes(seg2.Edges[1])]
|
||||
expected_nodes = [3, {1: FreeCAD.Vector(0.0, 0.0, 0.0), 2: FreeCAD.Vector(2.0, 0.0, 0.0), 3: FreeCAD.Vector(4.0, 0.0, 0.0)}]
|
||||
node_data = [
|
||||
seg2.NodeCount,
|
||||
seg2.Nodes
|
||||
]
|
||||
edge_data = [
|
||||
seg2.EdgeCount,
|
||||
seg2.Edges[0],
|
||||
seg2.getElementNodes(seg2.Edges[0]),
|
||||
seg2.Edges[1],
|
||||
seg2.getElementNodes(seg2.Edges[1])
|
||||
]
|
||||
expected_nodes = [
|
||||
3,
|
||||
{
|
||||
1: FreeCAD.Vector(0.0, 0.0, 0.0),
|
||||
2: FreeCAD.Vector(2.0, 0.0, 0.0),
|
||||
3: FreeCAD.Vector(4.0, 0.0, 0.0)
|
||||
}
|
||||
]
|
||||
expected_edges = [2, 1, (1, 2), 2, (2, 3)]
|
||||
self.assertEqual(node_data, expected_nodes, "Nodes of Python created seg2 element are unexpected")
|
||||
self.assertEqual(edge_data, expected_edges, "Edges of Python created seg2 element are unexpected")
|
||||
self.assertEqual(
|
||||
node_data,
|
||||
expected_nodes,
|
||||
"Nodes of Python created seg2 element are unexpected"
|
||||
)
|
||||
self.assertEqual(
|
||||
edge_data, expected_edges,
|
||||
"Edges of Python created seg2 element are unexpected"
|
||||
)
|
||||
|
||||
def test_mesh_seg3_python(self):
|
||||
# ********************************************************************************************
|
||||
def test_mesh_seg3_python(
|
||||
self
|
||||
):
|
||||
seg3 = Fem.FemMesh()
|
||||
seg3.addNode(0, 0, 0, 1)
|
||||
seg3.addNode(1, 0, 0, 2)
|
||||
@@ -72,7 +104,13 @@ class TestMeshCommon(unittest.TestCase):
|
||||
seg3.addEdge([3, 5, 4], 2)
|
||||
|
||||
node_data = [seg3.NodeCount, seg3.Nodes]
|
||||
edge_data = [seg3.EdgeCount, seg3.Edges[0], seg3.getElementNodes(seg3.Edges[0]), seg3.Edges[1], seg3.getElementNodes(seg3.Edges[1])]
|
||||
edge_data = [
|
||||
seg3.EdgeCount,
|
||||
seg3.Edges[0],
|
||||
seg3.getElementNodes(seg3.Edges[0]),
|
||||
seg3.Edges[1],
|
||||
seg3.getElementNodes(seg3.Edges[1])
|
||||
]
|
||||
expected_nodes = [
|
||||
5, {
|
||||
1: FreeCAD.Vector(0.0, 0.0, 0.0),
|
||||
@@ -83,10 +121,21 @@ class TestMeshCommon(unittest.TestCase):
|
||||
}
|
||||
]
|
||||
expected_edges = [2, 1, (1, 3, 2), 2, (3, 5, 4)]
|
||||
self.assertEqual(node_data, expected_nodes, "Nodes of Python created seg3 element are unexpected")
|
||||
self.assertEqual(edge_data, expected_edges, "Edges of Python created seg3 element are unexpected")
|
||||
self.assertEqual(
|
||||
node_data,
|
||||
expected_nodes,
|
||||
"Nodes of Python created seg3 element are unexpected"
|
||||
)
|
||||
self.assertEqual(
|
||||
edge_data,
|
||||
expected_edges,
|
||||
"Edges of Python created seg3 element are unexpected"
|
||||
)
|
||||
|
||||
def test_unv_save_load(self):
|
||||
# ********************************************************************************************
|
||||
def test_unv_save_load(
|
||||
self
|
||||
):
|
||||
tetra10 = Fem.FemMesh()
|
||||
tetra10.addNode(6, 12, 18, 1)
|
||||
tetra10.addNode(0, 0, 18, 2)
|
||||
@@ -106,16 +155,28 @@ class TestMeshCommon(unittest.TestCase):
|
||||
tetra10.write(unv_file)
|
||||
newmesh = Fem.read(unv_file)
|
||||
expected = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
|
||||
self.assertEqual(newmesh.getElementNodes(1), expected, "Nodes order of quadratic volume element is unexpected")
|
||||
self.assertEqual(
|
||||
newmesh.getElementNodes(1),
|
||||
expected,
|
||||
"Nodes order of quadratic volume element is unexpected"
|
||||
)
|
||||
|
||||
def test_writeAbaqus_precision(self):
|
||||
# ********************************************************************************************
|
||||
def test_writeAbaqus_precision(
|
||||
self
|
||||
):
|
||||
# https://forum.freecadweb.org/viewtopic.php?f=18&t=22759#p176669
|
||||
# ccx reads only F20.0 (i. e. Fortran floating point field 20 chars wide)
|
||||
# thus precision is set to 13 in writeAbaqus
|
||||
seg2 = Fem.FemMesh()
|
||||
seg2.addNode(0, 0, 0, 1)
|
||||
# 1234567890123456789012 1234567890123456789012 123456789012345678901234567
|
||||
seg2.addNode(-5000000000000000000.1, -1.123456789123456e-14, -0.1234567890123456789e-101, 2)
|
||||
seg2.addNode(
|
||||
# 3456789012345678901234567
|
||||
-5000000000000000000.1,
|
||||
-1.123456789123456e-14,
|
||||
-0.1234567890123456789e-101,
|
||||
2
|
||||
)
|
||||
seg2.addEdge([1, 2])
|
||||
|
||||
inp_file = testtools.get_fem_test_tmp_dir() + '/seg2_mesh.inp'
|
||||
@@ -133,18 +194,30 @@ class TestMeshCommon(unittest.TestCase):
|
||||
expected_win = '2, -5e+018, -1.123456789123e-014, -1.234567890123e-102'
|
||||
expected_lin = '2, -5e+18, -1.123456789123e-14, -1.234567890123e-102'
|
||||
expected = [expected_lin, expected_win]
|
||||
self.assertTrue(True if read_node_line in expected else False,
|
||||
"Problem in test_writeAbaqus_precision, \n{0}\n{1}".format(read_node_line, expected))
|
||||
self.assertTrue(
|
||||
True if read_node_line in expected else False,
|
||||
"Problem in test_writeAbaqus_precision, \n{0}\n{1}".format(
|
||||
read_node_line,
|
||||
expected
|
||||
)
|
||||
)
|
||||
|
||||
def tearDown(self):
|
||||
# ********************************************************************************************
|
||||
def tearDown(
|
||||
self
|
||||
):
|
||||
FreeCAD.closeDocument(self.doc_name)
|
||||
pass
|
||||
|
||||
|
||||
# ************************************************************************************************
|
||||
class TestMeshEleTetra10(unittest.TestCase):
|
||||
fcc_print('import TestMeshEleTetra10')
|
||||
|
||||
def setUp(self):
|
||||
# ********************************************************************************************
|
||||
def setUp(
|
||||
self
|
||||
):
|
||||
self.doc_name = "TestMeshEleTetra10"
|
||||
try:
|
||||
FreeCAD.setActiveDocument(self.doc_name)
|
||||
@@ -155,8 +228,15 @@ class TestMeshEleTetra10(unittest.TestCase):
|
||||
self.active_doc = FreeCAD.ActiveDocument
|
||||
|
||||
self.elem = 'tetra10'
|
||||
self.base_testfile = join(testtools.get_fem_test_home_dir(), 'mesh', (self.elem + '_mesh.'))
|
||||
self.base_outfile = join(testtools.get_fem_test_tmp_dir(), (self.elem + '_mesh.'))
|
||||
self.base_testfile = join(
|
||||
testtools.get_fem_test_home_dir(),
|
||||
'mesh',
|
||||
(self.elem + '_mesh.')
|
||||
)
|
||||
self.base_outfile = join(
|
||||
testtools.get_fem_test_tmp_dir(),
|
||||
(self.elem + '_mesh.')
|
||||
)
|
||||
# 10 node tetrahedron --> tetra10
|
||||
femmesh = Fem.FemMesh()
|
||||
femmesh.addNode(6, 12, 18, 1)
|
||||
@@ -198,7 +278,10 @@ class TestMeshEleTetra10(unittest.TestCase):
|
||||
fcc_print('\n')
|
||||
'''
|
||||
|
||||
def test_tetra10_create(self):
|
||||
# ********************************************************************************************
|
||||
def test_tetra10_create(
|
||||
self
|
||||
):
|
||||
# tetra10 element: creating by Python
|
||||
node_data = {
|
||||
'count': self.femmesh.NodeCount,
|
||||
@@ -207,10 +290,21 @@ class TestMeshEleTetra10(unittest.TestCase):
|
||||
elem_data = {
|
||||
'volcount': self.femmesh.VolumeCount,
|
||||
'tetcount': self.femmesh.TetraCount,
|
||||
'volumes': [self.femmesh.Volumes[0], self.femmesh.getElementNodes(self.femmesh.Volumes[0])]
|
||||
'volumes': [
|
||||
self.femmesh.Volumes[0],
|
||||
self.femmesh.getElementNodes(self.femmesh.Volumes[0])
|
||||
]
|
||||
}
|
||||
self.assertEqual(node_data, self.expected_nodes, "Nodes of Python created " + self.elem + "mesh element are unexpected")
|
||||
self.assertEqual(elem_data, self.expected_elem, "Elements of Python created " + self.elem + "mesh element are unexpected")
|
||||
self.assertEqual(
|
||||
node_data,
|
||||
self.expected_nodes,
|
||||
"Nodes of Python created " + self.elem + "mesh element are unexpected"
|
||||
)
|
||||
self.assertEqual(
|
||||
elem_data,
|
||||
self.expected_elem,
|
||||
"Elements of Python created " + self.elem + "mesh element are unexpected"
|
||||
)
|
||||
'''
|
||||
obj = doc.addObject("Fem::FemMeshObject" , elem)
|
||||
obj.FemMesh = femmesh
|
||||
@@ -218,7 +312,10 @@ class TestMeshEleTetra10(unittest.TestCase):
|
||||
obj.ViewObject.DisplayMode = "Faces, Wireframe & Nodes"
|
||||
'''
|
||||
|
||||
def test_tetra10_inp(self):
|
||||
# ********************************************************************************************
|
||||
def test_tetra10_inp(
|
||||
self
|
||||
):
|
||||
# tetra10 element: reading from and writing to inp mesh file format
|
||||
filetyp = 'inp'
|
||||
outfile = self.base_outfile + filetyp
|
||||
@@ -229,41 +326,79 @@ class TestMeshEleTetra10(unittest.TestCase):
|
||||
femmesh_outfile = Fem.read(outfile) # read the mesh from written mesh
|
||||
femmesh_testfile = Fem.read(testfile) # read the mesh from test mesh
|
||||
# reading the test mesh
|
||||
# fcc_print([femmesh_testfile.Volumes[0], femmesh_testfile.getElementNodes(femmesh_outfile.Volumes[0])])
|
||||
# '''
|
||||
fcc_print([
|
||||
femmesh_testfile.Volumes[0],
|
||||
femmesh_testfile.getElementNodes(femmesh_outfile.Volumes[0])
|
||||
])
|
||||
# '''
|
||||
self.assertEqual(
|
||||
femmesh_testfile.Nodes,
|
||||
self.expected_nodes['nodes'],
|
||||
"Test reading " + self.elem + " mesh to " + filetyp + " file failed. Nodes are different.\n"
|
||||
"Test reading {} mesh to {} file failed. Nodes are different.\n".format(
|
||||
self.elem,
|
||||
filetyp
|
||||
)
|
||||
)
|
||||
self.assertEqual(
|
||||
[femmesh_testfile.Volumes[0], femmesh_testfile.getElementNodes(femmesh_outfile.Volumes[0])],
|
||||
[
|
||||
femmesh_testfile.Volumes[0],
|
||||
femmesh_testfile.getElementNodes(femmesh_outfile.Volumes[0])
|
||||
],
|
||||
self.expected_elem['volumes'],
|
||||
"Test reading " + self.elem + " mesh to " + filetyp + " file failed. Volumes are different.\n"
|
||||
"Test reading {} mesh to {} file failed. Volumes are different.\n".format(
|
||||
self.elem,
|
||||
filetyp
|
||||
)
|
||||
)
|
||||
# reading the written mesh
|
||||
self.assertEqual(
|
||||
femmesh_outfile.Nodes,
|
||||
self.expected_nodes['nodes'],
|
||||
"Test reading " + self.elem + " mesh to " + filetyp + " file failed. Nodes are different.\n"
|
||||
"Test reading {} mesh to {} file failed. Nodes are different.\n".format(
|
||||
self.elem,
|
||||
filetyp
|
||||
)
|
||||
)
|
||||
self.assertEqual(
|
||||
[femmesh_outfile.Volumes[0], femmesh_outfile.getElementNodes(femmesh_outfile.Volumes[0])],
|
||||
[
|
||||
femmesh_outfile.Volumes[0],
|
||||
femmesh_outfile.getElementNodes(femmesh_outfile.Volumes[0])
|
||||
],
|
||||
self.expected_elem['volumes'],
|
||||
"Test reading " + self.elem + " mesh to " + filetyp + " file failed. Volumes are different.\n"
|
||||
"Test reading {} mesh to {} file failed. Volumes are different.\n".format(
|
||||
self.elem,
|
||||
filetyp
|
||||
)
|
||||
)
|
||||
# both
|
||||
self.assertEqual(
|
||||
femmesh_outfile.Nodes,
|
||||
femmesh_testfile.Nodes,
|
||||
"Test writing " + self.elem + " mesh to " + filetyp + " file failed. Nodes are different.\n"
|
||||
"Test reading {} mesh to {} file failed. Nodes are different.\n".format(
|
||||
self.elem,
|
||||
filetyp
|
||||
)
|
||||
)
|
||||
self.assertEqual(
|
||||
[femmesh_outfile.Volumes[0], femmesh_outfile.getElementNodes(femmesh_outfile.Volumes[0])],
|
||||
[femmesh_testfile.Volumes[0], femmesh_testfile.getElementNodes(femmesh_outfile.Volumes[0])],
|
||||
"Test writing " + self.elem + " mesh to " + filetyp + " file failed. Volumes are different.\n"
|
||||
[
|
||||
femmesh_outfile.Volumes[0],
|
||||
femmesh_outfile.getElementNodes(femmesh_outfile.Volumes[0])
|
||||
],
|
||||
[
|
||||
femmesh_testfile.Volumes[0],
|
||||
femmesh_testfile.getElementNodes(femmesh_outfile.Volumes[0])
|
||||
],
|
||||
"Test reading {} mesh to {} file failed. Volumes are different.\n".format(
|
||||
self.elem,
|
||||
filetyp
|
||||
)
|
||||
)
|
||||
|
||||
def test_tetra10_unv(self):
|
||||
# ********************************************************************************************
|
||||
def test_tetra10_unv(
|
||||
self
|
||||
):
|
||||
# tetra10 element: reading from and writing to unv mesh file format
|
||||
filetyp = 'unv'
|
||||
outfile = self.base_outfile + filetyp
|
||||
@@ -277,37 +412,64 @@ class TestMeshEleTetra10(unittest.TestCase):
|
||||
self.assertEqual(
|
||||
femmesh_testfile.Nodes,
|
||||
self.expected_nodes['nodes'],
|
||||
"Test writing " + self.elem + " mesh to " + filetyp + " file failed. Nodes are different.\n"
|
||||
"Test reading {} mesh to {} file failed. Nodes are different.\n".format(
|
||||
self.elem,
|
||||
filetyp
|
||||
)
|
||||
)
|
||||
self.assertEqual(
|
||||
[femmesh_testfile.Volumes[0], femmesh_testfile.getElementNodes(femmesh_outfile.Volumes[0])],
|
||||
[
|
||||
femmesh_testfile.Volumes[0],
|
||||
femmesh_testfile.getElementNodes(femmesh_outfile.Volumes[0])
|
||||
],
|
||||
self.expected_elem['volumes'],
|
||||
"Test writing " + self.elem + " mesh to " + filetyp + " file failed. Volumes are different.\n"
|
||||
"Test reading {} mesh to {} file failed. Volumes are different.\n".format(
|
||||
self.elem,
|
||||
filetyp
|
||||
)
|
||||
)
|
||||
# reading the written mesh
|
||||
self.assertEqual(
|
||||
femmesh_outfile.Nodes,
|
||||
self.expected_nodes['nodes'],
|
||||
"Test writing " + self.elem + " mesh to " + filetyp + " file failed. Nodes are different.\n"
|
||||
"Test reading {} mesh to {} file failed. Nodes are different.\n".format(
|
||||
self.elem,
|
||||
filetyp
|
||||
)
|
||||
)
|
||||
self.assertEqual(
|
||||
[femmesh_outfile.Volumes[0], femmesh_outfile.getElementNodes(femmesh_outfile.Volumes[0])],
|
||||
[
|
||||
femmesh_outfile.Volumes[0],
|
||||
femmesh_outfile.getElementNodes(femmesh_outfile.Volumes[0])
|
||||
],
|
||||
self.expected_elem['volumes'],
|
||||
"Test writing " + self.elem + " mesh to " + filetyp + " file failed. Volumes are different.\n"
|
||||
"Test reading {} mesh to {} file failed. Volumes are different.\n".format(
|
||||
self.elem,
|
||||
filetyp
|
||||
)
|
||||
)
|
||||
# both
|
||||
self.assertEqual(
|
||||
femmesh_outfile.Nodes,
|
||||
femmesh_testfile.Nodes,
|
||||
"Test writing " + self.elem + " mesh to " + filetyp + " file failed. Nodes are different.\n"
|
||||
"Test reading {} mesh to {} file failed. Nodes are different.\n".format(
|
||||
self.elem,
|
||||
filetyp
|
||||
)
|
||||
)
|
||||
self.assertEqual(
|
||||
femmesh_outfile.Volumes,
|
||||
femmesh_testfile.Volumes,
|
||||
"Test writing " + self.elem + " mesh to " + filetyp + " file failed. Volumes are different.\n"
|
||||
"Test reading {} mesh to {} file failed. Volumes are different.\n".format(
|
||||
self.elem,
|
||||
filetyp
|
||||
)
|
||||
)
|
||||
|
||||
def test_tetra10_vkt(self):
|
||||
# ********************************************************************************************
|
||||
def test_tetra10_vkt(
|
||||
self
|
||||
):
|
||||
# tetra10 element: reading from and writing to unv mesh file format
|
||||
filetyp = 'vtk'
|
||||
outfile = self.base_outfile + filetyp
|
||||
@@ -322,39 +484,66 @@ class TestMeshEleTetra10(unittest.TestCase):
|
||||
self.assertEqual(
|
||||
femmesh_testfile.Nodes,
|
||||
self.expected_nodes['nodes'],
|
||||
"Test writing " + self.elem + " mesh to " + filetyp + " file failed. Nodes are different.\n"
|
||||
"Test reading {} mesh to {} file failed. Nodes are different.\n".format(
|
||||
self.elem,
|
||||
filetyp
|
||||
)
|
||||
)
|
||||
self.assertEqual(
|
||||
[femmesh_testfile.Volumes[0], femmesh_testfile.getElementNodes(femmesh_outfile.Volumes[0])],
|
||||
[
|
||||
femmesh_testfile.Volumes[0],
|
||||
femmesh_testfile.getElementNodes(femmesh_outfile.Volumes[0])
|
||||
],
|
||||
self.expected_elem['volumes'],
|
||||
"Test writing " + self.elem + " mesh to " + filetyp + " file failed. Volumes are different.\n"
|
||||
"Test reading {} mesh to {} file failed. Volumes are different.\n".format(
|
||||
self.elem,
|
||||
filetyp
|
||||
)
|
||||
)
|
||||
# reading the written mesh
|
||||
self.assertEqual(
|
||||
femmesh_outfile.Nodes,
|
||||
self.expected_nodes['nodes'],
|
||||
"Test writing " + self.elem + " mesh to " + filetyp + " file failed. Nodes are different.\n"
|
||||
"Test reading {} mesh to {} file failed. Nodes are different.\n".format(
|
||||
self.elem,
|
||||
filetyp
|
||||
)
|
||||
)
|
||||
self.assertEqual(
|
||||
[femmesh_outfile.Volumes[0], femmesh_outfile.getElementNodes(femmesh_outfile.Volumes[0])],
|
||||
[
|
||||
femmesh_outfile.Volumes[0],
|
||||
femmesh_outfile.getElementNodes(femmesh_outfile.Volumes[0])
|
||||
],
|
||||
self.expected_elem['volumes'],
|
||||
"Test writing " + self.elem + " mesh to " + filetyp + " file failed. Volumes are different.\n"
|
||||
"Test reading {} mesh to {} file failed. Volumes are different.\n".format(
|
||||
self.elem,
|
||||
filetyp
|
||||
)
|
||||
)
|
||||
# both
|
||||
self.assertEqual(
|
||||
femmesh_outfile.Nodes,
|
||||
femmesh_testfile.Nodes,
|
||||
"Test writing " + self.elem + " mesh to " + filetyp + " file failed. Nodes are different.\n"
|
||||
"Test reading {} mesh to {} file failed. Nodes are different.\n".format(
|
||||
self.elem,
|
||||
filetyp
|
||||
)
|
||||
)
|
||||
self.assertEqual(
|
||||
femmesh_outfile.Volumes,
|
||||
femmesh_testfile.Volumes,
|
||||
"Test writing " + self.elem + " mesh to " + filetyp + " file failed. Volumes are different.\n"
|
||||
"Test reading {} mesh to {} file failed. Volumes are different.\n".format(
|
||||
self.elem,
|
||||
filetyp
|
||||
)
|
||||
)
|
||||
else:
|
||||
fcc_print('FEM_VTK post processing is disabled.')
|
||||
|
||||
def test_tetra10_z88(self):
|
||||
# ********************************************************************************************
|
||||
def test_tetra10_z88(
|
||||
self
|
||||
):
|
||||
# tetra10 element: reading from and writing to z88 mesh file format
|
||||
filetyp = 'z88'
|
||||
outfile = self.base_outfile + filetyp
|
||||
@@ -368,37 +557,64 @@ class TestMeshEleTetra10(unittest.TestCase):
|
||||
self.assertEqual(
|
||||
femmesh_testfile.Nodes,
|
||||
self.expected_nodes['nodes'],
|
||||
"Test writing " + self.elem + " mesh to " + filetyp + " file failed. Nodes are different.\n"
|
||||
"Test reading {} mesh to {} file failed. Nodes are different.\n".format(
|
||||
self.elem,
|
||||
filetyp
|
||||
)
|
||||
)
|
||||
self.assertEqual(
|
||||
[femmesh_testfile.Volumes[0], femmesh_testfile.getElementNodes(femmesh_outfile.Volumes[0])],
|
||||
[
|
||||
femmesh_testfile.Volumes[0],
|
||||
femmesh_testfile.getElementNodes(femmesh_outfile.Volumes[0])
|
||||
],
|
||||
self.expected_elem['volumes'],
|
||||
"Test writing " + self.elem + " mesh to " + filetyp + " file failed. Volumes are different.\n"
|
||||
"Test reading {} mesh to {} file failed. Volumes are different.\n".format(
|
||||
self.elem,
|
||||
filetyp
|
||||
)
|
||||
)
|
||||
# reading the written mesh
|
||||
self.assertEqual(
|
||||
femmesh_outfile.Nodes,
|
||||
self.expected_nodes['nodes'],
|
||||
"Test writing " + self.elem + " mesh to " + filetyp + " file failed. Nodes are different.\n"
|
||||
"Test reading {} mesh to {} file failed. Nodes are different.\n".format(
|
||||
self.elem,
|
||||
filetyp
|
||||
)
|
||||
)
|
||||
self.assertEqual(
|
||||
[femmesh_outfile.Volumes[0], femmesh_outfile.getElementNodes(femmesh_outfile.Volumes[0])],
|
||||
[
|
||||
femmesh_outfile.Volumes[0],
|
||||
femmesh_outfile.getElementNodes(femmesh_outfile.Volumes[0])
|
||||
],
|
||||
self.expected_elem['volumes'],
|
||||
"Test writing " + self.elem + " mesh to " + filetyp + " file failed. Volumes are different.\n"
|
||||
"Test reading {} mesh to {} file failed. Volumes are different.\n".format(
|
||||
self.elem,
|
||||
filetyp
|
||||
)
|
||||
)
|
||||
# both
|
||||
self.assertEqual(
|
||||
femmesh_outfile.Nodes,
|
||||
femmesh_testfile.Nodes,
|
||||
"Test writing " + self.elem + " mesh to " + filetyp + " file failed. Nodes are different.\n"
|
||||
"Test reading {} mesh to {} file failed. Nodes are different.\n".format(
|
||||
self.elem,
|
||||
filetyp
|
||||
)
|
||||
)
|
||||
self.assertEqual(
|
||||
femmesh_outfile.Volumes,
|
||||
femmesh_testfile.Volumes,
|
||||
"Test writing " + self.elem + " mesh to " + filetyp + " file failed. Volumes are different.\n"
|
||||
"Test reading {} mesh to {} file failed. Volumes are different.\n".format(
|
||||
self.elem,
|
||||
filetyp
|
||||
)
|
||||
)
|
||||
|
||||
def tearDown(self):
|
||||
# ********************************************************************************************
|
||||
def tearDown(
|
||||
self
|
||||
):
|
||||
# clearance, is executed after every test
|
||||
FreeCAD.closeDocument(self.doc_name)
|
||||
pass
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -34,7 +34,10 @@ from os.path import join
|
||||
class TestResult(unittest.TestCase):
|
||||
fcc_print('import TestResult')
|
||||
|
||||
def setUp(self):
|
||||
# ********************************************************************************************
|
||||
def setUp(
|
||||
self
|
||||
):
|
||||
# init, is executed before every test
|
||||
self.doc_name = "TestResult"
|
||||
try:
|
||||
@@ -45,9 +48,16 @@ class TestResult(unittest.TestCase):
|
||||
FreeCAD.setActiveDocument(self.doc_name)
|
||||
self.active_doc = FreeCAD.ActiveDocument
|
||||
|
||||
def test_read_frd_massflow_networkpressure(self):
|
||||
# ********************************************************************************************
|
||||
def test_read_frd_massflow_networkpressure(
|
||||
self
|
||||
):
|
||||
# read data from frd file
|
||||
frd_file = join(testtools.get_fem_test_home_dir(), 'ccx', 'Flow1D_thermomech.frd')
|
||||
frd_file = join(
|
||||
testtools.get_fem_test_home_dir(),
|
||||
'ccx',
|
||||
'Flow1D_thermomech.frd'
|
||||
)
|
||||
from feminout.importCcxFrdResults import read_frd_result as read_frd
|
||||
frd_content = read_frd(frd_file)
|
||||
|
||||
@@ -119,8 +129,14 @@ class TestResult(unittest.TestCase):
|
||||
12: (12, 26, 13)
|
||||
}
|
||||
'''
|
||||
efc['Tria3Elem'] = efc['Tria6Elem'] = efc['Quad4Elem'] = efc['Quad8Elem'] = {} # faces
|
||||
efc['Tetra4Elem'] = efc['Tetra10Elem'] = efc['Hexa8Elem'] = efc['Hexa20Elem'] = efc['Penta6Elem'] = efc['Penta15Elem'] = {} # volumes
|
||||
# faces
|
||||
efc['Tria3Elem'] = efc['Tria6Elem'] = {}
|
||||
efc['Quad4Elem'] = efc['Quad8Elem'] = {}
|
||||
# volumes
|
||||
efc['Tetra4Elem'] = efc['Tetra10Elem'] = {}
|
||||
efc['Hexa8Elem'] = efc['Hexa20Elem'] = {}
|
||||
efc['Penta6Elem'] = efc['Penta15Elem'] = {}
|
||||
|
||||
efc['Results'] = [
|
||||
{'time': 0.00390625},
|
||||
{'time': 0.0078125},
|
||||
@@ -217,21 +233,61 @@ class TestResult(unittest.TestCase):
|
||||
print(expected_npressure)
|
||||
|
||||
# tests
|
||||
self.assertEqual(frd_content_len, expected_frd_content_len, "Length's of read frd data values are unexpected")
|
||||
self.assertEqual(frd_content['Nodes'], expected_frd_content['Nodes'], "Values of read node data are unexpected")
|
||||
self.assertEqual(frd_content['Seg2Elem'], expected_frd_content['Seg2Elem'], "Values of read Seg2 data are unexpected")
|
||||
self.assertEqual(frd_content['Seg3Elem'], expected_frd_content['Seg3Elem'], "Values of read Seg3 data are unexpected")
|
||||
self.assertEqual(res_len, expected_res_len, "Length's of read result data values are unexpected")
|
||||
self.assertEqual(read_mflow, expected_mflow, "Values of read mflow result data are unexpected")
|
||||
self.assertEqual(read_npressure, expected_npressure, "Values of read npressure result data are unexpected")
|
||||
self.assertEqual(
|
||||
frd_content_len,
|
||||
expected_frd_content_len,
|
||||
"Length's of read frd data values are unexpected"
|
||||
)
|
||||
self.assertEqual(
|
||||
frd_content['Nodes'],
|
||||
expected_frd_content['Nodes'],
|
||||
"Values of read node data are unexpected"
|
||||
)
|
||||
self.assertEqual(
|
||||
frd_content['Seg2Elem'],
|
||||
expected_frd_content['Seg2Elem'],
|
||||
"Values of read Seg2 data are unexpected"
|
||||
)
|
||||
self.assertEqual(
|
||||
frd_content['Seg3Elem'],
|
||||
expected_frd_content['Seg3Elem'],
|
||||
"Values of read Seg3 data are unexpected"
|
||||
)
|
||||
self.assertEqual(
|
||||
res_len,
|
||||
expected_res_len,
|
||||
"Length's of read result data values are unexpected"
|
||||
)
|
||||
self.assertEqual(
|
||||
read_mflow,
|
||||
expected_mflow,
|
||||
"Values of read mflow result data are unexpected"
|
||||
)
|
||||
self.assertEqual(
|
||||
read_npressure,
|
||||
expected_npressure,
|
||||
"Values of read npressure result data are unexpected"
|
||||
)
|
||||
|
||||
def get_stress_values(self):
|
||||
# ********************************************************************************************
|
||||
def get_stress_values(
|
||||
self
|
||||
):
|
||||
# node 5 von calculix cantilver 3D example
|
||||
# doc = FreeCAD.open(FreeCAD.ConfigGet("AppHomePath") + 'data/examples/FemCalculixCantilever3D.FCStd')
|
||||
# doc = FreeCAD.open(
|
||||
# FreeCAD.ConfigGet("AppHomePath") + 'data/examples/FemCalculixCantilever3D.FCStd'
|
||||
# )
|
||||
# doc.Box_Mesh.FemMesh.Nodes[5]
|
||||
# Vector (0.0, 1000.0, 0.0)
|
||||
# res = doc.CalculiX_static_results
|
||||
# stress = (res.NodeStressXX[4], res.NodeStressYY[4], res.NodeStressZZ[4], res.NodeStressXY[4], res.NodeStressXZ[4],res.NodeStressYZ[4])
|
||||
# stress = (
|
||||
# res.NodeStressXX[4],
|
||||
# res.NodeStressYY[4],
|
||||
# res.NodeStressZZ[4],
|
||||
# res.NodeStressXY[4],
|
||||
# res.NodeStressXZ[4],
|
||||
# res.NodeStressYZ[4]
|
||||
# )
|
||||
stress = (
|
||||
-4.52840E+02, # Sxx
|
||||
-1.94075E+02, # Syy
|
||||
@@ -242,30 +298,60 @@ class TestResult(unittest.TestCase):
|
||||
)
|
||||
return stress
|
||||
|
||||
def test_stress_von_mises(self):
|
||||
# ********************************************************************************************
|
||||
def test_stress_von_mises(
|
||||
self
|
||||
):
|
||||
expected_mises = 283.2082
|
||||
from femresult.resulttools import calculate_von_mises as vm
|
||||
mises = vm(self.get_stress_values())
|
||||
# fcc_print(round(mises, 4))
|
||||
self.assertEqual(round(mises, 4), expected_mises, "Calculated von Mises stress is not the expected value.")
|
||||
self.assertEqual(
|
||||
round(mises, 4),
|
||||
expected_mises,
|
||||
"Calculated von Mises stress is not the expected value."
|
||||
)
|
||||
|
||||
def test_stress_principal(self):
|
||||
# ********************************************************************************************
|
||||
def test_stress_principal(
|
||||
self
|
||||
):
|
||||
expected_principal = (-178.0076, -194.0749, -468.9075, 145.4499)
|
||||
from femresult.resulttools import calculate_principal_stress as pr
|
||||
prin = pr(self.get_stress_values())
|
||||
rounded_prin = (round(prin[0], 4), round(prin[1], 4), round(prin[2], 4), round(prin[3], 4))
|
||||
rounded_prin = (
|
||||
round(prin[0], 4),
|
||||
round(prin[1], 4),
|
||||
round(prin[2], 4),
|
||||
round(prin[3], 4)
|
||||
)
|
||||
# fcc_print(rounded_prin)
|
||||
self.assertEqual(rounded_prin, expected_principal, "Calculated principal stresses are not the expected values.")
|
||||
self.assertEqual(
|
||||
rounded_prin,
|
||||
expected_principal,
|
||||
"Calculated principal stresses are not the expected values."
|
||||
)
|
||||
|
||||
def test_disp_abs(self):
|
||||
# ********************************************************************************************
|
||||
def test_disp_abs(
|
||||
self
|
||||
):
|
||||
expected_dispabs = 87.302986
|
||||
disp_xyz = [FreeCAD.Vector(8.12900E+00, 3.38889E-02, -8.69237E+01)] # x, y, z in node 4 of CalculiX cantilver face load
|
||||
# x, y, z in node 4 of CalculiX cantilver face load
|
||||
disp_xyz = [FreeCAD.Vector(8.12900E+00, 3.38889E-02, -8.69237E+01)]
|
||||
from femresult.resulttools import calculate_disp_abs as dp
|
||||
disp_abs = round(dp(disp_xyz)[0], 6)
|
||||
# fcc_print(disp_abs)
|
||||
self.assertEqual(disp_abs, expected_dispabs, "Calculated displacement abs are not the expected values.")
|
||||
self.assertEqual(
|
||||
disp_abs,
|
||||
expected_dispabs,
|
||||
"Calculated displacement abs are not the expected values."
|
||||
)
|
||||
|
||||
def tearDown(self):
|
||||
# ********************************************************************************************
|
||||
def tearDown(
|
||||
self
|
||||
):
|
||||
# clearance, is executed after every test
|
||||
FreeCAD.closeDocument(self.doc_name)
|
||||
pass
|
||||
|
||||
@@ -36,7 +36,10 @@ from os.path import join
|
||||
class TestSolverFrameWork(unittest.TestCase):
|
||||
fcc_print('import TestSolverFrameWork')
|
||||
|
||||
def setUp(self):
|
||||
# ********************************************************************************************
|
||||
def setUp(
|
||||
self
|
||||
):
|
||||
# init, is executed before every test
|
||||
self.doc_name = "TestSolverFrameWork"
|
||||
try:
|
||||
@@ -50,15 +53,24 @@ class TestSolverFrameWork(unittest.TestCase):
|
||||
self.temp_dir = testtools.get_fem_test_tmp_dir()
|
||||
self.test_file_dir = join(testtools.get_fem_test_home_dir(), 'ccx')
|
||||
|
||||
def test_solver_framework(self):
|
||||
# ********************************************************************************************
|
||||
def test_solver_framework(
|
||||
self
|
||||
):
|
||||
fcc_print('\n--------------- Start of FEM tests solver frame work ---------------')
|
||||
box = self.active_doc.addObject("Part::Box", "Box")
|
||||
fcc_print('Checking FEM new analysis...')
|
||||
analysis = ObjectsFem.makeAnalysis(self.active_doc, 'Analysis')
|
||||
analysis = ObjectsFem.makeAnalysis(
|
||||
self.active_doc,
|
||||
'Analysis'
|
||||
)
|
||||
self.assertTrue(analysis, "FemTest of new analysis failed")
|
||||
|
||||
fcc_print('Checking FEM new material...')
|
||||
material_object = ObjectsFem.makeMaterialSolid(self.active_doc, 'MechanicalMaterial')
|
||||
material_object = ObjectsFem.makeMaterialSolid(
|
||||
self.active_doc,
|
||||
'MechanicalMaterial'
|
||||
)
|
||||
mat = material_object.Material
|
||||
mat['Name'] = "Steel-Generic"
|
||||
mat['YoungsModulus'] = "200000 MPa"
|
||||
@@ -69,13 +81,19 @@ class TestSolverFrameWork(unittest.TestCase):
|
||||
analysis.addObject(material_object)
|
||||
|
||||
fcc_print('Checking FEM new fixed constraint...')
|
||||
fixed_constraint = self.active_doc.addObject("Fem::ConstraintFixed", "FemConstraintFixed")
|
||||
fixed_constraint = self.active_doc.addObject(
|
||||
"Fem::ConstraintFixed",
|
||||
"FemConstraintFixed"
|
||||
)
|
||||
fixed_constraint.References = [(box, "Face1")]
|
||||
self.assertTrue(fixed_constraint, "FemTest of new fixed constraint failed")
|
||||
analysis.addObject(fixed_constraint)
|
||||
|
||||
fcc_print('Checking FEM new force constraint...')
|
||||
force_constraint = self.active_doc.addObject("Fem::ConstraintForce", "FemConstraintForce")
|
||||
force_constraint = self.active_doc.addObject(
|
||||
"Fem::ConstraintForce",
|
||||
"FemConstraintForce"
|
||||
)
|
||||
force_constraint.References = [(box, "Face6")]
|
||||
force_constraint.Force = 40000.0
|
||||
force_constraint.Direction = (box, ["Edge5"])
|
||||
@@ -86,7 +104,10 @@ class TestSolverFrameWork(unittest.TestCase):
|
||||
analysis.addObject(force_constraint)
|
||||
|
||||
fcc_print('Checking FEM new pressure constraint...')
|
||||
pressure_constraint = self.active_doc.addObject("Fem::ConstraintPressure", "FemConstraintPressure")
|
||||
pressure_constraint = self.active_doc.addObject(
|
||||
"Fem::ConstraintPressure",
|
||||
"FemConstraintPressure"
|
||||
)
|
||||
pressure_constraint.References = [(box, "Face2")]
|
||||
pressure_constraint.Pressure = 1000.0
|
||||
pressure_constraint.Reversed = False
|
||||
@@ -101,7 +122,10 @@ class TestSolverFrameWork(unittest.TestCase):
|
||||
self.assertTrue(ret, "Import of mesh nodes failed")
|
||||
ret = create_elements_cube(mesh)
|
||||
self.assertTrue(ret, "Import of mesh volumes failed")
|
||||
mesh_object = self.active_doc.addObject('Fem::FemMeshObject', self.mesh_name)
|
||||
mesh_object = self.active_doc.addObject(
|
||||
'Fem::FemMeshObject',
|
||||
self.mesh_name
|
||||
)
|
||||
mesh_object.FemMesh = mesh
|
||||
self.assertTrue(mesh, "FemTest of new mesh failed")
|
||||
analysis.addObject(mesh_object)
|
||||
@@ -111,7 +135,10 @@ class TestSolverFrameWork(unittest.TestCase):
|
||||
# solver frame work ccx solver
|
||||
# calculix solver object
|
||||
fcc_print('\nChecking FEM CalculiX solver for solver frame work...')
|
||||
solver_ccx_object = ObjectsFem.makeSolverCalculix(self.active_doc, 'SolverCalculiX')
|
||||
solver_ccx_object = ObjectsFem.makeSolverCalculix(
|
||||
self.active_doc,
|
||||
'SolverCalculiX'
|
||||
)
|
||||
solver_ccx_object.AnalysisType = 'static'
|
||||
solver_ccx_object.GeometricalNonlinearity = 'linear'
|
||||
solver_ccx_object.ThermoMechSteadyState = False
|
||||
@@ -124,17 +151,27 @@ class TestSolverFrameWork(unittest.TestCase):
|
||||
analysis.addObject(solver_ccx_object)
|
||||
|
||||
static_base_name = 'cube_static'
|
||||
solverframework_analysis_dir = testtools.get_unit_test_tmp_dir(testtools.get_fem_test_tmp_dir(), 'FEM_solverframework')
|
||||
solverframework_analysis_dir = testtools.get_unit_test_tmp_dir(
|
||||
testtools.get_fem_test_tmp_dir(),
|
||||
'FEM_solverframework'
|
||||
)
|
||||
|
||||
# write input file
|
||||
fcc_print('Checking FEM ccx solver for solver frame work......')
|
||||
fcc_print('machine_ccx')
|
||||
machine_ccx = solver_ccx_object.Proxy.createMachine(solver_ccx_object, solverframework_analysis_dir)
|
||||
machine_ccx = solver_ccx_object.Proxy.createMachine(
|
||||
solver_ccx_object,
|
||||
solverframework_analysis_dir
|
||||
)
|
||||
machine_ccx.target = femsolver.run.PREPARE
|
||||
machine_ccx.start()
|
||||
machine_ccx.join() # wait for the machine to finish.
|
||||
|
||||
infile_given = join(testtools.get_fem_test_home_dir(), 'ccx', (static_base_name + '.inp'))
|
||||
infile_given = join(
|
||||
testtools.get_fem_test_home_dir(),
|
||||
'ccx',
|
||||
(static_base_name + '.inp')
|
||||
)
|
||||
inpfile_totest = join(solverframework_analysis_dir, (self.mesh_name + '.inp'))
|
||||
fcc_print('Comparing {} to {}'.format(infile_given, inpfile_totest))
|
||||
ret = testtools.compare_inp_files(infile_given, inpfile_totest)
|
||||
@@ -142,20 +179,30 @@ class TestSolverFrameWork(unittest.TestCase):
|
||||
|
||||
# use solver frame work elmer solver
|
||||
# elmer solver object
|
||||
solver_elmer_object = ObjectsFem.makeSolverElmer(self.active_doc, 'SolverElmer')
|
||||
solver_elmer_object = ObjectsFem.makeSolverElmer(
|
||||
self.active_doc,
|
||||
'SolverElmer'
|
||||
)
|
||||
self.assertTrue(solver_elmer_object, "FemTest of elmer solver failed")
|
||||
analysis.addObject(solver_elmer_object)
|
||||
solver_elmer_eqobj = ObjectsFem.makeEquationElasticity(self.active_doc, solver_elmer_object)
|
||||
solver_elmer_eqobj = ObjectsFem.makeEquationElasticity(
|
||||
self.active_doc,
|
||||
solver_elmer_object
|
||||
)
|
||||
self.assertTrue(solver_elmer_eqobj, "FemTest of elmer elasticity equation failed")
|
||||
|
||||
# set ThermalExpansionCoefficient, current elmer seems to need it even on simple elasticity analysis
|
||||
# set ThermalExpansionCoefficient
|
||||
# current elmer seems to need it even on simple elasticity analysis
|
||||
mat = material_object.Material
|
||||
mat['ThermalExpansionCoefficient'] = "0 um/m/K" # FIXME elmer elasticity needs the dictionary key, otherwise it fails
|
||||
# FIXME elmer elasticity needs the dictionary key, otherwise it fails
|
||||
mat['ThermalExpansionCoefficient'] = "0 um/m/K"
|
||||
material_object.Material = mat
|
||||
|
||||
mesh_gmsh = ObjectsFem.makeMeshGmsh(self.active_doc)
|
||||
mesh_gmsh.CharacteristicLengthMin = "9 mm"
|
||||
mesh_gmsh.FemMesh = mesh_object.FemMesh # elmer needs a GMHS mesh object, FIXME error message on Python solver run
|
||||
# elmer needs a GMHS mesh object
|
||||
# FIXME error message on Python solver run
|
||||
mesh_gmsh.FemMesh = mesh_object.FemMesh
|
||||
mesh_gmsh.Part = box
|
||||
analysis.addObject(mesh_gmsh)
|
||||
self.active_doc.removeObject(mesh_object.Name)
|
||||
@@ -163,7 +210,11 @@ class TestSolverFrameWork(unittest.TestCase):
|
||||
# solver frame work Elmer solver
|
||||
# write input files
|
||||
fcc_print('\nChecking FEM Elmer solver for solver frame work...')
|
||||
machine_elmer = solver_elmer_object.Proxy.createMachine(solver_elmer_object, solverframework_analysis_dir, True)
|
||||
machine_elmer = solver_elmer_object.Proxy.createMachine(
|
||||
solver_elmer_object,
|
||||
solverframework_analysis_dir,
|
||||
True
|
||||
)
|
||||
machine_elmer.target = femsolver.run.PREPARE
|
||||
machine_elmer.start()
|
||||
machine_elmer.join() # wait for the machine to finish.
|
||||
@@ -197,7 +248,10 @@ class TestSolverFrameWork(unittest.TestCase):
|
||||
self.active_doc.saveAs(save_fc_file)
|
||||
fcc_print('--------------- End of FEM tests solver frame work ---------------')
|
||||
|
||||
def tearDown(self):
|
||||
# ********************************************************************************************
|
||||
def tearDown(
|
||||
self
|
||||
):
|
||||
# clearance, is executed after every test
|
||||
FreeCAD.closeDocument(self.doc_name)
|
||||
pass
|
||||
|
||||
@@ -34,29 +34,38 @@ import FreeCAD
|
||||
from os.path import join
|
||||
|
||||
|
||||
def get_fem_test_home_dir():
|
||||
def get_fem_test_home_dir(
|
||||
):
|
||||
return join(FreeCAD.getHomePath(), 'Mod', 'Fem', 'femtest', 'testfiles')
|
||||
|
||||
|
||||
def get_fem_test_tmp_dir():
|
||||
def get_fem_test_tmp_dir(
|
||||
):
|
||||
temp_dir = join(tempfile.gettempdir(), 'FEM_unittests')
|
||||
if not os.path.exists(temp_dir):
|
||||
os.makedirs(temp_dir)
|
||||
return(temp_dir)
|
||||
|
||||
|
||||
def get_unit_test_tmp_dir(temp_dir, unittestdir):
|
||||
def get_unit_test_tmp_dir(
|
||||
temp_dir,
|
||||
unittestdir
|
||||
):
|
||||
testdir = join(temp_dir, unittestdir)
|
||||
if not os.path.exists(testdir):
|
||||
os.makedirs(testdir)
|
||||
return testdir
|
||||
|
||||
|
||||
def fcc_print(message):
|
||||
def fcc_print(
|
||||
message
|
||||
):
|
||||
FreeCAD.Console.PrintMessage('{} \n'.format(message))
|
||||
|
||||
|
||||
def get_defmake_count(fem_vtk_post=True):
|
||||
def get_defmake_count(
|
||||
fem_vtk_post=True
|
||||
):
|
||||
'''
|
||||
count the def make in module ObjectsFem
|
||||
could also be done in bash with
|
||||
@@ -67,7 +76,9 @@ def get_defmake_count(fem_vtk_post=True):
|
||||
lines_modefile = modfile.readlines()
|
||||
modfile.close()
|
||||
lines_defmake = [l for l in lines_modefile if l.startswith('def make')]
|
||||
if not fem_vtk_post: # FEM VTK post processing is disabled, we are not able to create VTK post objects
|
||||
if not fem_vtk_post:
|
||||
# FEM VTK post processing is disabled
|
||||
# we are not able to create VTK post objects
|
||||
new_lines = []
|
||||
for l in lines_defmake:
|
||||
if "PostVtk" not in l:
|
||||
@@ -76,7 +87,9 @@ def get_defmake_count(fem_vtk_post=True):
|
||||
return len(lines_defmake)
|
||||
|
||||
|
||||
def get_fem_test_defs(inout='out'):
|
||||
def get_fem_test_defs(
|
||||
inout='out'
|
||||
):
|
||||
test_path = join(FreeCAD.getHomePath(), 'Mod', 'Fem', 'femtest')
|
||||
collected_test_modules = []
|
||||
collected_test_methods = []
|
||||
@@ -97,12 +110,17 @@ def get_fem_test_defs(inout='out'):
|
||||
if ln.startswith('def test'):
|
||||
ln = ln.lstrip('def ')
|
||||
ln = ln.split('(')[0]
|
||||
collected_test_methods.append('femtest.{}.{}.{}'.format(module_name, class_name, ln))
|
||||
collected_test_methods.append(
|
||||
'femtest.{}.{}.{}'.format(module_name, class_name, ln)
|
||||
)
|
||||
tfile.close()
|
||||
print('')
|
||||
for m in collected_test_methods:
|
||||
run_outside_fc = './bin/FreeCADCmd --run-test "{}"'.format(m)
|
||||
run_inside_fc = 'unittest.TextTestRunner().run(unittest.TestLoader().loadTestsFromName("{}"))'.format(m)
|
||||
run_inside_fc = (
|
||||
'unittest.TextTestRunner().run(unittest.TestLoader().loadTestsFromName("{}"))'
|
||||
.format(m)
|
||||
)
|
||||
if inout == 'in':
|
||||
print('\nimport unittest')
|
||||
print(run_inside_fc)
|
||||
@@ -110,12 +128,17 @@ def get_fem_test_defs(inout='out'):
|
||||
print(run_outside_fc)
|
||||
|
||||
|
||||
def compare_inp_files(file_name1, file_name2):
|
||||
def compare_inp_files(
|
||||
file_name1,
|
||||
file_name2
|
||||
):
|
||||
file1 = open(file_name1, 'r')
|
||||
f1 = file1.readlines()
|
||||
file1.close()
|
||||
# l.startswith('17671.0,1') is a temporary workaround for python3 problem with 1DFlow input
|
||||
# TODO as soon as the 1DFlow result reading is fixed, this should be triggered in the 1DFlow unit test
|
||||
# l.startswith('17671.0,1') is a temporary workaround
|
||||
# for python3 problem with 1DFlow input
|
||||
# TODO as soon as the 1DFlow result reading is fixed
|
||||
# this should be triggered in the 1DFlow unit test
|
||||
lf1 = [l for l in f1 if not (l.startswith('** written ') or l.startswith('** file ') or l.startswith('17671.0,1'))]
|
||||
lf1 = force_unix_line_ends(lf1)
|
||||
file2 = open(file_name2, 'r')
|
||||
@@ -130,11 +153,17 @@ def compare_inp_files(file_name1, file_name2):
|
||||
for l in diff:
|
||||
result += l
|
||||
if result:
|
||||
result = "Comparing {} to {} failed!\n".format(file_name1, file_name2) + result
|
||||
result = (
|
||||
"Comparing {} to {} failed!\n"
|
||||
.format(file_name1, file_name2) + result
|
||||
)
|
||||
return result
|
||||
|
||||
|
||||
def compare_files(file_name1, file_name2):
|
||||
def compare_files(
|
||||
file_name1,
|
||||
file_name2
|
||||
):
|
||||
file1 = open(file_name1, 'r')
|
||||
f1 = file1.readlines()
|
||||
file1.close()
|
||||
@@ -157,9 +186,28 @@ def compare_files(file_name1, file_name2):
|
||||
return result
|
||||
|
||||
|
||||
def compare_stats(fea, stat_file=None, loc_stat_types=None, res_obj_name=None):
|
||||
def compare_stats(
|
||||
fea,
|
||||
stat_file=None,
|
||||
loc_stat_types=None,
|
||||
res_obj_name=None
|
||||
):
|
||||
import femresult.resulttools as resulttools
|
||||
stat_types = ["U1", "U2", "U3", "Uabs", "Sabs", "MaxPrin", "MidPrin", "MinPrin", "MaxShear", "Peeq", "Temp", "MFlow", "NPress"]
|
||||
stat_types = [
|
||||
"U1",
|
||||
"U2",
|
||||
"U3",
|
||||
"Uabs",
|
||||
"Sabs",
|
||||
"MaxPrin",
|
||||
"MidPrin",
|
||||
"MinPrin",
|
||||
"MaxShear",
|
||||
"Peeq",
|
||||
"Temp",
|
||||
"MFlow",
|
||||
"NPress"
|
||||
]
|
||||
if not loc_stat_types:
|
||||
loc_stat_types = stat_types
|
||||
if stat_file:
|
||||
@@ -174,11 +222,17 @@ def compare_stats(fea, stat_file=None, loc_stat_types=None, res_obj_name=None):
|
||||
stats = []
|
||||
for s in loc_stat_types:
|
||||
if res_obj_name:
|
||||
statval = resulttools.get_stats(FreeCAD.ActiveDocument.getObject(res_obj_name), s)
|
||||
statval = resulttools.get_stats(
|
||||
FreeCAD.ActiveDocument.getObject(res_obj_name),
|
||||
s
|
||||
)
|
||||
else:
|
||||
print('No result object name given')
|
||||
return False
|
||||
stats.append("{0}: ({1:.14g}, {2:.14g}, {3:.14g})\n".format(s, statval[0], statval[1], statval[2]))
|
||||
stats.append(
|
||||
"{0}: ({1:.14g}, {2:.14g}, {3:.14g})\n"
|
||||
.format(s, statval[0], statval[1], statval[2])
|
||||
)
|
||||
if sf_content != stats:
|
||||
fcc_print("Expected stats from {}".format(stat_file))
|
||||
fcc_print(sf_content)
|
||||
@@ -188,7 +242,9 @@ def compare_stats(fea, stat_file=None, loc_stat_types=None, res_obj_name=None):
|
||||
return False
|
||||
|
||||
|
||||
def force_unix_line_ends(line_list):
|
||||
def force_unix_line_ends(
|
||||
line_list
|
||||
):
|
||||
new_line_list = []
|
||||
for ln in line_list:
|
||||
if ln.endswith("\r\n"):
|
||||
@@ -197,7 +253,9 @@ def force_unix_line_ends(line_list):
|
||||
return new_line_list
|
||||
|
||||
|
||||
def collect_python_modules(femsubdir=None):
|
||||
def collect_python_modules(
|
||||
femsubdir=None
|
||||
):
|
||||
if not femsubdir:
|
||||
pydir = join(FreeCAD.ConfigGet("AppHomePath"), 'Mod', 'Fem')
|
||||
else:
|
||||
@@ -207,14 +265,19 @@ def collect_python_modules(femsubdir=None):
|
||||
for pyfile in sorted(os.listdir(pydir)):
|
||||
if pyfile.endswith(".py") and not pyfile.startswith('Init'):
|
||||
if not femsubdir:
|
||||
collected_modules.append(os.path.splitext(os.path.basename(pyfile))[0])
|
||||
collected_modules.append(
|
||||
os.path.splitext(os.path.basename(pyfile))[0]
|
||||
)
|
||||
else:
|
||||
collected_modules.append(femsubdir.replace('/', '.') + '.' + os.path.splitext(os.path.basename(pyfile))[0])
|
||||
collected_modules.append(
|
||||
femsubdir.replace('/', '.') + '.' + os.path.splitext(os.path.basename(pyfile))[0]
|
||||
)
|
||||
return collected_modules
|
||||
|
||||
|
||||
# open all files
|
||||
def all_test_files():
|
||||
def all_test_files(
|
||||
):
|
||||
# open all files
|
||||
cube_frequency()
|
||||
cube_static()
|
||||
Flow1D_thermomech()
|
||||
@@ -222,32 +285,63 @@ def all_test_files():
|
||||
spine_thermomech()
|
||||
|
||||
|
||||
# run the specific test case of the file, open the file in FreeCAD GUI and return the doc identifier
|
||||
def cube_frequency():
|
||||
# run the specific test case of the file
|
||||
# open the file in FreeCAD GUI and return the doc identifier
|
||||
def cube_frequency(
|
||||
):
|
||||
testname = "femtest.testccxtools.TestCcxTools.test_3_freq_analysis"
|
||||
unittest.TextTestRunner().run(unittest.TestLoader().loadTestsFromName(testname))
|
||||
return FreeCAD.open(join(get_fem_test_tmp_dir(), 'FEM_ccx_frequency', 'cube_frequency.FCStd'))
|
||||
doc = FreeCAD.open(join(
|
||||
get_fem_test_tmp_dir(),
|
||||
'FEM_ccx_frequency',
|
||||
'cube_frequency.FCStd')
|
||||
)
|
||||
return doc
|
||||
|
||||
|
||||
def cube_static():
|
||||
def cube_static(
|
||||
):
|
||||
testname = "femtest.testccxtools.TestCcxTools.test_1_static_analysis"
|
||||
unittest.TextTestRunner().run(unittest.TestLoader().loadTestsFromName(testname))
|
||||
return FreeCAD.open(join(get_fem_test_tmp_dir(), 'FEM_ccx_static', 'cube_static.FCStd'))
|
||||
doc = FreeCAD.open(
|
||||
join(get_fem_test_tmp_dir(),
|
||||
'FEM_ccx_static',
|
||||
'cube_static.FCStd')
|
||||
)
|
||||
return doc
|
||||
|
||||
|
||||
def Flow1D_thermomech():
|
||||
def Flow1D_thermomech(
|
||||
):
|
||||
testname = "femtest.testccxtools.TestCcxTools.test_5_Flow1D_thermomech_analysis"
|
||||
unittest.TextTestRunner().run(unittest.TestLoader().loadTestsFromName(testname))
|
||||
return FreeCAD.open(join(get_fem_test_tmp_dir(), 'FEM_ccx_Flow1D_thermomech', 'Flow1D_thermomech.FCStd'))
|
||||
doc = FreeCAD.open(join(
|
||||
get_fem_test_tmp_dir(),
|
||||
'FEM_ccx_Flow1D_thermomech',
|
||||
'Flow1D_thermomech.FCStd')
|
||||
)
|
||||
return doc
|
||||
|
||||
|
||||
def multimat():
|
||||
def multimat(
|
||||
):
|
||||
testname = "femtest.testccxtools.TestCcxTools.test_2_static_multiple_material"
|
||||
unittest.TextTestRunner().run(unittest.TestLoader().loadTestsFromName(testname))
|
||||
return FreeCAD.open(join(get_fem_test_tmp_dir(), 'FEM_ccx_multimat', 'multimat.FCStd'))
|
||||
doc = FreeCAD.open(join(
|
||||
get_fem_test_tmp_dir(),
|
||||
'FEM_ccx_multimat',
|
||||
'multimat.FCStd')
|
||||
)
|
||||
return doc
|
||||
|
||||
|
||||
def spine_thermomech():
|
||||
def spine_thermomech(
|
||||
):
|
||||
testname = "femtest.testccxtools.TestCcxTools.test_4_thermomech_analysis"
|
||||
unittest.TextTestRunner().run(unittest.TestLoader().loadTestsFromName(testname))
|
||||
return FreeCAD.open(join(get_fem_test_tmp_dir(), 'FEM_ccx_thermomech', 'spine_thermomech.FCStd'))
|
||||
doc = FreeCAD.open(join(
|
||||
get_fem_test_tmp_dir(),
|
||||
'FEM_ccx_thermomech',
|
||||
'spine_thermomech.FCStd')
|
||||
)
|
||||
return doc
|
||||
|
||||
Reference in New Issue
Block a user