From e1ad86876ed71a53aa3eb7350808fa76de2c50dd Mon Sep 17 00:00:00 2001 From: Ajinkya Dahale Date: Sat, 11 Sep 2021 13:25:35 -0400 Subject: [PATCH 1/2] [FEM] Add tools for more yield points in simple hardening materials String List instead of String should allow for arbitrarily many entries, theoretically. Note the defaults previously in `YieldPoint1` an `YieldPoint2` were arbitrary. Now the list is kept empty by default. Fixes issue #4720. --- .../femexamples/material_nl_platewithhole.py | 3 +-- .../material_mechanicalnonlinear.py | 25 ++++--------------- .../calculix/write_femelement_material.py | 8 ++---- 3 files changed, 8 insertions(+), 28 deletions(-) diff --git a/src/Mod/Fem/femexamples/material_nl_platewithhole.py b/src/Mod/Fem/femexamples/material_nl_platewithhole.py index e81d72f71a2f..6ce3d71ec8bf 100644 --- a/src/Mod/Fem/femexamples/material_nl_platewithhole.py +++ b/src/Mod/Fem/femexamples/material_nl_platewithhole.py @@ -149,8 +149,7 @@ def setup(doc=None, solvertype="ccxtools"): # nonlinear material name_nlm = "Material_nonlin" nonlinear_mat = ObjectsFem.makeMaterialMechanicalNonlinear(doc, material_obj, name_nlm) - nonlinear_mat.YieldPoint1 = '240.0, 0.0' - nonlinear_mat.YieldPoint2 = '270.0, 0.025' + nonlinear_mat.YieldPoints = ['240.0, 0.0', '270.0, 0.025'] analysis.addObject(nonlinear_mat) # check solver attributes, Nonlinearity needs to be set to nonlinear diff --git a/src/Mod/Fem/femobjects/material_mechanicalnonlinear.py b/src/Mod/Fem/femobjects/material_mechanicalnonlinear.py index 9184aa26ac90..8aa8b3b57730 100644 --- a/src/Mod/Fem/femobjects/material_mechanicalnonlinear.py +++ b/src/Mod/Fem/femobjects/material_mechanicalnonlinear.py @@ -60,25 +60,10 @@ def __init__(self, obj): obj.MaterialModelNonlinearity = choices_nonlinear_material_models[0] obj.addProperty( - "App::PropertyString", - "YieldPoint1", + "App::PropertyStringList", + "YieldPoints", "Fem", - "Set stress and strain for yield point one, separated by a comma." + "Set stress and strain for yield points as a list of strings, " + "each point \"stress, plastic strain\"" ) - obj.YieldPoint1 = "235.0, 0.0" - - obj.addProperty( - "App::PropertyString", - "YieldPoint2", - "Fem", - "Set stress and strain for yield point two, separated by a comma." - ) - obj.YieldPoint2 = "241.0, 0.025" - - obj.addProperty( - "App::PropertyString", - "YieldPoint3", - "Fem", - "Set stress and strain for yield point three, separated by a comma." - ) - obj.YieldPoint3 = "" + obj.YieldPoints = [] diff --git a/src/Mod/Fem/femsolver/calculix/write_femelement_material.py b/src/Mod/Fem/femsolver/calculix/write_femelement_material.py index 98747fd7b5a7..edccbd613530 100644 --- a/src/Mod/Fem/femsolver/calculix/write_femelement_material.py +++ b/src/Mod/Fem/femsolver/calculix/write_femelement_material.py @@ -113,10 +113,6 @@ def is_density_needed(): if nl_mat_obj.LinearBaseMaterial == mat_obj: if nl_mat_obj.MaterialModelNonlinearity == "simple hardening": f.write("*PLASTIC\n") - if nl_mat_obj.YieldPoint1: - f.write("{}\n".format(nl_mat_obj.YieldPoint1)) - if nl_mat_obj.YieldPoint2: - f.write("{}\n".format(nl_mat_obj.YieldPoint2)) - if nl_mat_obj.YieldPoint3: - f.write("{}\n".format(nl_mat_obj.YieldPoint3)) + for yield_point in nl_mat_obj.YieldPoints: + f.write("{}\n".format(yield_point)) f.write("\n") From 8724b0de4511bbac431c980a993c4c0032ddf21d Mon Sep 17 00:00:00 2001 From: Ajinkya Dahale Date: Tue, 14 Sep 2021 00:33:27 -0400 Subject: [PATCH 2/2] [FEM] Add backward compatibility for simple hardening Prior to a recent commit (or this, if squashed), yield points of a non-linear material with simple hardening were stored as three different properties. These changes consolidate them into the new `YieldPoints` property. --- .../material_mechanicalnonlinear.py | 83 +++++++++++++------ 1 file changed, 58 insertions(+), 25 deletions(-) diff --git a/src/Mod/Fem/femobjects/material_mechanicalnonlinear.py b/src/Mod/Fem/femobjects/material_mechanicalnonlinear.py index 8aa8b3b57730..c95296dd668f 100644 --- a/src/Mod/Fem/femobjects/material_mechanicalnonlinear.py +++ b/src/Mod/Fem/femobjects/material_mechanicalnonlinear.py @@ -41,29 +41,62 @@ class MaterialMechanicalNonlinear(base_fempythonobject.BaseFemPythonObject): def __init__(self, obj): super(MaterialMechanicalNonlinear, self).__init__(obj) + self.add_properties(obj) - obj.addProperty( - "App::PropertyLink", - "LinearBaseMaterial", - "Base", - "Set the linear material the nonlinear builds upon." - ) - - choices_nonlinear_material_models = ["simple hardening"] - obj.addProperty( - "App::PropertyEnumeration", - "MaterialModelNonlinearity", - "Fem", - "Set the type on nonlinear material model" - ) - obj.MaterialModelNonlinearity = choices_nonlinear_material_models - obj.MaterialModelNonlinearity = choices_nonlinear_material_models[0] - - obj.addProperty( - "App::PropertyStringList", - "YieldPoints", - "Fem", - "Set stress and strain for yield points as a list of strings, " - "each point \"stress, plastic strain\"" - ) - obj.YieldPoints = [] + def onDocumentRestored(self, obj): + + # YieldPoints was (until 0.19) stored as 3 separate variables. Consolidate them if present. + yield_points = [] + if hasattr(obj, "YieldPoint1"): + if obj.YieldPoint1: + yield_points.append(obj.YieldPoint1) + obj.removeProperty("YieldPoint1") + if hasattr(obj, "YieldPoint2"): + if obj.YieldPoint2: + yield_points.append(obj.YieldPoint2) + obj.removeProperty("YieldPoint2") + if hasattr(obj, "YieldPoint3"): + if obj.YieldPoint3: + yield_points.append(obj.YieldPoint3) + obj.removeProperty("YieldPoint3") + + self.add_properties(obj) + if yield_points: + obj.YieldPoints = yield_points + + # TODO: If in the future more nonlinear options are added, update choices here. + + def add_properties(self, obj): + + # this method is called from onDocumentRestored + # thus only add and or set a attribute + # if the attribute does not exist + + if not hasattr(obj, "LinearBaseMaterial"): + obj.addProperty( + "App::PropertyLink", + "LinearBaseMaterial", + "Base", + "Set the linear material the nonlinear builds upon." + ) + + if not hasattr(obj, "MaterialModelNonlinearity"): + choices_nonlinear_material_models = ["simple hardening"] + obj.addProperty( + "App::PropertyEnumeration", + "MaterialModelNonlinearity", + "Fem", + "Set the type on nonlinear material model" + ) + obj.MaterialModelNonlinearity = choices_nonlinear_material_models + obj.MaterialModelNonlinearity = choices_nonlinear_material_models[0] + + if not hasattr(obj, "YieldPoints"): + obj.addProperty( + "App::PropertyStringList", + "YieldPoints", + "Fem", + "Set stress and strain for yield points as a list of strings, " + "each point \"stress, plastic strain\"" + ) + obj.YieldPoints = []