From 8ec0916efbde7e74ed661a1948d935b2965e1a08 Mon Sep 17 00:00:00 2001 From: marioalexis Date: Sun, 2 Jun 2024 12:37:07 -0300 Subject: [PATCH] Fem: Add body heat source to CalculiX writer - fixes #11650 --- src/Mod/Fem/CMakeLists.txt | 1 + src/Mod/Fem/femmesh/meshsetsgetter.py | 13 +++ src/Mod/Fem/femmesh/meshtools.py | 2 + .../write_constraint_bodyheatsource.py | 96 +++++++++++++++++++ src/Mod/Fem/femsolver/calculix/writer.py | 3 + src/Mod/Fem/femtools/membertools.py | 3 + 6 files changed, 118 insertions(+) create mode 100644 src/Mod/Fem/femsolver/calculix/write_constraint_bodyheatsource.py diff --git a/src/Mod/Fem/CMakeLists.txt b/src/Mod/Fem/CMakeLists.txt index 97a64ed510..aa2fba8d25 100755 --- a/src/Mod/Fem/CMakeLists.txt +++ b/src/Mod/Fem/CMakeLists.txt @@ -221,6 +221,7 @@ SET(FemSolverCalculix_SRCS femsolver/calculix/__init__.py femsolver/calculix/solver.py femsolver/calculix/tasks.py + femsolver/calculix/write_constraint_bodyheatsource.py femsolver/calculix/write_constraint_centrif.py femsolver/calculix/write_constraint_contact.py femsolver/calculix/write_constraint_displacement.py diff --git a/src/Mod/Fem/femmesh/meshsetsgetter.py b/src/Mod/Fem/femmesh/meshsetsgetter.py index c84b2b31b0..3093b55c9c 100644 --- a/src/Mod/Fem/femmesh/meshsetsgetter.py +++ b/src/Mod/Fem/femmesh/meshsetsgetter.py @@ -135,6 +135,7 @@ class MeshSetsGetter(): # constraints element sets getter self.get_constraints_centrif_elements() + self.get_constraints_bodyheatsource_elements() # constraints node sets getter self.get_constraints_fixed_nodes() @@ -540,6 +541,18 @@ class MeshSetsGetter(): else: self.get_solid_element_sets(self.member.cons_centrif) + def get_constraints_bodyheatsource_elements(self): + # get element ids and write them into the femobj + if not self.member.cons_bodyheatsource: + return + if ( + len(self.member.cons_bodyheatsource) == 1 + and not self.member.cons_bodyheatsource[0]["Object"].References + ): + self.member.cons_bodyheatsource[0]["FEMElements"] = self.ccx_evolumes + else: + self.get_solid_element_sets(self.member.cons_bodyheatsource) + # ******************************************************************************************** # ******************************************************************************************** # element sets material and element geometry diff --git a/src/Mod/Fem/femmesh/meshtools.py b/src/Mod/Fem/femmesh/meshtools.py index 845119f25e..615a04d203 100644 --- a/src/Mod/Fem/femmesh/meshtools.py +++ b/src/Mod/Fem/femmesh/meshtools.py @@ -784,6 +784,8 @@ def get_elset_short_name( return "S" + str(i) elif is_of_type(obj, "Fem::ConstraintCentrif"): return "C" + str(i) + elif is_of_type(obj, "Fem::ConstraintBodyHeatSource"): + return "H" + str(i) else: FreeCAD.Console.PrintError( "Error in creating short elset name " diff --git a/src/Mod/Fem/femsolver/calculix/write_constraint_bodyheatsource.py b/src/Mod/Fem/femsolver/calculix/write_constraint_bodyheatsource.py new file mode 100644 index 0000000000..075209de84 --- /dev/null +++ b/src/Mod/Fem/femsolver/calculix/write_constraint_bodyheatsource.py @@ -0,0 +1,96 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later + +#/*************************************************************************** +# * Copyright (c) 2024 Mario Passaglia * +# * * +# * This file is part of FreeCAD. * +# * * +# * FreeCAD is free software: you can redistribute it and/or modify it * +# * under the terms of the GNU Lesser General Public License as * +# * published by the Free Software Foundation, either version 2.1 of the * +# * License, or (at your option) any later version. * +# * * +# * 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 * +# * Lesser General Public License for more details. * +# * * +# * You should have received a copy of the GNU Lesser General Public * +# * License along with FreeCAD. If not, see * +# * . * +# * * +# ************************************************************************** + +__title__ = "FreeCAD FEM calculix constraint body heat source" +__author__ = "Mario Passaglia" +__url__ = "https://www.freecad.org" + + +import FreeCAD + + +def get_analysis_types(): + return ["thermomech"] + + +def get_sets_name(): + return "constraints_bodyheatsource_element_sets" + + +def get_constraint_title(): + return "Body Heat Source Constraints" + + +def get_before_write_meshdata_constraint(): + return "" + + +def get_after_write_meshdata_constraint(): + return "" + + +def get_before_write_constraint(): + return "" + + +def get_after_write_constraint(): + return "" + + +def write_meshdata_constraint(f, femobj, bodyheatsource_obj, ccxwriter): + f.write("*ELSET,ELSET={}\n".format(bodyheatsource_obj.Name)) + if isinstance(femobj["FEMElements"], str): + f.write("{}\n".format(femobj["FEMElements"])) + else: + for e in femobj["FEMElements"]: + f.write("{},\n".format(e)) + + +def write_constraint(f, femobj, bodyheatsource_obj, ccxwriter): + + # floats read from ccx should use {:.13G}, see comment in writer module + # search referenced material + ref = bodyheatsource_obj.References + density = None + for mat in ccxwriter.member.mats_linear: + for mat_ref in mat["Object"].References: + if mat_ref[0] == ref[0][0]: + density = FreeCAD.Units.Quantity(mat["Object"].Material["Density"]) + break + + if not density: + # search material without references + for mat in ccxwriter.member.mats_linear: + if not mat["Object"].References: + density = FreeCAD.Units.Quantity(mat["Object"].Material["Density"]) + + # get some data from the bodyheatsource_obj (is in power per unit mass) + heat = FreeCAD.Units.Quantity(bodyheatsource_obj.HeatSource, "m^2/s^3") * density + # write to file + f.write("*DFLUX\n") + f.write( + "{},BF,{:.13G}\n".format( + bodyheatsource_obj.Name, heat.getValueAs("t/(mm*s^3)").Value + ) + ) + f.write("\n") diff --git a/src/Mod/Fem/femsolver/calculix/writer.py b/src/Mod/Fem/femsolver/calculix/writer.py index bee4afb173..306d2b95fd 100644 --- a/src/Mod/Fem/femsolver/calculix/writer.py +++ b/src/Mod/Fem/femsolver/calculix/writer.py @@ -36,6 +36,7 @@ import FreeCAD from FreeCAD import Units from . import write_constraint_centrif as con_centrif +from . import write_constraint_bodyheatsource as con_bodyheatsource from . import write_constraint_contact as con_contact from . import write_constraint_displacement as con_displacement from . import write_constraint_fixed as con_fixed @@ -160,6 +161,7 @@ class FemInputWriterCcx(writerbase.FemInputWriter): # element sets constraints self.write_constraints_meshsets(inpfile, self.member.cons_centrif, con_centrif) + self.write_constraints_meshsets(inpfile, self.member.cons_bodyheatsource, con_bodyheatsource) # node sets self.write_constraints_meshsets(inpfile, self.member.cons_fixed, con_fixed) @@ -196,6 +198,7 @@ class FemInputWriterCcx(writerbase.FemInputWriter): self.write_constraints_propdata(inpfile, self.member.cons_sectionprint, con_sectionprint) self.write_constraints_propdata(inpfile, self.member.cons_selfweight, con_selfweight) self.write_constraints_propdata(inpfile, self.member.cons_centrif, con_centrif) + self.write_constraints_propdata(inpfile, self.member.cons_bodyheatsource, con_bodyheatsource) self.write_constraints_meshsets(inpfile, self.member.cons_force, con_force) self.write_constraints_meshsets(inpfile, self.member.cons_pressure, con_pressure) self.write_constraints_propdata(inpfile, self.member.cons_temperature, con_temperature) diff --git a/src/Mod/Fem/femtools/membertools.py b/src/Mod/Fem/femtools/membertools.py index 058ca710d5..6445ff7e01 100644 --- a/src/Mod/Fem/femtools/membertools.py +++ b/src/Mod/Fem/femtools/membertools.py @@ -289,6 +289,9 @@ class AnalysisMember(): self.cons_centrif = self.get_several_member( "Fem::ConstraintCentrif" ) + self.cons_bodyheatsource = self.get_several_member( + "Fem::ConstraintBodyHeatSource" + ) self.cons_contact = self.get_several_member( "Fem::ConstraintContact" )