From 138144d88e0c2310ac710ffcf574c4d2ca66ba6a Mon Sep 17 00:00:00 2001 From: Bernd Hahnebach Date: Tue, 13 Jul 2021 21:11:09 +0200 Subject: [PATCH] FEM: calculix writer, improve floating point writing --- .../calculix/write_constraint_centrif.py | 6 ++---- .../calculix/write_constraint_contact.py | 7 +++++-- .../calculix/write_constraint_displacement.py | 15 +++++++++------ .../femsolver/calculix/write_constraint_fixed.py | 3 +++ .../femsolver/calculix/write_constraint_force.py | 3 +++ .../calculix/write_constraint_heatflux.py | 7 +++++-- .../write_constraint_initialtemperature.py | 5 ++++- src/Mod/Fem/femsolver/calculix/writer.py | 11 +++++++++++ .../ccxcantilever_prescribeddisplacement.inp | 2 +- .../calculix/constraint_contact_shell_shell.inp | 2 +- .../femtest/data/calculix/thermomech_bimetall.inp | 2 +- .../femtest/data/calculix/thermomech_spine.inp | 2 +- 12 files changed, 46 insertions(+), 19 deletions(-) diff --git a/src/Mod/Fem/femsolver/calculix/write_constraint_centrif.py b/src/Mod/Fem/femsolver/calculix/write_constraint_centrif.py index b84b705614..b5a0b98753 100644 --- a/src/Mod/Fem/femsolver/calculix/write_constraint_centrif.py +++ b/src/Mod/Fem/femsolver/calculix/write_constraint_centrif.py @@ -72,6 +72,8 @@ def write_meshdata_constraint(f, femobj, centrif_obj, ccxwriter): def write_constraint(f, femobj, centrif_obj, ccxwriter): + # floats read from ccx should use {:.13G}, see comment in writer module + # get some data from the centrif_obj refobj = centrif_obj.RotationAxis[0][0] subobj = centrif_obj.RotationAxis[0][1][0] @@ -90,10 +92,6 @@ def write_constraint(f, femobj, centrif_obj, ccxwriter): # write to file f.write("*DLOAD\n") - # Why {:.13G} ... - # ccx uses F20.0 FORTRAN input fields, see in dload.f in ccx's source - # https://forum.freecadweb.org/viewtopic.php?f=18&t=22759&#p176578 - # example "{:.13G}".format(math.sqrt(2.)*-1e100) and count chars f.write( "{},CENTRIF,{:.13G},{:.13G},{:.13G},{:.13G},{:.13G},{:.13G},{:.13G}\n" .format( diff --git a/src/Mod/Fem/femsolver/calculix/write_constraint_contact.py b/src/Mod/Fem/femsolver/calculix/write_constraint_contact.py index cd2f7ad41d..dd8ddee7fd 100644 --- a/src/Mod/Fem/femsolver/calculix/write_constraint_contact.py +++ b/src/Mod/Fem/femsolver/calculix/write_constraint_contact.py @@ -66,6 +66,9 @@ def write_meshdata_constraint(f, femobj, contact_obj, ccxwriter): def write_constraint(f, femobj, contact_obj, ccxwriter): + + # floats read from ccx should use {:.13G}, see comment in writer module + f.write( "*CONTACT PAIR, INTERACTION=INT{},TYPE=SURFACE TO SURFACE\n" .format(contact_obj.Name) @@ -76,9 +79,9 @@ def write_constraint(f, femobj, contact_obj, ccxwriter): f.write("*SURFACE INTERACTION, NAME=INT{}\n".format(contact_obj.Name)) f.write("*SURFACE BEHAVIOR,PRESSURE-OVERCLOSURE=LINEAR\n") slope = contact_obj.Slope - f.write("{} \n".format(slope)) + f.write("{:.13G}\n".format(slope)) friction = contact_obj.Friction if friction > 0: f.write("*FRICTION \n") stick = (slope / 10.0) - f.write("{}, {} \n".format(friction, stick)) + f.write("{:.13G}, {:.13G}\n".format(friction, stick)) diff --git a/src/Mod/Fem/femsolver/calculix/write_constraint_displacement.py b/src/Mod/Fem/femsolver/calculix/write_constraint_displacement.py index 123450fc75..a99da3a0ea 100644 --- a/src/Mod/Fem/femsolver/calculix/write_constraint_displacement.py +++ b/src/Mod/Fem/femsolver/calculix/write_constraint_displacement.py @@ -61,30 +61,33 @@ def write_meshdata_constraint(f, femobj, disp_obj, ccxwriter): 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.xFix: f.write("{},1\n".format(disp_obj.Name)) elif not disp_obj.xFree: - f.write("{},1,1,{}\n".format(disp_obj.Name, disp_obj.xDisplacement)) + f.write("{},1,1,{:.13G}\n".format(disp_obj.Name, disp_obj.xDisplacement)) if disp_obj.yFix: f.write("{},2\n".format(disp_obj.Name)) elif not disp_obj.yFree: - f.write("{},2,2,{}\n".format(disp_obj.Name, disp_obj.yDisplacement)) + f.write("{},2,2,{:.13G}\n".format(disp_obj.Name, disp_obj.yDisplacement)) if disp_obj.zFix: f.write("{},3\n".format(disp_obj.Name)) elif not disp_obj.zFree: - f.write("{},3,3,{}\n".format(disp_obj.Name, disp_obj.zDisplacement)) + f.write("{},3,3,{:.13G}\n".format(disp_obj.Name, disp_obj.zDisplacement)) if ccxwriter.beamsection_objects or ccxwriter.shellthickness_objects: if disp_obj.rotxFix: f.write("{},4\n".format(disp_obj.Name)) elif not disp_obj.rotxFree: - f.write("{},4,4,{}\n".format(disp_obj.Name, disp_obj.xRotation)) + f.write("{},4,4,{:.13G}\n".format(disp_obj.Name, disp_obj.xRotation)) if disp_obj.rotyFix: f.write("{},5\n".format(disp_obj.Name)) elif not disp_obj.rotyFree: - f.write("{},5,5,{}\n".format(disp_obj.Name, disp_obj.yRotation)) + f.write("{},5,5,{:.13G}\n".format(disp_obj.Name, disp_obj.yRotation)) if disp_obj.rotzFix: f.write("{},6\n".format(disp_obj.Name)) elif not disp_obj.rotzFree: - f.write("{},6,6,{}\n".format(disp_obj.Name, disp_obj.zRotation)) + f.write("{},6,6,{:.13G}\n".format(disp_obj.Name, disp_obj.zRotation)) diff --git a/src/Mod/Fem/femsolver/calculix/write_constraint_fixed.py b/src/Mod/Fem/femsolver/calculix/write_constraint_fixed.py index 506e0c54cd..a90bc89d0c 100644 --- a/src/Mod/Fem/femsolver/calculix/write_constraint_fixed.py +++ b/src/Mod/Fem/femsolver/calculix/write_constraint_fixed.py @@ -74,6 +74,9 @@ def write_meshdata_constraint(f, femobj, fix_obj, ccxwriter): def write_constraint(f, femobj, fix_obj, ccxwriter): + + # floats read from ccx should use {:.13G}, see comment in writer module + if ( ccxwriter.femmesh.Volumes and (len(ccxwriter.shellthickness_objects) > 0 or len(ccxwriter.beamsection_objects) > 0) diff --git a/src/Mod/Fem/femsolver/calculix/write_constraint_force.py b/src/Mod/Fem/femsolver/calculix/write_constraint_force.py index e61b14674c..8e5306b844 100644 --- a/src/Mod/Fem/femsolver/calculix/write_constraint_force.py +++ b/src/Mod/Fem/femsolver/calculix/write_constraint_force.py @@ -43,6 +43,9 @@ def get_after_write_meshdata_constraint(): def write_meshdata_constraint(f, femobj, force_obj, ccxwriter): + + # floats read from ccx should use {:.13G}, see comment in writer module + direction_vec = femobj["Object"].DirectionVector for ref_shape in femobj["NodeLoadTable"]: f.write("** " + ref_shape[0] + "\n") diff --git a/src/Mod/Fem/femsolver/calculix/write_constraint_heatflux.py b/src/Mod/Fem/femsolver/calculix/write_constraint_heatflux.py index 14389c1e8c..62fcf7d994 100644 --- a/src/Mod/Fem/femsolver/calculix/write_constraint_heatflux.py +++ b/src/Mod/Fem/femsolver/calculix/write_constraint_heatflux.py @@ -43,18 +43,21 @@ def get_after_write_meshdata_constraint(): def write_meshdata_constraint(f, femobj, heatflux_obj, ccxwriter): + + # floats read from ccx should use {:.13G}, see comment in writer module + if heatflux_obj.ConstraintType == "Convection": heatflux_key_word = "FILM" heatflux_facetype = "F" # SvdW: add factor to force heatflux to units system of t/mm/s/K - heatflux_values = "{},{}".format( + heatflux_values = "{:.13G},{:.13G}".format( heatflux_obj.AmbientTemp, heatflux_obj.FilmCoef * 0.001 ) elif heatflux_obj.ConstraintType == "DFlux": heatflux_key_word = "DFLUX" heatflux_facetype = "S" - heatflux_values = "{}".format(heatflux_obj.DFlux * 0.001) + heatflux_values = "{:.13G}".format(heatflux_obj.DFlux * 0.001) f.write("*{}\n".format(heatflux_key_word)) for ref_shape in femobj["HeatFluxFaceTable"]: diff --git a/src/Mod/Fem/femsolver/calculix/write_constraint_initialtemperature.py b/src/Mod/Fem/femsolver/calculix/write_constraint_initialtemperature.py index 7b4bd8f94e..171364dbe8 100644 --- a/src/Mod/Fem/femsolver/calculix/write_constraint_initialtemperature.py +++ b/src/Mod/Fem/femsolver/calculix/write_constraint_initialtemperature.py @@ -44,7 +44,10 @@ def get_after_write_constraint(): def write_constraint(f, femobj, inittemp_obj, ccxwriter): - f.write("{0},{1}\n".format(ccxwriter.ccx_nall, inittemp_obj.initialTemperature)) + # floats read from ccx should use {:.13G}, see comment in writer module + + + f.write("{},{:.13G}\n".format(ccxwriter.ccx_nall, inittemp_obj.initialTemperature)) # Should only be one object in the analysis diff --git a/src/Mod/Fem/femsolver/calculix/writer.py b/src/Mod/Fem/femsolver/calculix/writer.py index 8f9fa284c7..e5c4276dcc 100644 --- a/src/Mod/Fem/femsolver/calculix/writer.py +++ b/src/Mod/Fem/femsolver/calculix/writer.py @@ -92,6 +92,17 @@ units_information = """********************************************************* """ +# TODO +# {0:.13G} or {:.13G} should be used on all places writing floating points to ccx +# All floating points fields read from ccx are F20.0 FORTRAN input fields. +# see in dload.f in ccx's source +# https://forum.freecadweb.org/viewtopic.php?f=18&p=516518#p516433 +# https://forum.freecadweb.org/viewtopic.php?f=18&t=22759&#p176578 +# example "{:.13G}".format(math.sqrt(2.)*-1e100) and count chars +# a property type is best checked in FreeCAD objects definition +# see femobjects package for Python objects or in objects App + + class FemInputWriterCcx(writerbase.FemInputWriter): def __init__( self, diff --git a/src/Mod/Fem/femtest/data/calculix/ccxcantilever_prescribeddisplacement.inp b/src/Mod/Fem/femtest/data/calculix/ccxcantilever_prescribeddisplacement.inp index 4521c3f5d4..c3a9479d55 100644 --- a/src/Mod/Fem/femtest/data/calculix/ccxcantilever_prescribeddisplacement.inp +++ b/src/Mod/Fem/femtest/data/calculix/ccxcantilever_prescribeddisplacement.inp @@ -394,7 +394,7 @@ ConstraintFixed,3 ** Displacement constraint applied ** ConstraintDisplacmentPrescribed *BOUNDARY -ConstraintDisplacmentPrescribed,3,3,-250.0 +ConstraintDisplacmentPrescribed,3,3,-250 *********************************************************** diff --git a/src/Mod/Fem/femtest/data/calculix/constraint_contact_shell_shell.inp b/src/Mod/Fem/femtest/data/calculix/constraint_contact_shell_shell.inp index ba57d47851..6f153f30a5 100644 --- a/src/Mod/Fem/femtest/data/calculix/constraint_contact_shell_shell.inp +++ b/src/Mod/Fem/femtest/data/calculix/constraint_contact_shell_shell.inp @@ -38369,7 +38369,7 @@ Efaces DEPConstraintContact,INDConstraintContact *SURFACE INTERACTION, NAME=INTConstraintContact *SURFACE BEHAVIOR,PRESSURE-OVERCLOSURE=LINEAR -1000000.0 +1000000 *********************************************************** ** At least one step is needed to run an CalculiX analysis of FreeCAD diff --git a/src/Mod/Fem/femtest/data/calculix/thermomech_bimetall.inp b/src/Mod/Fem/femtest/data/calculix/thermomech_bimetall.inp index 0eaddf774e..f949fd9bbd 100644 --- a/src/Mod/Fem/femtest/data/calculix/thermomech_bimetall.inp +++ b/src/Mod/Fem/femtest/data/calculix/thermomech_bimetall.inp @@ -8205,7 +8205,7 @@ Evolumes ** Initial temperature constraint *INITIAL CONDITIONS,TYPE=TEMPERATURE ** ConstraintInitialTemperature -Nall,273.0 +Nall,273 *********************************************************** ** Sections diff --git a/src/Mod/Fem/femtest/data/calculix/thermomech_spine.inp b/src/Mod/Fem/femtest/data/calculix/thermomech_spine.inp index f4bd019240..b5dda6cea6 100644 --- a/src/Mod/Fem/femtest/data/calculix/thermomech_spine.inp +++ b/src/Mod/Fem/femtest/data/calculix/thermomech_spine.inp @@ -125,7 +125,7 @@ Evolumes ** Initial temperature constraint *INITIAL CONDITIONS,TYPE=TEMPERATURE ** FemConstraintInitialTemperature -Nall,300.0 +Nall,300 *********************************************************** ** Sections