Skip to content

Commit

Permalink
More refactoring within FEM and materials
Browse files Browse the repository at this point in the history
  • Loading branch information
Krande committed Nov 5, 2021
1 parent 4d0e2f4 commit 1e2a259
Show file tree
Hide file tree
Showing 15 changed files with 606 additions and 627 deletions.
3 changes: 2 additions & 1 deletion MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
include src/ada/sections/resources/ProfileDB.json
include src/ada/sections/resources/ProfileDB.json
include src/ada/materials/metals/resources/NLMatParams.json
5 changes: 3 additions & 2 deletions src/ada/concepts/containers.py
Original file line number Diff line number Diff line change
Expand Up @@ -480,9 +480,8 @@ def add(self, material) -> Material:
class Sections(NumericMapped):
sec_id = Counter(1)

def __init__(self, sections: Iterable[Section] = None, unique_ids=True, parent=None):
def __init__(self, sections: Iterable[Section] = None, unique_ids=True, parent: Union["Part", "Assembly"] = None):
super(Sections, self).__init__(parent=parent)
""":type parent: ada.Part"""
sections = [] if sections is None else sections
if unique_ids:
sections = list(toolz.unique(sections, key=attrgetter("name")))
Expand Down Expand Up @@ -522,6 +521,8 @@ def __getitem__(self, index):
return Sections(result) if isinstance(index, slice) else result

def __add__(self, other: Sections):
if self.parent is None:
raise ValueError()
for sec in other:
sec.parent = self.parent
other.renumber_id(self.max_id + 1)
Expand Down
4 changes: 2 additions & 2 deletions src/ada/concepts/levels.py
Original file line number Diff line number Diff line change
Expand Up @@ -426,8 +426,8 @@ def move_all_mats_and_sec_here_from_subparts(self):
for p in self.get_all_subparts():
self._materials += p.materials
self._sections += p.sections
p._materials = Materials()
p._sections = Sections()
p._materials = Materials(parent=p)
p._sections = Sections(parent=p)

self.sections.merge_sections_by_properties()
self.materials.merge_materials_by_properties()
Expand Down
72 changes: 72 additions & 0 deletions src/ada/fem/formats/abaqus/read/read_materials.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import re
from typing import TYPE_CHECKING

from ada import Material
from ada.core.utils import roundoff
from ada.materials.metals import CarbonSteel, PlasticityModel

from .helper_utils import _re_in

if TYPE_CHECKING:
from ada import Assembly


def get_materials_from_bulk(assembly: "Assembly", bulk_str):
re_str = (
r"(\*Material,\s*name=.*?)(?=\*|\Z)(?!\*Elastic|\*Density|\*Plastic|"
r"\*Damage Initiation|\*Damage Evolution|\*Expansion)"
)
re_materials = re.compile(re_str, _re_in)
for m in re_materials.finditer(bulk_str):
mat = mat_str_to_mat_obj(m.group())
assembly.add_material(mat)


def mat_str_to_mat_obj(mat_str) -> Material:
rd = roundoff

# Name
name = re.search(r"name=(.*?)\n", mat_str, _re_in).group(1).split("=")[-1].strip()

# Density
density_ = re.search(r"\*Density\n(.*?)(?:,|$)", mat_str, _re_in)
if density_ is not None:
density = rd(density_.group(1).strip().split(",")[0].strip(), 10)
else:
print('No density flag found for material "{}"'.format(name))
density = None

# Elastic
re_elastic_ = re.search(r"\*Elastic(?:,\s*type=(.*?)|)\n(.*?)(?:\*|$)", mat_str, _re_in)
if re_elastic_ is not None:
re_elastic = re_elastic_.group(2).strip().split(",")
young, poisson = rd(re_elastic[0]), rd(re_elastic[1])
else:
print('No Elastic properties found for material "{name}"'.format(name=name))
young, poisson = None, None

# Plastic
re_plastic_ = re.search(r"\*Plastic\n(.*?)(?:\*|\Z)", mat_str, _re_in)
if re_plastic_ is not None:
re_plastic = [tuple(x.split(",")) for x in re_plastic_.group(1).strip().splitlines()]
sig_p = [rd(x[0]) for x in re_plastic]
eps_p = [rd(x[1]) for x in re_plastic]
else:
eps_p, sig_p = None, None

# Expansion
re_zeta = re.search(r"\*Expansion(?:,\s*type=(.*?)|)\n(.*?)(?:\*|$)", mat_str, _re_in)
if re_zeta is not None:
zeta = float(re_zeta.group(2).split(",")[0].strip())
else:
zeta = 0.0

# Return material object
model = CarbonSteel(
rho=density,
E=young,
v=poisson,
zeta=zeta,
plasticity_model=PlasticityModel(eps_p=eps_p, sig_p=sig_p),
)
return Material(name=name, mat_model=model)
68 changes: 2 additions & 66 deletions src/ada/fem/formats/abaqus/read/reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,8 @@

from ada.concepts.containers import Nodes
from ada.concepts.points import Node
from ada.concepts.structural import Material
from ada.concepts.transforms import Rotation, Transform
from ada.core.utils import Counter, roundoff
from ada.core.utils import Counter
from ada.fem import (
Bc,
Constraint,
Expand All @@ -30,12 +29,12 @@
from ada.fem.formats.utils import str_to_int
from ada.fem.interactions import ContactTypes
from ada.fem.shapes import ElemType
from ada.materials.metals import CarbonSteel

from . import cards
from .helper_utils import _re_in, get_set_from_assembly, list_cleanup
from .read_elements import get_elem_from_bulk_str, update_connector_data
from .read_masses import get_mass_from_bulk
from .read_materials import get_materials_from_bulk
from .read_sections import get_connector_sections_from_bulk, get_sections_from_inp

part_name_counter = Counter(1, "Part")
Expand Down Expand Up @@ -269,17 +268,6 @@ def grab_init_props(m):
assembly.fem.add_predefined_field(grab_init_props(match))


def get_materials_from_bulk(assembly: Assembly, bulk_str):
re_str = (
r"(\*Material,\s*name=.*?)(?=\*|\Z)(?!\*Elastic|\*Density|\*Plastic|"
r"\*Damage Initiation|\*Damage Evolution|\*Expansion)"
)
re_materials = re.compile(re_str, _re_in)
for m in re_materials.finditer(bulk_str):
mat = mat_str_to_mat_obj(m.group())
assembly.add_material(mat)


def get_intprop_from_lines(assembly: Assembly, bulk_str):
"""
*Surface Interaction, name=contactProp
Expand Down Expand Up @@ -347,58 +335,6 @@ def get_instance_data(inst_name, p_ref, inst_bulk) -> InstanceData:
return InstanceData(p_ref, inst_name, inst_bulk, transform)


def mat_str_to_mat_obj(mat_str) -> Material:
rd = roundoff

# Name
name = re.search(r"name=(.*?)\n", mat_str, _re_in).group(1).split("=")[-1].strip()

# Density
density_ = re.search(r"\*Density\n(.*?)(?:,|$)", mat_str, _re_in)
if density_ is not None:
density = rd(density_.group(1).strip().split(",")[0].strip(), 10)
else:
print('No density flag found for material "{}"'.format(name))
density = None

# Elastic
re_elastic_ = re.search(r"\*Elastic(?:,\s*type=(.*?)|)\n(.*?)(?:\*|$)", mat_str, _re_in)
if re_elastic_ is not None:
re_elastic = re_elastic_.group(2).strip().split(",")
young, poisson = rd(re_elastic[0]), rd(re_elastic[1])
else:
print('No Elastic properties found for material "{name}"'.format(name=name))
young, poisson = None, None

# Plastic
re_plastic_ = re.search(r"\*Plastic\n(.*?)(?:\*|\Z)", mat_str, _re_in)
if re_plastic_ is not None:
re_plastic = [tuple(x.split(",")) for x in re_plastic_.group(1).strip().splitlines()]
sig_p = [rd(x[0]) for x in re_plastic]
eps_p = [rd(x[1]) for x in re_plastic]
else:
eps_p, sig_p = None, None

# Expansion
re_zeta = re.search(r"\*Expansion(?:,\s*type=(.*?)|)\n(.*?)(?:\*|$)", mat_str, _re_in)
if re_zeta is not None:
zeta = float(re_zeta.group(2).split(",")[0].strip())
else:
zeta = 0.0

# Return material object
model = CarbonSteel(
rho=density,
E=young,
v=poisson,
eps_p=eps_p,
zeta=zeta,
sig_p=sig_p,
plasticity_model=None,
)
return Material(name=name, mat_model=model)


def import_multiple_inps(input_files_dir):
"""
Import a set of inp files from a folder
Expand Down
36 changes: 18 additions & 18 deletions src/ada/fem/formats/abaqus/write/write_materials.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,31 +12,31 @@ def materials_str(assembly: "Assembly"):
def material_str(material: "Material") -> str:
if "aba_inp" in material.metadata.keys():
return material.metadata["aba_inp"]
if "rayleigh_damping" in material.metadata.keys():
alpha, beta = material.metadata["rayleigh_damping"]
else:
alpha, beta = None, None

no_compression = material.metadata["no_compression"] if "no_compression" in material.metadata.keys() else False
compr_str = "\n*No Compression" if no_compression is True else ""

if material.model.eps_p is not None and len(material.model.eps_p) != 0:
pl_str = "\n*Plastic\n"
pl_str += "\n".join(
["{x:>12.5E}, {y:>10}".format(x=x, y=y) for x, y in zip(material.model.sig_p, material.model.eps_p)]
)
else:
pl_str = ""

if material.name == "RP16_MAT_Low_S355_16_t_40":
print("sd")

pl_str = ""
if material.model.plasticity_model is not None:
pl_model = material.model.plasticity_model
if pl_model.eps_p is not None and len(pl_model.eps_p) != 0:
pl_str = "\n*Plastic\n"
pl_str += "\n".join(
["{x:>12.5E}, {y:>10}".format(x=x, y=y) for x, y in zip(pl_model.sig_p, pl_model.eps_p)]
)

alpha = material.model.rayleigh_damping.alpha
beta = material.model.rayleigh_damping.beta
d_str = ""
if alpha is not None and beta is not None:
d_str = "\n*Damping, alpha={alpha}, beta={beta}".format(alpha=material.model.alpha, beta=material.model.beta)
else:
d_str = ""
d_str = f"\n*Damping, alpha={alpha}, beta={beta}"

exp_str = ""
if material.model.zeta is not None and material.model.zeta != 0.0:
exp_str = "\n*Expansion\n {zeta}".format(zeta=material.model.zeta)
else:
exp_str = ""
exp_str = f"\n*Expansion\n {material.model.zeta}"

# Density == 0.0 is unsupported
density = material.model.rho if material.model.rho > 0.0 else 1e-6
Expand Down
1 change: 0 additions & 1 deletion src/ada/fem/formats/abaqus/write/writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
StepImplicit,
StepSteadyState,
)
from ada.materials import Material

from .helper_utils import get_instance_name
from .write_connectors import connector_section_str, connector_str
Expand Down
21 changes: 10 additions & 11 deletions src/ada/fem/formats/calculix/write/writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,23 +203,22 @@ def material_str(material):
no_compression = material._metadata["no_compression"] if "no_compression" in material._metadata.keys() else False
compr_str = "\n*No Compression" if no_compression is True else ""

if material.model.eps_p is not None and len(material.model.eps_p) != 0:
pl_str = "\n*Plastic\n"
pl_str += "\n".join(
["{x:>12.5E}, {y:>10}".format(x=x, y=y) for x, y in zip(material.model.sig_p, material.model.eps_p)]
)
else:
pl_str = ""
pl_str = ""
if material.model.plasticity_model is not None:
pl_model = material.model.plasticity_model
if pl_model.eps_p is not None and len(pl_model.eps_p) != 0:
pl_str = "\n*Plastic\n"
pl_str += "\n".join(
["{x:>12.5E}, {y:>10}".format(x=x, y=y) for x, y in zip(pl_model.sig_p, pl_model.eps_p)]
)

d_str = ""
if alpha is not None and beta is not None:
d_str = "\n*Damping, alpha={alpha}, beta={beta}".format(alpha=material.model.alpha, beta=material.model.beta)
else:
d_str = ""

exp_str = ""
if material.model.zeta is not None and material.model.zeta != 0.0:
exp_str = "\n*Expansion\n {zeta}".format(zeta=material.model.zeta)
else:
exp_str = ""

return f"""*Material, name={material.name}
*Elastic
Expand Down
6 changes: 3 additions & 3 deletions src/ada/fem/formats/code_aster/write/writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,11 +166,11 @@ def write_material(material: Material) -> str:
model = material.model
nl = NewLine(3, suffix=" ")

if model.plasticity_model is not None:
if model.plasticity_model is not None and model.plasticity_model.eps_p is not None:
nl_mat = "nl_mat=( \n "
eps = [e for e in model.eps_p]
eps = [e for e in model.plasticity_model.eps_p]
eps[0] = 1e-5 # Epsilon index=0 cannot be zero
nl_mat += "".join([f"{e:.4E},{s:.4E}," + next(nl) for e, s in zip(eps, model.sig_p)]) + ")"
nl_mat += "".join([f"{e:.4E},{s:.4E}," + next(nl) for e, s in zip(eps, model.plasticity_model.sig_p)]) + ")"
nl_mat += """
Traction=DEFI_FONCTION(
NOM_PARA='EPSI', NOM_RESU='SIGM', VALE=nl_mat, INTERPOL='LIN', PROL_DROITE='LINEAIRE', PROL_GAUCHE='CONSTANT'
Expand Down
4 changes: 0 additions & 4 deletions src/ada/fem/formats/sesam/read/reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,8 +171,6 @@ def get_morsmel(m) -> Material:
v=roundoff(d["ps1"]),
alpha=roundoff(d["alpha1"]),
zeta=roundoff(d["damp1"]),
sig_p=[],
eps_p=[],
sig_y=5e6,
),
metadata=d,
Expand All @@ -191,8 +189,6 @@ def get_mat(match) -> Material:
v=roundoff(d["poiss"]),
alpha=roundoff(d["damp"]),
zeta=roundoff(d["alpha"]),
sig_p=[],
eps_p=[],
sig_y=roundoff(d["yield"]),
),
parent=part,
Expand Down
4 changes: 2 additions & 2 deletions src/ada/materials/concept.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ def _import_from_ifc_mat(self, ifc_mat):
if "StrengthGrade" in props:
mat_model = CarbonSteel(grade=props["StrengthGrade"], **mat_props)
else:
mat_model = Metal(sig_u=None, eps_p=None, sig_p=None, plasticitymodel=None, **mat_props)
mat_model = Metal(sig_u=None, **mat_props)

return dict(_name=ifc_mat.Name, _mat_model=mat_model)

Expand All @@ -174,7 +174,7 @@ def name(self, value):
self._name = value.strip()

@property
def model(self):
def model(self) -> CarbonSteel:
return self._mat_model

@model.setter
Expand Down
Loading

0 comments on commit 1e2a259

Please sign in to comment.