diff --git a/src/Mod/Fem/CMakeLists.txt b/src/Mod/Fem/CMakeLists.txt index 6ed260d2df..a5e4be1ef7 100755 --- a/src/Mod/Fem/CMakeLists.txt +++ b/src/Mod/Fem/CMakeLists.txt @@ -77,6 +77,7 @@ SET(FemExamples_SRCS femexamples/elmer_nonguitutorial01_eigenvalue_of_elastic_beam.py femexamples/equation_electrostatics_capacitance_two_balls.py femexamples/equation_electrostatics_electricforce_elmer_nongui6.py + femexamples/equation_flow_elmer_2D.py femexamples/frequency_beamsimple.py femexamples/manager.py femexamples/material_multiple_bendingbeam_fiveboxes.py diff --git a/src/Mod/Fem/femexamples/boxanalysis_frequency.py b/src/Mod/Fem/femexamples/boxanalysis_frequency.py index a12065cd15..0e8ee1c924 100644 --- a/src/Mod/Fem/femexamples/boxanalysis_frequency.py +++ b/src/Mod/Fem/femexamples/boxanalysis_frequency.py @@ -37,7 +37,7 @@ def get_information(): "constraints": [], "solvers": ["calculix", "ccxtools"], "material": "solid", - "equation": "frequency" + "equations": ["frequency"] } diff --git a/src/Mod/Fem/femexamples/boxanalysis_static.py b/src/Mod/Fem/femexamples/boxanalysis_static.py index 95bfb07311..e059e7651d 100644 --- a/src/Mod/Fem/femexamples/boxanalysis_static.py +++ b/src/Mod/Fem/femexamples/boxanalysis_static.py @@ -39,7 +39,7 @@ def get_information(): "constraints": ["fixed", "force", "pressure"], "solvers": ["calculix", "ccxtools", "elmer"], "material": "solid", - "equation": "mechanical" + "equations": ["mechanical"] } diff --git a/src/Mod/Fem/femexamples/buckling_lateraltorsionalbuckling.py b/src/Mod/Fem/femexamples/buckling_lateraltorsionalbuckling.py index 06dcb8b3f7..3b6718dd6c 100644 --- a/src/Mod/Fem/femexamples/buckling_lateraltorsionalbuckling.py +++ b/src/Mod/Fem/femexamples/buckling_lateraltorsionalbuckling.py @@ -39,7 +39,7 @@ def get_information(): "constraints": ["displacement", "force"], "solvers": ["calculix", "ccxtools"], "material": "solid", - "equation": "buckling" + "equations": ["buckling"] } diff --git a/src/Mod/Fem/femexamples/buckling_platebuckling.py b/src/Mod/Fem/femexamples/buckling_platebuckling.py index 71917f99c0..f33349146c 100644 --- a/src/Mod/Fem/femexamples/buckling_platebuckling.py +++ b/src/Mod/Fem/femexamples/buckling_platebuckling.py @@ -39,7 +39,7 @@ def get_information(): "constraints": ["displacement", "force"], "solvers": ["calculix", "ccxtools"], "material": "solid", - "equation": "buckling" + "equations": ["buckling"] } diff --git a/src/Mod/Fem/femexamples/ccx_buckling_flexuralbuckling.py b/src/Mod/Fem/femexamples/ccx_buckling_flexuralbuckling.py index b4a75cf3f8..fd726498ce 100644 --- a/src/Mod/Fem/femexamples/ccx_buckling_flexuralbuckling.py +++ b/src/Mod/Fem/femexamples/ccx_buckling_flexuralbuckling.py @@ -40,7 +40,7 @@ def get_information(): "constraints": ["fixed", "force"], "solvers": ["calculix", "ccxtools"], "material": "solid", - "equation": "buckling" + "equations": ["buckling"] } diff --git a/src/Mod/Fem/femexamples/ccx_cantilever_beam_circle.py b/src/Mod/Fem/femexamples/ccx_cantilever_beam_circle.py index a32273d4ac..7adf75aeca 100644 --- a/src/Mod/Fem/femexamples/ccx_cantilever_beam_circle.py +++ b/src/Mod/Fem/femexamples/ccx_cantilever_beam_circle.py @@ -36,7 +36,7 @@ def get_information(): "constraints": ["fixed", "force"], "solvers": ["calculix", "ccxtools"], "material": "solid", - "equation": "mechanical" + "equations": ["mechanical"] } diff --git a/src/Mod/Fem/femexamples/ccx_cantilever_beam_pipe.py b/src/Mod/Fem/femexamples/ccx_cantilever_beam_pipe.py index 46fbe8c726..1dbcc84106 100644 --- a/src/Mod/Fem/femexamples/ccx_cantilever_beam_pipe.py +++ b/src/Mod/Fem/femexamples/ccx_cantilever_beam_pipe.py @@ -36,7 +36,7 @@ def get_information(): "constraints": ["fixed", "force"], "solvers": ["calculix", "ccxtools"], "material": "solid", - "equation": "mechanical" + "equations": ["mechanical"] } diff --git a/src/Mod/Fem/femexamples/ccx_cantilever_beam_rect.py b/src/Mod/Fem/femexamples/ccx_cantilever_beam_rect.py index 577a9fae50..f4a21255de 100644 --- a/src/Mod/Fem/femexamples/ccx_cantilever_beam_rect.py +++ b/src/Mod/Fem/femexamples/ccx_cantilever_beam_rect.py @@ -36,7 +36,7 @@ def get_information(): "constraints": ["fixed", "force"], "solvers": ["calculix", "ccxtools"], "material": "solid", - "equation": "mechanical" + "equations": ["mechanical"] } diff --git a/src/Mod/Fem/femexamples/ccx_cantilever_ele_hexa20.py b/src/Mod/Fem/femexamples/ccx_cantilever_ele_hexa20.py index 87f8d3ed7e..96ef4929e2 100644 --- a/src/Mod/Fem/femexamples/ccx_cantilever_ele_hexa20.py +++ b/src/Mod/Fem/femexamples/ccx_cantilever_ele_hexa20.py @@ -40,7 +40,7 @@ def get_information(): "constraints": ["fixed", "force"], "solvers": ["calculix", "ccxtools", "elmer", "z88"], "material": "solid", - "equation": "mechanical" + "equations": ["mechanical"] } diff --git a/src/Mod/Fem/femexamples/ccx_cantilever_ele_quad4.py b/src/Mod/Fem/femexamples/ccx_cantilever_ele_quad4.py index 42bcd33fce..6052f11a94 100644 --- a/src/Mod/Fem/femexamples/ccx_cantilever_ele_quad4.py +++ b/src/Mod/Fem/femexamples/ccx_cantilever_ele_quad4.py @@ -39,7 +39,7 @@ def get_information(): "constraints": ["fixed", "force"], "solvers": ["calculix", "ccxtools", "mystran"], "material": "solid", - "equation": "mechanical" + "equations": ["mechanical"] } diff --git a/src/Mod/Fem/femexamples/ccx_cantilever_ele_quad8.py b/src/Mod/Fem/femexamples/ccx_cantilever_ele_quad8.py index 11ce8d0e3f..3e9fe96b90 100644 --- a/src/Mod/Fem/femexamples/ccx_cantilever_ele_quad8.py +++ b/src/Mod/Fem/femexamples/ccx_cantilever_ele_quad8.py @@ -39,7 +39,7 @@ def get_information(): "constraints": ["fixed", "force"], "solvers": ["calculix", "ccxtools"], "material": "solid", - "equation": "mechanical" + "equations": ["mechanical"] } diff --git a/src/Mod/Fem/femexamples/ccx_cantilever_ele_seg2.py b/src/Mod/Fem/femexamples/ccx_cantilever_ele_seg2.py index b8d30bcc99..eb5997b81b 100644 --- a/src/Mod/Fem/femexamples/ccx_cantilever_ele_seg2.py +++ b/src/Mod/Fem/femexamples/ccx_cantilever_ele_seg2.py @@ -39,7 +39,7 @@ def get_information(): "constraints": ["fixed", "force"], "solvers": ["calculix", "ccxtools", "mystran"], "material": "solid", - "equation": "mechanical" + "equations": ["mechanical"] } diff --git a/src/Mod/Fem/femexamples/ccx_cantilever_ele_seg3.py b/src/Mod/Fem/femexamples/ccx_cantilever_ele_seg3.py index 3f2d86da31..54432dc1de 100644 --- a/src/Mod/Fem/femexamples/ccx_cantilever_ele_seg3.py +++ b/src/Mod/Fem/femexamples/ccx_cantilever_ele_seg3.py @@ -34,7 +34,7 @@ def get_information(): "constraints": ["fixed", "force"], "solvers": ["calculix", "ccxtools"], "material": "solid", - "equation": "mechanical" + "equations": ["mechanical"] } diff --git a/src/Mod/Fem/femexamples/ccx_cantilever_ele_tetra4.py b/src/Mod/Fem/femexamples/ccx_cantilever_ele_tetra4.py index 42c33b54f6..217a67f567 100644 --- a/src/Mod/Fem/femexamples/ccx_cantilever_ele_tetra4.py +++ b/src/Mod/Fem/femexamples/ccx_cantilever_ele_tetra4.py @@ -38,7 +38,7 @@ def get_information(): "constraints": ["fixed", "force"], "solvers": ["calculix", "ccxtools", "elmer", "mystran", "z88"], "material": "solid", - "equation": "mechanical" + "equations": ["mechanical"] } diff --git a/src/Mod/Fem/femexamples/ccx_cantilever_ele_tria3.py b/src/Mod/Fem/femexamples/ccx_cantilever_ele_tria3.py index a16c752a1c..c943ec14de 100644 --- a/src/Mod/Fem/femexamples/ccx_cantilever_ele_tria3.py +++ b/src/Mod/Fem/femexamples/ccx_cantilever_ele_tria3.py @@ -39,7 +39,7 @@ def get_information(): "constraints": ["fixed", "force"], "solvers": ["calculix", "ccxtools", "mystran"], "material": "solid", - "equation": "mechanical" + "equations": ["mechanical"] } diff --git a/src/Mod/Fem/femexamples/ccx_cantilever_ele_tria6.py b/src/Mod/Fem/femexamples/ccx_cantilever_ele_tria6.py index 6423bdf782..5f92f28251 100644 --- a/src/Mod/Fem/femexamples/ccx_cantilever_ele_tria6.py +++ b/src/Mod/Fem/femexamples/ccx_cantilever_ele_tria6.py @@ -34,7 +34,7 @@ def get_information(): "constraints": ["fixed", "force"], "solvers": ["calculix", "ccxtools", "z88"], "material": "solid", - "equation": "mechanical" + "equations": ["mechanical"] } diff --git a/src/Mod/Fem/femexamples/ccx_cantilever_faceload.py b/src/Mod/Fem/femexamples/ccx_cantilever_faceload.py index 4b8bf5e81d..6216385c89 100644 --- a/src/Mod/Fem/femexamples/ccx_cantilever_faceload.py +++ b/src/Mod/Fem/femexamples/ccx_cantilever_faceload.py @@ -37,7 +37,7 @@ def get_information(): "constraints": ["fixed", "force"], "solvers": ["calculix", "ccxtools", "elmer", "mystran", "z88"], "material": "solid", - "equation": "mechanical" + "equations": ["mechanical"] } diff --git a/src/Mod/Fem/femexamples/ccx_cantilever_nodeload.py b/src/Mod/Fem/femexamples/ccx_cantilever_nodeload.py index d88066d88f..6de1a9b0ac 100644 --- a/src/Mod/Fem/femexamples/ccx_cantilever_nodeload.py +++ b/src/Mod/Fem/femexamples/ccx_cantilever_nodeload.py @@ -37,7 +37,7 @@ def get_information(): "constraints": ["fixed", "force"], "solvers": ["calculix", "ccxtools", "elmer", "mystran", "z88"], "material": "solid", - "equation": "mechanical" + "equations": ["mechanical"] } diff --git a/src/Mod/Fem/femexamples/ccx_cantilever_prescribeddisplacement.py b/src/Mod/Fem/femexamples/ccx_cantilever_prescribeddisplacement.py index 6dd8a8586f..0d6e5a18d4 100644 --- a/src/Mod/Fem/femexamples/ccx_cantilever_prescribeddisplacement.py +++ b/src/Mod/Fem/femexamples/ccx_cantilever_prescribeddisplacement.py @@ -37,7 +37,7 @@ def get_information(): "constraints": ["fixed", "displacement"], "solvers": ["calculix", "ccxtools", "elmer"], "material": "solid", - "equation": "mechanical" + "equations": ["mechanical"] } diff --git a/src/Mod/Fem/femexamples/constraint_centrif.py b/src/Mod/Fem/femexamples/constraint_centrif.py index 44ab08280b..3404779f08 100644 --- a/src/Mod/Fem/femexamples/constraint_centrif.py +++ b/src/Mod/Fem/femexamples/constraint_centrif.py @@ -44,7 +44,7 @@ def get_information(): "constraints": ["centrif", "fixed"], "solvers": ["calculix", "ccxtools"], "material": "multimaterial", - "equation": "mechanical" + "equations": ["mechanical"] } diff --git a/src/Mod/Fem/femexamples/constraint_contact_shell_shell.py b/src/Mod/Fem/femexamples/constraint_contact_shell_shell.py index 259fe26194..53bac467fa 100644 --- a/src/Mod/Fem/femexamples/constraint_contact_shell_shell.py +++ b/src/Mod/Fem/femexamples/constraint_contact_shell_shell.py @@ -43,7 +43,7 @@ def get_information(): "constraints": ["fixed", "force", "contact"], "solvers": ["calculix", "ccxtools"], "material": "solid", - "equation": "mechanical" + "equations": ["mechanical"] } diff --git a/src/Mod/Fem/femexamples/constraint_contact_solid_solid.py b/src/Mod/Fem/femexamples/constraint_contact_solid_solid.py index a914ecd468..e235313417 100644 --- a/src/Mod/Fem/femexamples/constraint_contact_solid_solid.py +++ b/src/Mod/Fem/femexamples/constraint_contact_solid_solid.py @@ -44,7 +44,7 @@ def get_information(): "constraints": ["fixed", "pressure", "contact"], "solvers": ["calculix", "ccxtools"], "material": "solid", - "equation": "mechanical" + "equations": ["mechanical"] } diff --git a/src/Mod/Fem/femexamples/constraint_section_print.py b/src/Mod/Fem/femexamples/constraint_section_print.py index 92979181f6..abd7ad8e9d 100644 --- a/src/Mod/Fem/femexamples/constraint_section_print.py +++ b/src/Mod/Fem/femexamples/constraint_section_print.py @@ -50,7 +50,7 @@ def get_information(): "constraints": ["section_print", "fixed", "pressure"], "solvers": ["calculix", "ccxtools"], "material": "solid", - "equation": "mechanical" + "equations": ["mechanical"] } diff --git a/src/Mod/Fem/femexamples/constraint_selfweight_cantilever.py b/src/Mod/Fem/femexamples/constraint_selfweight_cantilever.py index a6c1074e67..6d116f0704 100644 --- a/src/Mod/Fem/femexamples/constraint_selfweight_cantilever.py +++ b/src/Mod/Fem/femexamples/constraint_selfweight_cantilever.py @@ -39,7 +39,7 @@ def get_information(): "constraints": ["fixed", "self weight"], "solvers": ["calculix", "ccxtools", "elmer"], "material": "solid", - "equation": "mechanical" + "equations": ["mechanical"] } diff --git a/src/Mod/Fem/femexamples/constraint_tie.py b/src/Mod/Fem/femexamples/constraint_tie.py index f476771101..6f896644ae 100644 --- a/src/Mod/Fem/femexamples/constraint_tie.py +++ b/src/Mod/Fem/femexamples/constraint_tie.py @@ -44,7 +44,7 @@ def get_information(): "constraints": ["fixed", "force", "tie"], "solvers": ["calculix", "ccxtools"], "material": "solid", - "equation": "mechanical" + "equations": ["mechanical"] } diff --git a/src/Mod/Fem/femexamples/constraint_transform_beam_hinged.py b/src/Mod/Fem/femexamples/constraint_transform_beam_hinged.py index bb6e326c06..5d9c842fb9 100644 --- a/src/Mod/Fem/femexamples/constraint_transform_beam_hinged.py +++ b/src/Mod/Fem/femexamples/constraint_transform_beam_hinged.py @@ -44,7 +44,7 @@ def get_information(): "constraints": ["pressure", "displacement", "transform"], "solvers": ["calculix", "ccxtools"], "material": "solid", - "equation": "mechanical" + "equations": ["mechanical"] } diff --git a/src/Mod/Fem/femexamples/constraint_transform_torque.py b/src/Mod/Fem/femexamples/constraint_transform_torque.py index f11de2dc99..a38d5fa903 100644 --- a/src/Mod/Fem/femexamples/constraint_transform_torque.py +++ b/src/Mod/Fem/femexamples/constraint_transform_torque.py @@ -52,7 +52,7 @@ def get_information(): "constraints": ["fixed", "force", "transform"], "solvers": ["calculix", "ccxtools"], "material": "solid", - "equation": "mechanical" + "equations": ["mechanical"] } diff --git a/src/Mod/Fem/femexamples/elmer_nonguitutorial01_eigenvalue_of_elastic_beam.py b/src/Mod/Fem/femexamples/elmer_nonguitutorial01_eigenvalue_of_elastic_beam.py index 884998f4f1..c22094a9ab 100644 --- a/src/Mod/Fem/femexamples/elmer_nonguitutorial01_eigenvalue_of_elastic_beam.py +++ b/src/Mod/Fem/femexamples/elmer_nonguitutorial01_eigenvalue_of_elastic_beam.py @@ -39,7 +39,7 @@ def get_information(): "constraints": [], "solvers": ["calculix", "ccxtools", "elmer"], "material": "solid", - "equation": "elasticity" # "frequency", but list not allowed here + "equations": ["elasticity"] # "frequency", but list not allowed here } diff --git a/src/Mod/Fem/femexamples/equation_electrostatics_capacitance_two_balls.py b/src/Mod/Fem/femexamples/equation_electrostatics_capacitance_two_balls.py index e501e725e6..1fd20ff401 100644 --- a/src/Mod/Fem/femexamples/equation_electrostatics_capacitance_two_balls.py +++ b/src/Mod/Fem/femexamples/equation_electrostatics_capacitance_two_balls.py @@ -42,7 +42,7 @@ def get_information(): "constraints": ["electrostatic potential"], "solvers": ["elmer"], "material": "fluid", - "equation": "electrostatic" + "equations": ["electrostatic"] } def get_explanation(header=""): diff --git a/src/Mod/Fem/femexamples/equation_electrostatics_electricforce_elmer_nongui6.py b/src/Mod/Fem/femexamples/equation_electrostatics_electricforce_elmer_nongui6.py index e7682473ae..038397b248 100644 --- a/src/Mod/Fem/femexamples/equation_electrostatics_electricforce_elmer_nongui6.py +++ b/src/Mod/Fem/femexamples/equation_electrostatics_electricforce_elmer_nongui6.py @@ -45,7 +45,7 @@ def get_information(): "constraints": ["electrostatic potential"], "solvers": ["elmer"], "material": "fluid", - "equation": "electrostatic" + "equations": ["electrostatic"] } def get_explanation(header=""): diff --git a/src/Mod/Fem/femexamples/equation_flow_elmer_2D.py b/src/Mod/Fem/femexamples/equation_flow_elmer_2D.py new file mode 100644 index 0000000000..b7dba8c029 --- /dev/null +++ b/src/Mod/Fem/femexamples/equation_flow_elmer_2D.py @@ -0,0 +1,280 @@ +# *************************************************************************** +# * Copyright (c) 2023 Uwe Stöhr * +# * * +# * 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 sys +import FreeCAD +from FreeCAD import Placement +from FreeCAD import Rotation +from FreeCAD import Vector + +import Draft +import ObjectsFem + +from BOPTools import SplitFeatures +from . import manager +from .manager import get_meshname +from .manager import init_doc + +def get_information(): + return { + "name": "Flow - Elmer 2D", + "meshtype": "solid", + "meshelement": "Tet10", + "constraints": ["initial pressure", "initial velocity", + "velocity", "initial temperature", "temperature"], + "solvers": ["elmer"], + "material": "fluid", + "equations": ["flow", "heat"] + } + +def get_explanation(header=""): + return header + """ + +To run the example from Python console use: +from femexamples.equation_flow_elmer_2D import setup +setup() + +Flow and Heat equation in FreeCAD FEM-Elmer + +""" + +def setup(doc=None, solvertype="elmer"): + + # 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()))) + + # geometric objects + + # the wire defining the pipe volume in 2D + p1 = Vector(400, 0, -50.000) + p2 = Vector(400, 0, -150.000) + p3 = Vector(1200, 0, -150.000) + p4 = Vector(1200, 0, 50.000) + p5 = Vector(0, 0, 50.000) + p6 = Vector(0, 0, -50.000) + wire = Draft.make_wire([p1, p2, p3, p4, p5, p6], closed=True) + wire.Label = "Wire" + + # the circle defining the heating rod + pCirc = Vector(160, 0, 0) + axisCirc = Vector(1, 0, 0) + placementCircle = Placement(pCirc, Rotation(axisCirc, 90)) + circle = Draft.make_circle(10, placement=placementCircle) + circle.Label = "HeatingRod" + circle.ViewObject.Visibility = False + + # a link of the circle + circleLink = doc.addObject("App::Link", "Link-HeatingRod") + circleLink.LinkTransform = True + circleLink.LinkedObject = circle + + # cut rod from wire to get volume of fluid + cut = doc.addObject("Part::Cut", "Cut") + cut.Base = wire + cut.Tool = circleLink + cut.ViewObject.Visibility = False + + # BooleanFregments object to combine cut with rod + BooleanFragments = SplitFeatures.makeBooleanFragments(name="BooleanFragments") + BooleanFragments.Objects = [cut, circle] + + # set view + doc.recompute() + if FreeCAD.GuiUp: + BooleanFragments.ViewObject.Transparency = 50 + BooleanFragments.ViewObject.Document.activeView().viewFront() + BooleanFragments.ViewObject.Document.activeView().fitAll() + + # analysis + analysis = ObjectsFem.makeAnalysis(doc, "Analysis") + if FreeCAD.GuiUp: + import FemGui + FemGui.setActiveAnalysis(analysis) + + # solver + if solvertype == "elmer": + solver_obj = ObjectsFem.makeSolverElmer(doc, "SolverElmer") + solver_flow = ObjectsFem.makeEquationFlow(doc, solver_obj) + solver_heat = ObjectsFem.makeEquationHeat(doc, solver_obj) + else: + FreeCAD.Console.PrintWarning( + "Not known or not supported solver type: {}. " + "No solver object was created.\n".format(solvertype) + ) + return doc + analysis.addObject(solver_obj) + + # solver settings + solver_flow.Priority = 10 + solver_flow.IdrsParameter = 3 + solver_flow.LinearIterativeMethod = "Idrs" + solver_flow.LinearPreconditioning = "ILU1" + solver_heat.Priority = 20 + solver_heat.IdrsParameter = 3 + solver_heat.LinearIterativeMethod = "Idrs" + solver_heat.LinearPreconditioning = "ILU1" + solver_heat.RelaxationFactor = 0.9 + + # material + material_obj = ObjectsFem.makeMaterialFluid(doc, "Material_Fluid") + mat = material_obj.Material + mat["Name"] = "Air" + mat["Density"] = "1.204 kg/m^3" + mat["KinematicViscosity"] = "15.11 mm^2/s" + mat["VolumetricThermalExpansionCoefficient"] = "0.00 mm/m/K" + mat["ThermalConductivity"] = "0.02587 W/m/K" + mat["ThermalExpansionCoefficient"] = "0.00343/K" + mat["SpecificHeat"] = "1010.00 J/kg/K" + mat["RelativePermittivity"] = "1.00059" + material_obj.Material = mat + material_obj.References = [(BooleanFragments, "Face2")] + analysis.addObject(material_obj) + + material_obj = ObjectsFem.makeMaterialSolid(doc, "Material_Wall") + mat = material_obj.Material + mat["Name"] = "Aluminum-Generic" + mat["Density"] = "2700.0 kg/m^3" + mat["PoissonRatio"] = "0.35" + mat["ShearModulus"] = "25.0 GPa" + mat["UltimateTensileStrength"] = "310 MPa" + mat["YoungsModulus"] = "70000 MPa" + mat["ThermalConductivity"] = "237 W/m/K" + mat["ThermalExpansionCoefficient"] = "23.1 µm/m/K" + mat["SpecificHeat"] = "897.00 J/kg/K" + material_obj.Material = mat + material_obj.References = [(BooleanFragments, "Face1")] + analysis.addObject(material_obj) + + # constraint inlet velocity + FlowVelocity_Inlet = ObjectsFem.makeConstraintFlowVelocity(doc, "FlowVelocity_Inlet") + FlowVelocity_Inlet.References = [(BooleanFragments, "Edge5")] + FlowVelocity_Inlet.NormalDirection = Vector(-1, 0, 0) + FlowVelocity_Inlet.VelocityX = 0.020 + FlowVelocity_Inlet.VelocityXEnabled = True + FlowVelocity_Inlet.VelocityYEnabled = True + FlowVelocity_Inlet.VelocityZEnabled = True + analysis.addObject(FlowVelocity_Inlet) + + # constraint outlet velocity + FlowVelocity_Outlet = ObjectsFem.makeConstraintFlowVelocity(doc, "FlowVelocity_Outlet") + FlowVelocity_Outlet.References = [(BooleanFragments, "Edge6")] + FlowVelocity_Outlet.NormalDirection = Vector(1, 0, 0) + FlowVelocity_Outlet.VelocityYEnabled = True + FlowVelocity_Outlet.VelocityZEnabled = True + analysis.addObject(FlowVelocity_Outlet) + + # constraint wall velocity + FlowVelocity_Wall = ObjectsFem.makeConstraintFlowVelocity(doc, "FlowVelocity_Wall") + FlowVelocity_Wall.References = [ + (BooleanFragments, "Edge2"), + (BooleanFragments, "Edge3"), + (BooleanFragments, "Edge4"), + (BooleanFragments, "Edge7")] + FlowVelocity_Wall.NormalDirection = Vector(0, 0, -1) + FlowVelocity_Wall.VelocityXEnabled = True + FlowVelocity_Wall.VelocityYEnabled = True + FlowVelocity_Wall.VelocityZEnabled = True + analysis.addObject(FlowVelocity_Wall) + + # constraint initial velocity + FlowVelocity_Initial = ObjectsFem.makeConstraintInitialFlowVelocity(doc, "FlowVelocity_Initial") + FlowVelocity_Initial.References = [(BooleanFragments, "Face2")] + FlowVelocity_Initial.NormalDirection = Vector(0, -1, 0) + FlowVelocity_Initial.VelocityXEnabled = True + FlowVelocity_Initial.VelocityYEnabled = True + FlowVelocity_Initial.VelocityZEnabled = True + analysis.addObject(FlowVelocity_Initial) + + # constraint initial temperature + Temperature_Initial = ObjectsFem.makeConstraintInitialTemperature(doc, "Temperature_Initial") + Temperature_Initial.initialTemperature = 300.0 + analysis.addObject(Temperature_Initial) + + # constraint wall temperature + Temperature_Wall = ObjectsFem.makeConstraintTemperature(doc, "Temperature_Wall") + Temperature_Wall.Temperature = 293.0 + Temperature_Wall.NormalDirection = Vector(0, 0, -1) + Temperature_Wall.References = [ + (BooleanFragments, "Edge2"), + (BooleanFragments, "Edge3"), + (BooleanFragments, "Edge4"), + (BooleanFragments, "Edge7")] + analysis.addObject(Temperature_Wall) + + # constraint inlet temperature + Temperature_Inlet = ObjectsFem.makeConstraintTemperature(doc, "Temperature_Inlet") + Temperature_Inlet.Temperature = 350.0 + Temperature_Inlet.NormalDirection = Vector(-1, 0, 0) + Temperature_Inlet.References = [(BooleanFragments, "Edge5")] + analysis.addObject(Temperature_Inlet) + + # constraint heating rod temperature + Temperature_HeatingRod = ObjectsFem.makeConstraintTemperature(doc, "Temperature_HeatingRod") + Temperature_HeatingRod.Temperature = 600.0 + Temperature_HeatingRod.NormalDirection = Vector(0, -1, 0) + Temperature_HeatingRod.References = [(BooleanFragments, "Edge1")] + analysis.addObject(Temperature_HeatingRod) + + # constraint initial pressure + Pressure_Initial = ObjectsFem.makeConstraintInitialPressure(doc, "Pressure_Initial") + Pressure_Initial.Pressure = "100.0 kPa" + Pressure_Initial.NormalDirection = Vector(0, -1, 0) + Pressure_Initial.References = [(BooleanFragments, "Face2")] + analysis.addObject(Pressure_Initial) + + # mesh + femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0] + femmesh_obj.Part = BooleanFragments + femmesh_obj.ElementOrder = "1st" + femmesh_obj.CharacteristicLengthMax = "4 mm" + femmesh_obj.ViewObject.Visibility = False + + # mesh_region + mesh_region = ObjectsFem.makeMeshRegion(doc, femmesh_obj, name="MeshRegion") + mesh_region.CharacteristicLength = "2 mm" + mesh_region.References = [ + (BooleanFragments, "Edge1"), + (BooleanFragments, "Vertex2"), + (BooleanFragments, "Vertex4"), + (BooleanFragments, "Vertex6")] + mesh_region.ViewObject.Visibility = False + + # generate the mesh + from femmesh import gmshtools + gmsh_mesh = gmshtools.GmshTools(femmesh_obj, analysis) + try: + error = gmsh_mesh.create_mesh() + except Exception: + error = sys.exc_info()[1] + FreeCAD.Console.PrintError( + "Unexpected error when creating mesh: {}\n" + .format(error) + ) + + doc.recompute() + return doc diff --git a/src/Mod/Fem/femexamples/examplesgui.py b/src/Mod/Fem/femexamples/examplesgui.py index 3e288ae87a..08871cb8bf 100644 --- a/src/Mod/Fem/femexamples/examplesgui.py +++ b/src/Mod/Fem/femexamples/examplesgui.py @@ -86,7 +86,9 @@ class FemExamples(QtGui.QWidget): self.files_name[info["name"]] = f meshtypes.add(info["meshtype"]) mesheles.add(info["meshelement"]) - equations.add(info["equation"]) + file_equations = info["equations"] + for equation in file_equations: + equations.add(equation) materials.add(info["material"]) file_solvers = info["solvers"] for solver in file_solvers: @@ -105,8 +107,8 @@ class FemExamples(QtGui.QWidget): all_examples = QtGui.QTreeWidgetItem(self.view, ["All"]) for example, info in files_info.items(): QtGui.QTreeWidgetItem(all_examples, [info["name"]]) - self.view.addTopLevelItem(all_examples) + all_constraints = QtGui.QTreeWidgetItem(self.view, ["Constraints"]) for constraint in constraints: constraint_item = QtGui.QTreeWidgetItem(all_constraints, [constraint]) @@ -114,16 +116,15 @@ class FemExamples(QtGui.QWidget): file_constraints = info["constraints"] if constraint in file_constraints: QtGui.QTreeWidgetItem(constraint_item, [info["name"]]) - self.view.addTopLevelItem(all_constraints) all_equations = QtGui.QTreeWidgetItem(self.view, ["Equations"]) for equation in equations: equation_item = QtGui.QTreeWidgetItem(all_equations, [equation]) for example, info in files_info.items(): - if info["equation"] == equation: + file_equations = info["equations"] + if equation in file_equations: QtGui.QTreeWidgetItem(equation_item, [info["name"]]) - self.view.addTopLevelItem(all_equations) all_materials = QtGui.QTreeWidgetItem(self.view, ["Materials"]) @@ -132,7 +133,6 @@ class FemExamples(QtGui.QWidget): for example, info in files_info.items(): if info["material"] == material: QtGui.QTreeWidgetItem(material_item, [info["name"]]) - self.view.addTopLevelItem(all_materials) all_meshtypes = QtGui.QTreeWidgetItem(self.view, ["MeshTypes"]) @@ -141,7 +141,6 @@ class FemExamples(QtGui.QWidget): for example, info in files_info.items(): if info["meshtype"] == mesh: QtGui.QTreeWidgetItem(mesh_item, [info["name"]]) - self.view.addTopLevelItem(all_meshtypes) all_mesheles = QtGui.QTreeWidgetItem(self.view, ["MeshElements"]) @@ -150,7 +149,6 @@ class FemExamples(QtGui.QWidget): for example, info in files_info.items(): if info["meshelement"] == mesh: QtGui.QTreeWidgetItem(mesh_item, [info["name"]]) - self.view.addTopLevelItem(all_mesheles) all_solvers = QtGui.QTreeWidgetItem(self.view, ["Solvers"]) @@ -160,7 +158,6 @@ class FemExamples(QtGui.QWidget): file_solvers = info["solvers"] if solver in file_solvers: QtGui.QTreeWidgetItem(solver_item, [info["name"]]) - self.view.addTopLevelItem(all_solvers) self.view.setHeaderHidden(True) diff --git a/src/Mod/Fem/femexamples/frequency_beamsimple.py b/src/Mod/Fem/femexamples/frequency_beamsimple.py index b412aab389..3434ffcf2a 100644 --- a/src/Mod/Fem/femexamples/frequency_beamsimple.py +++ b/src/Mod/Fem/femexamples/frequency_beamsimple.py @@ -39,7 +39,7 @@ def get_information(): "constraints": ["fixed"], "solvers": ["calculix", "ccxtools"], "material": "solid", - "equation": "frequency" + "equations": ["frequency"] } diff --git a/src/Mod/Fem/femexamples/manager.py b/src/Mod/Fem/femexamples/manager.py index b72a71e8b6..6b0a21acb1 100644 --- a/src/Mod/Fem/femexamples/manager.py +++ b/src/Mod/Fem/femexamples/manager.py @@ -70,6 +70,7 @@ def run_all(): run_example("elmer_nonguitutorial01_eigenvalue_of_elastic_beam", run_solver=True) run_example("equation_electrostatics_capacitance_two_balls", run_solver=True) run_example("equation_electrostatics_electricforce_elmer_nongui6", run_solver=True) + run_example("equation_flow_elmer_2D", run_solver=True) run_example("frequency_beamsimple", run_solver=True) run_example("material_multiple_bendingbeam_fiveboxes", run_solver=True) run_example("material_multiple_bendingbeam_fivefaces", run_solver=True) @@ -102,6 +103,7 @@ def setup_all(): run_example("elmer_nonguitutorial01_eigenvalue_of_elastic_beam") run_example("equation_electrostatics_capacitance_two_balls") run_example("equation_electrostatics_electricforce_elmer_nongui6") + run_example("equation_flow_elmer_2D") run_example("frequency_beamsimple") run_example("material_multiple_bendingbeam_fiveboxes") run_example("material_multiple_bendingbeam_fivefaces") diff --git a/src/Mod/Fem/femexamples/material_multiple_bendingbeam_fiveboxes.py b/src/Mod/Fem/femexamples/material_multiple_bendingbeam_fiveboxes.py index 7f90c44a4b..138e54f3b1 100644 --- a/src/Mod/Fem/femexamples/material_multiple_bendingbeam_fiveboxes.py +++ b/src/Mod/Fem/femexamples/material_multiple_bendingbeam_fiveboxes.py @@ -42,7 +42,7 @@ def get_information(): "constraints": ["fixed", "force"], "solvers": ["calculix", "ccxtools"], "material": "multimaterial", - "equation": "mechanical" + "equations": ["mechanical"] } diff --git a/src/Mod/Fem/femexamples/material_multiple_bendingbeam_fivefaces.py b/src/Mod/Fem/femexamples/material_multiple_bendingbeam_fivefaces.py index d5bac29b75..c3e933fc08 100644 --- a/src/Mod/Fem/femexamples/material_multiple_bendingbeam_fivefaces.py +++ b/src/Mod/Fem/femexamples/material_multiple_bendingbeam_fivefaces.py @@ -40,7 +40,7 @@ def get_information(): "constraints": ["fixed", "force"], "solvers": ["calculix", "ccxtools"], "material": "multimaterial", - "equation": "mechanical" + "equations": ["mechanical"] } diff --git a/src/Mod/Fem/femexamples/material_multiple_tensionrod_twoboxes.py b/src/Mod/Fem/femexamples/material_multiple_tensionrod_twoboxes.py index 8ae258cf40..5e0c52e3e0 100644 --- a/src/Mod/Fem/femexamples/material_multiple_tensionrod_twoboxes.py +++ b/src/Mod/Fem/femexamples/material_multiple_tensionrod_twoboxes.py @@ -43,7 +43,7 @@ def get_information(): "constraints": ["fixed", "pressure"], "solvers": ["calculix", "ccxtools"], "material": "multimaterial", - "equation": "mechanical" + "equations": ["mechanical"] } diff --git a/src/Mod/Fem/femexamples/material_nl_platewithhole.py b/src/Mod/Fem/femexamples/material_nl_platewithhole.py index 6ce3d71ec8..68c33fc7b8 100644 --- a/src/Mod/Fem/femexamples/material_nl_platewithhole.py +++ b/src/Mod/Fem/femexamples/material_nl_platewithhole.py @@ -51,7 +51,7 @@ def get_information(): "constraints": ["fixed", "force"], "solvers": ["calculix", "ccxtools"], "material": "nonlinear", - "equation": "mechanical" + "equations": ["mechanical"] } diff --git a/src/Mod/Fem/femexamples/mystran_plate.py b/src/Mod/Fem/femexamples/mystran_plate.py index 0f187dd969..f288d5ecfe 100644 --- a/src/Mod/Fem/femexamples/mystran_plate.py +++ b/src/Mod/Fem/femexamples/mystran_plate.py @@ -41,7 +41,7 @@ def get_information(): "constraints": ["fixed", "force"], "solvers": ["calculix", "ccxtools", "elmer", "mystran"], "material": "solid", - "equation": "mechanical" + "equations": ["mechanical"] } diff --git a/src/Mod/Fem/femexamples/rc_wall_2d.py b/src/Mod/Fem/femexamples/rc_wall_2d.py index ca6bcf6695..6fda1c86f5 100644 --- a/src/Mod/Fem/femexamples/rc_wall_2d.py +++ b/src/Mod/Fem/femexamples/rc_wall_2d.py @@ -44,7 +44,7 @@ def get_information(): "constraints": ["fixed", "force", "displacement"], "solvers": ["calculix", "ccxtools"], "material": "reinforced", - "equation": "mechanical" + "equations": ["mechanical"] } diff --git a/src/Mod/Fem/femexamples/square_pipe_end_twisted_edgeforces.py b/src/Mod/Fem/femexamples/square_pipe_end_twisted_edgeforces.py index e34bd0da16..18c14b2acd 100644 --- a/src/Mod/Fem/femexamples/square_pipe_end_twisted_edgeforces.py +++ b/src/Mod/Fem/femexamples/square_pipe_end_twisted_edgeforces.py @@ -43,7 +43,7 @@ def get_information(): "constraints": ["force", "fixed"], "solvers": ["calculix", "ccxtools"], "material": "solid", - "equation": "mechanical" + "equations": ["mechanical"] } diff --git a/src/Mod/Fem/femexamples/square_pipe_end_twisted_nodeforces.py b/src/Mod/Fem/femexamples/square_pipe_end_twisted_nodeforces.py index 1b70ffb811..f51a666aaf 100644 --- a/src/Mod/Fem/femexamples/square_pipe_end_twisted_nodeforces.py +++ b/src/Mod/Fem/femexamples/square_pipe_end_twisted_nodeforces.py @@ -43,7 +43,7 @@ def get_information(): "constraints": ["force", "fixed"], "solvers": ["calculix", "ccxtools"], "material": "solid", - "equation": "mechanical" + "equations": ["mechanical"] } diff --git a/src/Mod/Fem/femexamples/thermomech_bimetall.py b/src/Mod/Fem/femexamples/thermomech_bimetall.py index 8196390fb5..e41c5b22a4 100644 --- a/src/Mod/Fem/femexamples/thermomech_bimetall.py +++ b/src/Mod/Fem/femexamples/thermomech_bimetall.py @@ -51,7 +51,7 @@ def get_information(): "constraints": ["fixed", "initial temperature", "temperature"], "solvers": ["calculix", "ccxtools", "elmer"], "material": "multimaterial", - "equation": "thermomechanical" + "equations": ["thermomechanical"] } diff --git a/src/Mod/Fem/femexamples/thermomech_flow1d.py b/src/Mod/Fem/femexamples/thermomech_flow1d.py index df9059c47c..674565b46f 100644 --- a/src/Mod/Fem/femexamples/thermomech_flow1d.py +++ b/src/Mod/Fem/femexamples/thermomech_flow1d.py @@ -43,7 +43,7 @@ def get_information(): "constraints": ["self weight"], "solvers": ["calculix", "ccxtools"], "material": "fluid", - "equation": "thermomechanical" + "equations": ["thermomechanical"] } diff --git a/src/Mod/Fem/femexamples/thermomech_spine.py b/src/Mod/Fem/femexamples/thermomech_spine.py index 6ea6cce4f8..57c255ad2d 100644 --- a/src/Mod/Fem/femexamples/thermomech_spine.py +++ b/src/Mod/Fem/femexamples/thermomech_spine.py @@ -40,7 +40,7 @@ def get_information(): "constraints": ["fixed", "initial temperature", "temperature", "heatflux"], "solvers": ["calculix", "ccxtools"], "material": "solid", - "equation": "thermomechanical" + "equations": ["thermomechanical"] } diff --git a/src/Mod/Fem/femexamples/truss_3d_cs_circle_ele_seg2.py b/src/Mod/Fem/femexamples/truss_3d_cs_circle_ele_seg2.py index 0b7d953cbd..1d8a844cb3 100644 --- a/src/Mod/Fem/femexamples/truss_3d_cs_circle_ele_seg2.py +++ b/src/Mod/Fem/femexamples/truss_3d_cs_circle_ele_seg2.py @@ -38,7 +38,7 @@ def get_information(): "constraints": ["fixed", "force"], "solvers": ["z88"], "material": "solid", - "equation": "mechanical" + "equations": ["mechanical"] } diff --git a/src/Mod/Fem/femexamples/truss_3d_cs_circle_ele_seg3.py b/src/Mod/Fem/femexamples/truss_3d_cs_circle_ele_seg3.py index 9763ab6b99..50965ccaad 100644 --- a/src/Mod/Fem/femexamples/truss_3d_cs_circle_ele_seg3.py +++ b/src/Mod/Fem/femexamples/truss_3d_cs_circle_ele_seg3.py @@ -43,7 +43,7 @@ def get_information(): "constraints": ["fixed", "force"], "solvers": ["calculix", "ccxtools"], "material": "solid", - "equation": "mechanical" + "equations": ["mechanical"] }