# *************************************************************************** # * Copyright (c) 2015 - FreeCAD Developers * # * Copyright (c) 2018 - 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 ObjectsFem import femsolver.run import unittest from . import utilstest as testtools from .utilstest import fcc_print class TestSolverFrameWork(unittest.TestCase): fcc_print('import TestSolverFrameWork') def setUp(self): self.doc_name = "TestSolverFrameWork" try: FreeCAD.setActiveDocument(self.doc_name) except: FreeCAD.newDocument(self.doc_name) finally: FreeCAD.setActiveDocument(self.doc_name) self.active_doc = FreeCAD.ActiveDocument self.mesh_name = 'Mesh' self.temp_dir = testtools.get_fem_test_tmp_dir() self.test_file_dir = testtools.get_fem_test_home_dir() + 'ccx/' 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') self.assertTrue(analysis, "FemTest of new analysis failed") fcc_print('Checking FEM new material...') material_object = ObjectsFem.makeMaterialSolid(self.active_doc, 'MechanicalMaterial') mat = material_object.Material mat['Name'] = "Steel-Generic" mat['YoungsModulus'] = "200000 MPa" mat['PoissonRatio'] = "0.30" mat['Density'] = "7900 kg/m^3" material_object.Material = mat self.assertTrue(material_object, "FemTest of new material failed") analysis.addObject(material_object) fcc_print('Checking FEM new fixed constraint...') 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.References = [(box, "Face6")] force_constraint.Force = 40000.0 force_constraint.Direction = (box, ["Edge5"]) self.active_doc.recompute() force_constraint.Reversed = True self.active_doc.recompute() self.assertTrue(force_constraint, "FemTest of new force constraint failed") analysis.addObject(force_constraint) fcc_print('Checking FEM new pressure constraint...') pressure_constraint = self.active_doc.addObject("Fem::ConstraintPressure", "FemConstraintPressure") pressure_constraint.References = [(box, "Face2")] pressure_constraint.Pressure = 1000.0 pressure_constraint.Reversed = False self.assertTrue(pressure_constraint, "FemTest of new pressure constraint failed") analysis.addObject(pressure_constraint) fcc_print('Checking FEM new mesh...') from .testfiles.ccx.cube_mesh import create_nodes_cube from .testfiles.ccx.cube_mesh import create_elements_cube mesh = Fem.FemMesh() ret = create_nodes_cube(mesh) 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.FemMesh = mesh self.assertTrue(mesh, "FemTest of new mesh failed") analysis.addObject(mesh_object) self.active_doc.recompute() # solver frame work ccx solver fcc_print('\nChecking FEM CalculiX solver for solver frame work...') solver_ccx_object = ObjectsFem.makeSolverCalculix(self.active_doc, 'SolverCalculiX') solver_ccx_object.AnalysisType = 'static' solver_ccx_object.GeometricalNonlinearity = 'linear' solver_ccx_object.ThermoMechSteadyState = False solver_ccx_object.MatrixSolverType = 'default' solver_ccx_object.IterationsControlParameterTimeUse = False solver_ccx_object.EigenmodesCount = 10 solver_ccx_object.EigenmodeHighLimit = 1000000.0 solver_ccx_object.EigenmodeLowLimit = 0.0 self.assertTrue(solver_ccx_object, "FemTest of new ccx solver failed") 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/') fcc_print('Checking FEM Elmer solver for solver frame work......') fcc_print('machine_ccx') machine_ccx = solver_ccx_object.Proxy.createMachine(solver_ccx_object, solverframework_analysis_dir) fcc_print('Machine testmode: ' + str(machine_ccx.testmode)) machine_ccx.target = femsolver.run.PREPARE machine_ccx.start() machine_ccx.join() # wait for the machine to finish. static_analysis_inp_file = testtools.get_fem_test_home_dir() + 'ccx/' + static_base_name + '.inp' fcc_print('Comparing {} to {}/{}.inp'.format(static_analysis_inp_file, solverframework_analysis_dir, self.mesh_name)) ret = testtools.compare_inp_files(static_analysis_inp_file, solverframework_analysis_dir + self.mesh_name + '.inp') self.assertFalse(ret, "ccxtools write_inp_file test failed.\n{}".format(ret)) # use solver frame work elmer solver 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) self.assertTrue(solver_elmer_eqobj, "FemTest of elmer elasticity equation failed") # 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 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 mesh_gmsh.Part = box analysis.addObject(mesh_gmsh) self.active_doc.removeObject(mesh_object.Name) # solver frame work Elmer solver fcc_print('\nChecking FEM Elmer solver for solver frame work...') machine_elmer = solver_elmer_object.Proxy.createMachine(solver_elmer_object, solverframework_analysis_dir, True) fcc_print('Machine testmode: ' + str(machine_elmer.testmode)) machine_elmer.target = femsolver.run.PREPARE machine_elmer.start() machine_elmer.join() # wait for the machine to finish. test_file_dir_elmer = testtools.get_fem_test_home_dir() + 'elmer/' fcc_print('Test writing STARTINFO file') fcc_print('Comparing {} to {}'.format(test_file_dir_elmer + 'ELMERSOLVER_STARTINFO', solverframework_analysis_dir + 'ELMERSOLVER_STARTINFO')) ret = testtools.compare_files(test_file_dir_elmer + 'ELMERSOLVER_STARTINFO', solverframework_analysis_dir + 'ELMERSOLVER_STARTINFO') self.assertFalse(ret, "STARTINFO write file test failed.\n{}".format(ret)) fcc_print('Test writing case file') fcc_print('Comparing {} to {}'.format(test_file_dir_elmer + 'case.sif', solverframework_analysis_dir + 'case.sif')) ret = testtools.compare_files(test_file_dir_elmer + 'case.sif', solverframework_analysis_dir + 'case.sif') self.assertFalse(ret, "case write file test failed.\n{}".format(ret)) fcc_print('Test writing GMSH geo file') fcc_print('Comparing {} to {}'.format(test_file_dir_elmer + 'group_mesh.geo', solverframework_analysis_dir + 'group_mesh.geo')) ret = testtools.compare_files(test_file_dir_elmer + 'group_mesh.geo', solverframework_analysis_dir + 'group_mesh.geo') self.assertFalse(ret, "GMSH geo write file test failed.\n{}".format(ret)) save_fc_file = solverframework_analysis_dir + static_base_name + '.FCStd' fcc_print('Save FreeCAD file for static2 analysis to {}...'.format(save_fc_file)) self.active_doc.saveAs(save_fc_file) fcc_print('--------------- End of FEM tests solver frame work ---------------') def tearDown(self): FreeCAD.closeDocument(self.doc_name) pass