FEM: Add support for amplitudes with CalculiX (#22851)
This commit is contained in:
51
src/Mod/Fem/femsolver/calculix/write_amplitude.py
Normal file
51
src/Mod/Fem/femsolver/calculix/write_amplitude.py
Normal file
@@ -0,0 +1,51 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
# ***************************************************************************
|
||||
# * Copyright (c) 2025 Jakub Michalski <jakub.j.michalski[at]gmail.com> *
|
||||
# * *
|
||||
# * 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 *
|
||||
# * <https://www.gnu.org/licenses/>. *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
|
||||
__title__ = "FreeCAD FEM calculix amplitude"
|
||||
__author__ = "Jakub Michalski"
|
||||
__url__ = "https://www.freecad.org"
|
||||
|
||||
|
||||
def write_amplitude(f, ccxwriter):
|
||||
|
||||
# write amplitude definitions for all analysis features that use them
|
||||
|
||||
def write_obj_amplitude(obj):
|
||||
if obj.EnableAmplitude:
|
||||
f.write(f"*AMPLITUDE, NAME={obj.Name}\n")
|
||||
for value in obj.AmplitudeValues:
|
||||
f.write(f"{value}\n")
|
||||
f.write("\n")
|
||||
|
||||
constraint_lists = [
|
||||
ccxwriter.member.cons_force,
|
||||
ccxwriter.member.cons_pressure,
|
||||
ccxwriter.member.cons_displacement,
|
||||
ccxwriter.member.cons_heatflux,
|
||||
ccxwriter.member.cons_temperature,
|
||||
ccxwriter.member.cons_bodyheatsource,
|
||||
]
|
||||
|
||||
for constraint_list in constraint_lists:
|
||||
for entry in constraint_list:
|
||||
write_obj_amplitude(entry["Object"])
|
||||
@@ -96,6 +96,9 @@ def write_constraint(f, femobj, bodyheatsource_obj, ccxwriter):
|
||||
volume = ref_feat.getSubObject(ref_sub_obj).Volume
|
||||
heat = bodyheatsource_obj.TotalPower / FreeCAD.Units.Quantity(volume, "mm^3")
|
||||
# write to file
|
||||
f.write("*DFLUX\n")
|
||||
if bodyheatsource_obj.EnableAmplitude:
|
||||
f.write(f"*DFLUX, AMPLITUDE={bodyheatsource_obj.Name}\n")
|
||||
else:
|
||||
f.write("*DFLUX\n")
|
||||
f.write("{},BF,{:.13G}\n".format(bodyheatsource_obj.Name, heat.getValueAs("t/(mm*s^3)").Value))
|
||||
f.write("\n")
|
||||
|
||||
@@ -66,7 +66,10 @@ def write_constraint(f, femobj, disp_obj, ccxwriter):
|
||||
|
||||
# floats read from ccx should use {:.13G}, see comment in writer module
|
||||
|
||||
f.write("*BOUNDARY\n")
|
||||
if disp_obj.EnableAmplitude:
|
||||
f.write(f"*BOUNDARY, AMPLITUDE={disp_obj.Name}\n")
|
||||
else:
|
||||
f.write("*BOUNDARY\n")
|
||||
if not disp_obj.xFree:
|
||||
f.write(
|
||||
"{},1,1,{}\n".format(
|
||||
|
||||
@@ -35,7 +35,7 @@ def get_sets_name():
|
||||
|
||||
|
||||
def get_before_write_meshdata_constraint():
|
||||
return "*CLOAD\n"
|
||||
return ""
|
||||
|
||||
|
||||
def get_after_write_meshdata_constraint():
|
||||
@@ -46,6 +46,10 @@ def write_meshdata_constraint(f, femobj, force_obj, ccxwriter):
|
||||
|
||||
# floats read from ccx should use {:.13G}, see comment in writer module
|
||||
|
||||
if force_obj.EnableAmplitude:
|
||||
f.write(f"*CLOAD, AMPLITUDE={force_obj.Name}\n")
|
||||
else:
|
||||
f.write("*CLOAD\n")
|
||||
direction_vec = femobj["Object"].DirectionVector
|
||||
dir_zero_tol = 1e-15 # TODO: should this be more generally for more values?
|
||||
# be careful with raising the tolerance, a big load would have an impact
|
||||
|
||||
@@ -76,7 +76,12 @@ def write_meshdata_constraint(f, femobj, heatflux_obj, ccxwriter):
|
||||
else:
|
||||
return
|
||||
|
||||
f.write(f"*{heatflux_key_word}\n")
|
||||
if heatflux_obj.EnableAmplitude:
|
||||
heatflux_amplitude = f", AMPLITUDE={heatflux_obj.Name}"
|
||||
else:
|
||||
heatflux_amplitude = ""
|
||||
|
||||
f.write(f"*{heatflux_key_word}{heatflux_amplitude}\n")
|
||||
for ref_shape in femobj["HeatFluxFaceTable"]:
|
||||
elem_string = ref_shape[0]
|
||||
face_table = ref_shape[1]
|
||||
|
||||
@@ -48,12 +48,14 @@ def write_meshdata_constraint(f, femobj, prs_obj, ccxwriter):
|
||||
|
||||
# floats read from ccx should use {:.13G}, see comment in writer module
|
||||
|
||||
if prs_obj.EnableAmplitude:
|
||||
f.write(f"*DLOAD, AMPLITUDE={prs_obj.Name}\n")
|
||||
else:
|
||||
f.write("*DLOAD\n")
|
||||
rev = -1 if prs_obj.Reversed else 1
|
||||
# the pressure has to be output in MPa
|
||||
pressure_quantity = FreeCAD.Units.Quantity(prs_obj.Pressure.getValueAs("MPa"))
|
||||
press_rev = rev * pressure_quantity
|
||||
|
||||
f.write("*DLOAD\n")
|
||||
for ref_shape in femobj["PressureFaces"]:
|
||||
# the loop is needed for compatibility reason
|
||||
# in deprecated method get_pressure_obj_faces_depreciated
|
||||
|
||||
@@ -68,8 +68,12 @@ def write_constraint(f, femobj, temp_obj, ccxwriter):
|
||||
# floats read from ccx should use {:.13G}, see comment in writer module
|
||||
|
||||
NumberOfNodes = len(femobj["Nodes"])
|
||||
if temp_obj.EnableAmplitude:
|
||||
temp_amplitude = f", AMPLITUDE={temp_obj.Name}"
|
||||
else:
|
||||
temp_amplitude = ""
|
||||
if temp_obj.ConstraintType == "Temperature":
|
||||
f.write("*BOUNDARY\n")
|
||||
f.write(f"*BOUNDARY{temp_amplitude}\n")
|
||||
f.write(
|
||||
"{},11,11,{}\n".format(
|
||||
temp_obj.Name, FreeCAD.Units.Quantity(temp_obj.Temperature.getValueAs("K"))
|
||||
@@ -77,7 +81,7 @@ def write_constraint(f, femobj, temp_obj, ccxwriter):
|
||||
)
|
||||
f.write("\n")
|
||||
elif temp_obj.ConstraintType == "CFlux":
|
||||
f.write("*CFLUX\n")
|
||||
f.write(f"*CFLUX{temp_amplitude}\n")
|
||||
# CFLUX has to be specified in mW
|
||||
f.write(
|
||||
"{},11,{}\n".format(
|
||||
|
||||
@@ -60,6 +60,7 @@ from . import write_femelement_material
|
||||
from . import write_femelement_matgeosets
|
||||
from . import write_footer
|
||||
from . import write_mesh
|
||||
from . import write_amplitude
|
||||
from . import write_step_equation
|
||||
from . import write_step_output
|
||||
from .. import writerbase
|
||||
@@ -182,6 +183,9 @@ class FemInputWriterCcx(writerbase.FemInputWriter):
|
||||
self.write_constraints_propdata(inpfile, self.member.cons_transform, con_transform)
|
||||
self.write_constraints_propdata(inpfile, self.member.cons_rigidbody, con_rigidbody)
|
||||
|
||||
# amplitudes
|
||||
write_amplitude.write_amplitude(inpfile, self)
|
||||
|
||||
# step equation
|
||||
write_step_equation.write_step_equation(inpfile, self)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user