diff --git a/src/Mod/Fem/CMakeLists.txt b/src/Mod/Fem/CMakeLists.txt index abb933d3d4..7a2967bb59 100755 --- a/src/Mod/Fem/CMakeLists.txt +++ b/src/Mod/Fem/CMakeLists.txt @@ -117,6 +117,7 @@ SET(FemTests_SRCS femtest/__init__.py femtest/testccxtools.py femtest/testcommon.py + femtest/testmesh.py femtest/testsolverframework.py femtest/testtools.py ) diff --git a/src/Mod/Fem/TestFem.py b/src/Mod/Fem/TestFem.py index ebf703436d..3b080b7e34 100644 --- a/src/Mod/Fem/TestFem.py +++ b/src/Mod/Fem/TestFem.py @@ -1,8 +1,7 @@ -# Unit test for the FEM module - # *************************************************************************** -# * Copyright (c) 2015 - FreeCAD Developers * +# * Copyright (c) 2018 - FreeCAD Developers * # * Author: Przemo Firszt * +# * Author: Bernd Hahnebach * # * * # * This file is part of the FreeCAD CAx development system. * # * * @@ -25,9 +24,11 @@ # ***************************************************************************/ +# Unit test for the FEM module # the order should be as follows: # common-, object-, mesh-, inout-, ccxtools-, solverframworktests from femtest.testcommon import FemTest +from femtest.testmesh import FemMeshTest from femtest.testccxtools import FemCcxAnalysisTest from femtest.testsolverframework import SolverFrameWorkTest diff --git a/src/Mod/Fem/femtest/testcommon.py b/src/Mod/Fem/femtest/testcommon.py index 6c55a60ca0..dfdc330219 100644 --- a/src/Mod/Fem/femtest/testcommon.py +++ b/src/Mod/Fem/femtest/testcommon.py @@ -41,88 +41,6 @@ class FemTest(unittest.TestCase): FreeCAD.setActiveDocument("FemTest") self.active_doc = FreeCAD.ActiveDocument - def test_mesh_seg2_python(self): - seg2 = Fem.FemMesh() - seg2.addNode(0, 0, 0, 1) - seg2.addNode(2, 0, 0, 2) - seg2.addNode(4, 0, 0, 3) - 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)}] - 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") - - def test_mesh_seg3_python(self): - seg3 = Fem.FemMesh() - seg3.addNode(0, 0, 0, 1) - seg3.addNode(1, 0, 0, 2) - seg3.addNode(2, 0, 0, 3) - seg3.addNode(3, 0, 0, 4) - seg3.addNode(4, 0, 0, 5) - seg3.addEdge([1, 3, 2]) - 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])] - expected_nodes = [5, {1: FreeCAD.Vector(0.0, 0.0, 0.0), 2: FreeCAD.Vector(1.0, 0.0, 0.0), 3: FreeCAD.Vector(2.0, 0.0, 0.0), 4: FreeCAD.Vector(3.0, 0.0, 0.0), 5: FreeCAD.Vector(4.0, 0.0, 0.0)}] - 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") - - def test_unv_save_load(self): - tetra10 = Fem.FemMesh() - tetra10.addNode(6, 12, 18, 1) - tetra10.addNode(0, 0, 18, 2) - tetra10.addNode(12, 0, 18, 3) - tetra10.addNode(6, 6, 0, 4) - - tetra10.addNode(3, 6, 18, 5) - tetra10.addNode(6, 0, 18, 6) - tetra10.addNode(9, 6, 18, 7) - - tetra10.addNode(6, 9, 9, 8) - tetra10.addNode(3, 3, 9, 9) - tetra10.addNode(9, 3, 9, 10) - tetra10.addVolume([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) - - unv_file = testtools.get_fem_test_tmp_dir() + '/tetra10_mesh.unv' - 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") - - 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.addEdge([1, 2]) - - inp_file = testtools.get_fem_test_tmp_dir() + '/seg2_mesh.inp' - seg2.writeABAQUS(inp_file, 1, False) - - read_file = open(inp_file, 'r') - read_node_line = 'line was not found' - for l in read_file: - l = l.strip() - if l.startswith('2, -5'): - read_node_line = l - read_file.close() - - # 1234567 12345678901234567890 12345678901234567890 - 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)) - def test_read_frd_massflow_networkpressure(self): # read data from frd file frd_file = testtools.get_fem_test_home_dir() + 'ccx/Flow1D_thermomech.frd' diff --git a/src/Mod/Fem/femtest/testmesh.py b/src/Mod/Fem/femtest/testmesh.py new file mode 100644 index 0000000000..ab3322522b --- /dev/null +++ b/src/Mod/Fem/femtest/testmesh.py @@ -0,0 +1,127 @@ +# *************************************************************************** +# * Copyright (c) 2018 - FreeCAD Developers * +# * Author: 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. * +# * * +# * FreeCAD 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 FreeCAD; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# ***************************************************************************/ + +import Fem +import FreeCAD +import unittest +from . import testtools +from .testtools import fcc_print + + +class FemMeshTest(unittest.TestCase): + + def setUp(self): + try: + FreeCAD.setActiveDocument("FemTest") + except: + FreeCAD.newDocument("FemTest") + finally: + FreeCAD.setActiveDocument("FemTest") + self.active_doc = FreeCAD.ActiveDocument + + def test_mesh_seg2_python(self): + seg2 = Fem.FemMesh() + seg2.addNode(0, 0, 0, 1) + seg2.addNode(2, 0, 0, 2) + seg2.addNode(4, 0, 0, 3) + 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)}] + 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") + + def test_mesh_seg3_python(self): + seg3 = Fem.FemMesh() + seg3.addNode(0, 0, 0, 1) + seg3.addNode(1, 0, 0, 2) + seg3.addNode(2, 0, 0, 3) + seg3.addNode(3, 0, 0, 4) + seg3.addNode(4, 0, 0, 5) + seg3.addEdge([1, 3, 2]) + 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])] + expected_nodes = [5, {1: FreeCAD.Vector(0.0, 0.0, 0.0), 2: FreeCAD.Vector(1.0, 0.0, 0.0), 3: FreeCAD.Vector(2.0, 0.0, 0.0), 4: FreeCAD.Vector(3.0, 0.0, 0.0), 5: FreeCAD.Vector(4.0, 0.0, 0.0)}] + 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") + + def test_unv_save_load(self): + tetra10 = Fem.FemMesh() + tetra10.addNode(6, 12, 18, 1) + tetra10.addNode(0, 0, 18, 2) + tetra10.addNode(12, 0, 18, 3) + tetra10.addNode(6, 6, 0, 4) + + tetra10.addNode(3, 6, 18, 5) + tetra10.addNode(6, 0, 18, 6) + tetra10.addNode(9, 6, 18, 7) + + tetra10.addNode(6, 9, 9, 8) + tetra10.addNode(3, 3, 9, 9) + tetra10.addNode(9, 3, 9, 10) + tetra10.addVolume([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) + + unv_file = testtools.get_fem_test_tmp_dir() + '/tetra10_mesh.unv' + 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") + + 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.addEdge([1, 2]) + + inp_file = testtools.get_fem_test_tmp_dir() + '/seg2_mesh.inp' + seg2.writeABAQUS(inp_file, 1, False) + + read_file = open(inp_file, 'r') + read_node_line = 'line was not found' + for l in read_file: + l = l.strip() + if l.startswith('2, -5'): + read_node_line = l + read_file.close() + + # 1234567 12345678901234567890 12345678901234567890 + 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)) + + def tearDown(self): + FreeCAD.closeDocument("FemTest") + pass