From e7bd900a9410f175423a5673b069e25ff6ed2d69 Mon Sep 17 00:00:00 2001 From: Bernd Hahnebach Date: Wed, 25 Sep 2019 18:07:05 +0200 Subject: [PATCH] FEM: move setup multimaterial example from unit tests to fem examples --- src/Mod/Fem/CMakeLists.txt | 1 + .../Fem/femexamples/multimaterial_twoboxes.py | 168 ++++++++++++++++++ src/Mod/Fem/femtest/app/test_ccxtools.py | 103 +---------- 3 files changed, 174 insertions(+), 98 deletions(-) create mode 100644 src/Mod/Fem/femexamples/multimaterial_twoboxes.py diff --git a/src/Mod/Fem/CMakeLists.txt b/src/Mod/Fem/CMakeLists.txt index 22c96868cb..72e0d91d2d 100755 --- a/src/Mod/Fem/CMakeLists.txt +++ b/src/Mod/Fem/CMakeLists.txt @@ -37,6 +37,7 @@ SET(FemExamples_SRCS femexamples/__init__.py femexamples/ccx_cantilever_std.py femexamples/manager.py + femexamples/multimaterial_twoboxes.py femexamples/rc_wall_2d.py femexamples/thermomech_spine.py ) diff --git a/src/Mod/Fem/femexamples/multimaterial_twoboxes.py b/src/Mod/Fem/femexamples/multimaterial_twoboxes.py new file mode 100644 index 0000000000..512840ba1a --- /dev/null +++ b/src/Mod/Fem/femexamples/multimaterial_twoboxes.py @@ -0,0 +1,168 @@ +# *************************************************************************** +# * Copyright (c) 2019 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 FreeCAD +import ObjectsFem +import Fem + +mesh_name = "Mesh" # needs to be Mesh to work with unit tests + + +def init_doc(doc=None): + if doc is None: + doc = FreeCAD.newDocument() + return doc + + +def setup(doc=None, solver="ccxtools"): + # setup model + + if doc is None: + doc = init_doc() + + # part + # create a CompSolid of two Boxes extract the CompSolid + # we are able to remesh if needed + boxlow = doc.addObject("Part::Box", "BoxLower") + boxupp = doc.addObject("Part::Box", "BoxUpper") + boxupp.Placement.Base = (0, 0, 10) + + # for BooleanFragments Occt >=6.9 is needed + """ + import BOPTools.SplitFeatures + bf = BOPTools.SplitFeatures.makeBooleanFragments(name="BooleanFragments") + bf.Objects = [boxlow, boxupp] + bf.Mode = "CompSolid" + self.active_doc.recompute() + bf.Proxy.execute(bf) + bf.purgeTouched() + for obj in bf.ViewObject.Proxy.claimChildren(): + obj.ViewObject.hide() + self.active_doc.recompute() + import CompoundTools.CompoundFilter + cf = CompoundTools.CompoundFilter.makeCompoundFilter(name="MultiMatCompSolid") + cf.Base = bf + cf.FilterType = "window-volume" + cf.Proxy.execute(cf) + cf.purgeTouched() + cf.Base.ViewObject.hide() + """ + doc.recompute() + + if FreeCAD.GuiUp: + import FreeCADGui + FreeCADGui.ActiveDocument.activeView().viewAxonometric() + FreeCADGui.SendMsgToActiveView("ViewFit") + + # analysis + analysis = ObjectsFem.makeAnalysis(doc, "Analysis") + + # solver + # TODO How to pass multiple solver for one analysis in one doc + if solver == "calculix": + solver_object = analysis.addObject( + ObjectsFem.makeSolverCalculix(doc, "SolverCalculiX") + )[0] + solver_object.AnalysisType = "static" + solver_object.GeometricalNonlinearity = "linear" + solver_object.ThermoMechSteadyState = False + solver_object.MatrixSolverType = "default" + solver_object.IterationsControlParameterTimeUse = False + elif solver == "ccxtools": + solver_object = analysis.addObject( + ObjectsFem.makeSolverCalculixCcxTools(doc, "CalculiXccxTools") + )[0] + solver_object.AnalysisType = "static" + solver_object.GeometricalNonlinearity = "linear" + solver_object.ThermoMechSteadyState = False + solver_object.MatrixSolverType = "default" + solver_object.IterationsControlParameterTimeUse = False + solver_object.WorkingDir = u"" + + # material + material_object_low = analysis.addObject( + ObjectsFem.makeMaterialSolid(doc, "MechanicalMaterialLow") + )[0] + mat = material_object_low.Material + mat["Name"] = "Aluminium-Generic" + mat["YoungsModulus"] = "70000 MPa" + mat["PoissonRatio"] = "0.35" + mat["Density"] = "2700 kg/m^3" + material_object_low.Material = mat + material_object_low.References = [(boxlow, "Solid1")] + analysis.addObject(material_object_low) + + material_object_upp = analysis.addObject( + ObjectsFem.makeMaterialSolid(doc, "MechanicalMaterialUpp") + )[0] + mat = material_object_upp.Material + mat["Name"] = "Steel-Generic" + mat["YoungsModulus"] = "200000 MPa" + mat["PoissonRatio"] = "0.30" + mat["Density"] = "7980 kg/m^3" + material_object_upp.Material = mat + material_object_upp.References = [(boxupp, "Solid1")] + + # fixed_constraint + fixed_constraint = analysis.addObject( + ObjectsFem.makeConstraintFixed(doc, "ConstraintFixed") + )[0] + # fixed_constraint.References = [(cf, "Face3")] + fixed_constraint.References = [(boxlow, "Face5")] + + # pressure_constraint + pressure_constraint = analysis.addObject( + ObjectsFem.makeConstraintPressure(doc, "ConstraintPressure") + )[0] + # pressure_constraint.References = [(cf, "Face3")] + pressure_constraint.References = [(boxlow, "Face5")] + # pressure_constraint.References = [(cf, "Face9")] + pressure_constraint.References = [(boxupp, "Face6")] + pressure_constraint.Pressure = 1000.0 + pressure_constraint.Reversed = False + + # mesh + # from femexamples.meshes.mesh_thermomech_spine import create_nodes, create_elements + from femtest.data.ccx.multimat_mesh import create_nodes, create_elements + fem_mesh = Fem.FemMesh() + control = create_nodes(fem_mesh) + if not control: + FreeCAD.Console.PrintError("Error on creating nodes.\n") + control = create_elements(fem_mesh) + if not control: + FreeCAD.Console.PrintError("Error on creating elements.\n") + femmesh_obj = analysis.addObject( + doc.addObject("Fem::FemMeshObject", mesh_name) + )[0] + femmesh_obj.FemMesh = fem_mesh + + doc.recompute() + return doc + + +""" +from femexamples import multimaterial_simple as multimat +multimat.setup() + +""" diff --git a/src/Mod/Fem/femtest/app/test_ccxtools.py b/src/Mod/Fem/femtest/app/test_ccxtools.py index b4ba31f0b2..a1ac100e87 100644 --- a/src/Mod/Fem/femtest/app/test_ccxtools.py +++ b/src/Mod/Fem/femtest/app/test_ccxtools.py @@ -288,106 +288,13 @@ class TestCcxTools(unittest.TestCase): ): fcc_print("--------------- Start of FEM ccxtools multiple material test ---------------") - # create a CompSolid of two Boxes extract the CompSolid - # we are able to remesh if needed - boxlow = self.active_doc.addObject("Part::Box", "BoxLower") - boxupp = self.active_doc.addObject("Part::Box", "BoxUpper") - boxupp.Placement.Base = (0, 0, 10) + # set up the simple multimat example + from femexamples import multimaterial_twoboxes + multimaterial_twoboxes.setup(self.active_doc, "ccxtools") - # for BooleanFragments Occt >=6.9 is needed - """ - import BOPTools.SplitFeatures - bf = BOPTools.SplitFeatures.makeBooleanFragments(name="BooleanFragments") - bf.Objects = [boxlow, boxupp] - bf.Mode = "CompSolid" - self.active_doc.recompute() - bf.Proxy.execute(bf) - bf.purgeTouched() - for obj in bf.ViewObject.Proxy.claimChildren(): - obj.ViewObject.hide() - self.active_doc.recompute() - import CompoundTools.CompoundFilter - cf = CompoundTools.CompoundFilter.makeCompoundFilter(name="MultiMatCompSolid") - cf.Base = bf - cf.FilterType = "window-volume" - cf.Proxy.execute(cf) - cf.purgeTouched() - cf.Base.ViewObject.hide() - """ - self.active_doc.recompute() - if FreeCAD.GuiUp: - import FreeCADGui - FreeCADGui.ActiveDocument.activeView().viewAxonometric() - FreeCADGui.SendMsgToActiveView("ViewFit") + analysis = self.active_doc.Analysis + solver_object = self.active_doc.CalculiXccxTools - analysis = ObjectsFem.makeAnalysis( - self.active_doc, - "Analysis" - ) - solver_object = ObjectsFem.makeSolverCalculixCcxTools( - self.active_doc, - "CalculiXccxTools" - ) - solver_object.AnalysisType = "static" - solver_object.GeometricalNonlinearity = "linear" - solver_object.ThermoMechSteadyState = False - solver_object.MatrixSolverType = "default" - solver_object.IterationsControlParameterTimeUse = False - analysis.addObject(solver_object) - - material_object_low = ObjectsFem.makeMaterialSolid( - self.active_doc, - "MechanicalMaterialLow" - ) - mat = material_object_low.Material - mat["Name"] = "Aluminium-Generic" - mat["YoungsModulus"] = "70000 MPa" - mat["PoissonRatio"] = "0.35" - mat["Density"] = "2700 kg/m^3" - material_object_low.Material = mat - material_object_low.References = [(boxlow, "Solid1")] - analysis.addObject(material_object_low) - - material_object_upp = ObjectsFem.makeMaterialSolid( - self.active_doc, - "MechanicalMaterialUpp" - ) - mat = material_object_upp.Material - mat["Name"] = "Steel-Generic" - mat["YoungsModulus"] = "200000 MPa" - mat["PoissonRatio"] = "0.30" - mat["Density"] = "7980 kg/m^3" - material_object_upp.Material = mat - material_object_upp.References = [(boxupp, "Solid1")] - analysis.addObject(material_object_upp) - - fixed_constraint = self.active_doc.addObject( - "Fem::ConstraintFixed", - "ConstraintFixed" - ) - # fixed_constraint.References = [(cf, "Face3")] - fixed_constraint.References = [(boxlow, "Face5")] - analysis.addObject(fixed_constraint) - - pressure_constraint = self.active_doc.addObject( - "Fem::ConstraintPressure", - "ConstraintPressure" - ) - # pressure_constraint.References = [(cf, "Face9")] - pressure_constraint.References = [(boxupp, "Face6")] - pressure_constraint.Pressure = 1000.0 - pressure_constraint.Reversed = False - analysis.addObject(pressure_constraint) - - mesh = Fem.FemMesh() - import femtest.data.ccx.multimat_mesh as multimatmesh - multimatmesh.create_nodes(mesh) - multimatmesh.create_elements(mesh) - mesh_object = self.active_doc.addObject("Fem::FemMeshObject", self.mesh_name) - mesh_object.FemMesh = mesh - analysis.addObject(mesh_object) - - self.active_doc.recompute() static_multiplemat_dir = testtools.get_unit_test_tmp_dir( self.temp_dir, "FEM_ccx_multimat/"