# *************************************************************************** # * Copyright (c) 2021 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. * # * * # * 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 * # * * # *************************************************************************** __title__ = "FreeCAD FEM calculix write inpfile materials" __author__ = "Bernd Hahnebach" __url__ = "https://www.freecad.org" import FreeCAD from femtools import constants def write_femelement_material(f, ccxwriter): # floats read from ccx should use {:.13G}, see comment in writer module # see unit comment in writer module def is_density_needed(): if ccxwriter.analysis_type == "frequency": return True if ( ccxwriter.analysis_type == "thermomech" and not ccxwriter.solver_obj.ThermoMechSteadyState ): return True if ccxwriter.member.cons_centrif: return True if ccxwriter.member.cons_selfweight: return True return False f.write("\n** Physical constants for SI(mm) unit system with Kelvins\n") f.write("*PHYSICAL CONSTANTS, ABSOLUTE ZERO=0, STEFAN BOLTZMANN=5.670374419e-11\n") f.write("\n{}\n".format(59 * "*")) f.write("** Materials\n") f.write("** see information about units at file end\n") for femobj in ccxwriter.member.mats_linear: # femobj --> dict, FreeCAD document object is femobj["Object"] mat_obj = femobj["Object"] mat_info_name = mat_obj.Material["Name"] mat_name = mat_obj.Name mat_label = mat_obj.Label # get material properties of solid material, Currently in SI units: M/kg/s/Kelvin if mat_obj.Category == "Solid": YM = FreeCAD.Units.Quantity(mat_obj.Material["YoungsModulus"]) YM_in_MPa = YM.getValueAs("MPa").Value PR = float(mat_obj.Material["PoissonRatio"]) if is_density_needed() is True: density = FreeCAD.Units.Quantity(mat_obj.Material["Density"]) density_in_tonne_per_mm3 = density.getValueAs("t/mm^3").Value if ccxwriter.analysis_type == "thermomech": TC = FreeCAD.Units.Quantity(mat_obj.Material["ThermalConductivity"]) # SvdW: Add factor to force units to results base units # of t/mm/s/K - W/m/K results in no factor needed TC_in_WmK = TC.getValueAs("W/m/K").Value SH = FreeCAD.Units.Quantity(mat_obj.Material["SpecificHeat"]) # SvdW: Add factor to force units to results base units of t/mm/s/K # FIXME: why not get it directly in the units needed ? SH_in_JkgK = SH.getValueAs("J/kg/K").Value * 1e06 if mat_obj.Category == "Solid": TEC = FreeCAD.Units.Quantity(mat_obj.Material["ThermalExpansionCoefficient"]) TEC_in_mmK = TEC.getValueAs("mm/mm/K").Value if "ThermalExpansionReferenceTemperature" in mat_obj.Material: RT = FreeCAD.Units.Quantity( mat_obj.Material["ThermalExpansionReferenceTemperature"] ) else: RT = FreeCAD.Units.Quantity("0 K") RT_in_K = RT.getValueAs("K").Value elif mat_obj.Category == "Fluid": KV = FreeCAD.Units.Quantity(mat_obj.Material["KinematicViscosity"]) KV_in_mm2s = KV.getValueAs("mm^2/s").Value DV_in_tmms = KV_in_mm2s * density_in_tonne_per_mm3 if ccxwriter.analysis_type == "static": if mat_obj.Category == "Solid": if "ThermalExpansionCoefficient" in mat_obj.Material: TEC = FreeCAD.Units.Quantity(mat_obj.Material["ThermalExpansionCoefficient"]) TEC_in_mmK = TEC.getValueAs("mm/mm/K").Value else: TEC_in_mmK = 0.0 if "ThermalExpansionReferenceTemperature" in mat_obj.Material: RT = FreeCAD.Units.Quantity( mat_obj.Material["ThermalExpansionReferenceTemperature"] ) else: RT = FreeCAD.Units.Quantity("0 K") RT_in_K = RT.getValueAs("K").Value if ( ccxwriter.analysis_type == "electromagnetic" and ccxwriter.solver_obj.ElectromagneticMode == "electrostatic" ): rel_perm = FreeCAD.Units.Quantity(mat_obj.Material["RelativePermittivity"]).Value vacuum_perm = FreeCAD.Units.Quantity(constants.vacuum_permittivity()) abs_perm = vacuum_perm.getValueAs("C/(mV*mm)").Value * rel_perm # write material properties f.write(f"** FreeCAD material name: {mat_info_name}\n") f.write(f"** {mat_label}\n") f.write(f"*MATERIAL, NAME={mat_name}\n") if mat_obj.Category == "Solid": f.write("*ELASTIC\n") f.write(f"{YM_in_MPa:.13G},{PR:.13G}\n") if is_density_needed() is True: f.write("*DENSITY\n") f.write(f"{density_in_tonne_per_mm3:.13G}\n") if ccxwriter.analysis_type == "thermomech": if mat_obj.Category == "Solid": f.write("*CONDUCTIVITY\n") f.write(f"{TC_in_WmK:.13G}\n") f.write(f"*EXPANSION, ZERO={RT_in_K:.13G}\n") f.write(f"{TEC_in_mmK:.13G}\n") f.write("*SPECIFIC HEAT\n") f.write(f"{SH_in_JkgK:.13G}\n") elif mat_obj.Category == "Fluid": f.write("*FLUID CONSTANTS\n") f.write(f"{SH_in_JkgK:.13G},{DV_in_tmms:.13G}\n") if ccxwriter.analysis_type == "static": if mat_obj.Category == "Solid": f.write(f"*EXPANSION, ZERO={RT_in_K:.13G}\n") f.write(f"{TEC_in_mmK:.13G}\n") if ( ccxwriter.analysis_type == "electromagnetic" and ccxwriter.solver_obj.ElectromagneticMode == "electrostatic" ): f.write("*CONDUCTIVITY\n") f.write(f"{abs_perm:.13G}\n") # nonlinear material properties if ccxwriter.solver_obj.MaterialNonlinearity == "nonlinear": for nlfemobj in ccxwriter.member.mats_nonlinear: # femobj --> dict, FreeCAD document object is nlfemobj["Object"] nl_mat_obj = nlfemobj["Object"] if nl_mat_obj.LinearBaseMaterial == mat_obj: if nl_mat_obj.MaterialModelNonlinearity == "isotropic hardening": f.write("*PLASTIC\n") else: f.write("*PLASTIC, HARDENING=KINEMATIC\n") for yield_point in nl_mat_obj.YieldPoints: f.write(f"{yield_point}\n") f.write("\n")