Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add orthotropic material properties for use in funtofem+caps2tacs #254

Merged
merged 1 commit into from
Sep 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
270 changes: 187 additions & 83 deletions tacs/caps2tacs/materials.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,28 @@ def __init__(
self,
name: str,
material_type: str,
young_modulus: float,
poisson_ratio: float,
density: float,
tension_allow: float,
compression_allow: float = None,
shear_allow: float = None,
yield_allow: float = None,
thermExpCoeff: float = None,
kappa:float=None,
specific_heat:float=None,
E1=None,
E2=None,
E3=None,
nu12=None,
nu13=None,
nu23=None,
rho=None,
cp=None,
kappa1=None,
kappa2=None,
kappa3=None,
alpha1=None,
alpha2=None,
alpha3=None,
G12=None,
G13=None,
G23=None,
T1=None,
T2=None,
C1=None,
C2=None,
S1=None,
):
"""
Material base class to wrap ESP/CAPS material inputs to TACS AIM
Expand All @@ -30,16 +42,28 @@ def __init__(
]
self._name = name
self._material_type = material_type
self._young_modulus = young_modulus
self._poisson_ratio = poisson_ratio
self._density = density
self._tension_allow = tension_allow
self._compression_allow = compression_allow
self._shear_allow = shear_allow
self._yield_allow = yield_allow
self._thermExpCoeff = thermExpCoeff
self._kappa = kappa
self._specific_heat = specific_heat
self._E1 = E1
self._E2 = E2
self._E3 = E3
self._nu12 = nu12
self._nu13 = nu13
self._nu23 = nu23
self._rho = rho
self._cp = cp
self._kappa1 = kappa1
self._kappa2 = kappa2
self._kappa3 = kappa3
self._alpha1 = alpha1
self._alpha2 = alpha2
self._alpha3 = alpha3
self._G12 = G12
self._G13 = G13
self._G23 = G23
self._T1 = T1
self._T2 = T2
self._C1 = C1
self._C2 = C2
self._S1 = S1

@property
def name(self) -> str:
Expand All @@ -56,28 +80,32 @@ def dictionary(self) -> dict:
"""
m_dict = {}
m_dict["materialType"] = self._material_type
m_dict["youngModulus"] = self._young_modulus
m_dict["poissonRatio"] = self._poisson_ratio
m_dict["density"] = self._density
m_dict["thermalExpCoeff"] = self._thermExpCoeff
m_dict["tensionAllow"] = self._tension_allow
m_dict["compressionAllow"] = self._compression_allow
m_dict["shearAllow"] = self._shear_allow
m_dict["yieldAllow"] = self._yield_allow
m_dict["kappa"] = self._kappa
m_dict["specificHeat"] = self._specific_heat
m_dict["density"] = self._rho
m_dict["specificHeat"] = self._cp
if self._kappa2 is None:
m_dict["kappa"] = self._kappa1
else:
# [KXX, KXY, KXZ, KYY, KYZ, KZZ] = [k1, 0, 0, k2, 0, k3]
m_dict["K"] = [self._kappa1, 0.0, 0.0, self._kappa2, 0.0, self._kappa3]
m_dict["thermalExpCoeff"] = self._alpha1
m_dict["thermalExpCoeffLateral"] = self._alpha2
m_dict["youngModulus"] = self._E1
m_dict["youngModulusLateral"] = self._E2
m_dict["poissonRatio"] = self._nu12
m_dict["poissonRatio23"] = self._nu23
m_dict["shearModulus"] = self._G12
m_dict["shearModulusTrans1Z"] = self._G13
m_dict["shearModulusTrans2Z"] = self._G23
m_dict["tensionAllow"] = self._T1
m_dict["tensionAllowLateral"] = self._T2
m_dict["compressionAllow"] = self._C1
m_dict["compressionAllowLateral"] = self._C2
m_dict["shearAllow"] = self._S1
# m_dict["yieldAllow"] = self._yield_allow

# return all items that are not None
return {k: v for k, v in m_dict.items() if v is not None}

@property
def young_modulus(self) -> float:
return self._young_modulus

@young_modulus.setter
def young_modulus(self, value: float):
self._young_modulus = value

def register_to(self, tacs_aim):
"""
cascaded method to register this constraint to TacsAim
Expand All @@ -90,82 +118,158 @@ class Isotropic(Material):
def __init__(
self,
name: str,
young_modulus: float,
poisson_ratio: float,
density: float,
tension_allow: float,
compression_allow: float = None,
shear_allow: float = None,
yield_allow: float = None,
thermExpCoeff: float = None,
kappa:float=None,
specific_heat:float=None,
E,
nu,
rho,
T1,
C1=None,
S1=None,
alpha=None,
kappa=None,
cp=None,
G=None,
):
"""
wrapper class for ESP/CAPS isotropic materials
"""
if G is None:
G = E / 2.0 / (1 + nu)
if C1 is None:
C1 = T1
super(Isotropic, self).__init__(
name=name,
material_type="Isotropic",
young_modulus=young_modulus,
poisson_ratio=poisson_ratio,
density=density,
tension_allow=tension_allow,
compression_allow=compression_allow,
shear_allow=shear_allow,
yield_allow=yield_allow,
thermExpCoeff=thermExpCoeff,
kappa=kappa,
specific_heat=specific_heat,
E1=E,
nu12=nu,
rho=rho,
T1=T1,
C1=C1,
S1=S1,
alpha1=alpha,
kappa1=kappa,
cp=cp,
G12=G,
)

@classmethod
def madeupium(
cls,
young_modulus=72.0e9,
poisson_ratio=0.33,
density=2.8e3,
E=72.0e9,
nu=0.33,
rho=2.8e3,
tension_allow=20.0e7,
):
return cls(
name="Madeupium",
young_modulus=young_modulus,
poisson_ratio=poisson_ratio,
density=density,
tension_allow=tension_allow,
E=E,
nu=nu,
rho=rho,
T1=tension_allow,
)

@classmethod
def aluminum(cls):
return cls(
name="aluminum",
young_modulus=70.0e9,
poisson_ratio=0.35,
density=2.7e3,
tension_allow=20.0e7,
compression_allow=20.0e7,
yield_allow=20.0e7,
thermExpCoeff=23.1e-6,
specific_heat=903,
E=70.0e9,
nu=0.35,
rho=2.7e3,
T1=20.0e7,
C1=20.0e7,
alpha=23.1e-6,
cp=903,
kappa=237,
)

@classmethod
def steel(cls):
return cls(
name="steel",
young_modulus=200.0e9,
poisson_ratio=0.30,
density=7.8e3,
tension_allow=1.0e9,
compression_allow=1.7e9,
yield_allow=0.9e9,
thermExpCoeff=11.5e-6,
E=200.0e9,
nu=0.30,
rho=7.8e3,
T1=1.0e9,
C1=1.7e9,
alpha=11.5e-6,
kappa=45,
specific_heat=420,
cp=420,
)


class Orthotropic(Material):
# TBD, ESP/CAPS doesn't accept all of E1, E2, E3, alpha_i, kappa_i, c_p, etc.
pass
def __init__(
self,
name: str,
rho,
E1,
E2,
nu12,
nu13=None,
nu23=None,
E3=None,
cp=None,
kappa1=None,
kappa2=None,
kappa3=None,
alpha1=None,
alpha2=None,
alpha3=None,
G12=None,
G13=None,
G23=None,
T1=None,
T2=None,
C1=None,
C2=None,
S1=None,
):
super(Orthotropic, self).__init__(
name=name,
material_type="Orthotropic",
E1=E1,
E2=E2,
nu12=nu12,
nu23=nu23,
rho=rho,
T1=T1,
G12=G12,
G13=G13,
G23=G23,
T2=T2,
C1=C1,
C2=C2,
S1=S1,
E3=E3,
nu13=nu13,
cp=cp,
kappa1=kappa1,
kappa2=kappa2,
kappa3=kappa3,
alpha1=alpha1,
alpha2=alpha2,
alpha3=alpha3,
)

@classmethod
def carbon_fiber(cls):
# STD CF UD (carbon-fiber fiber/epoxy resin)
# TODO : add more kinds here
return cls(
name="carbon_fiber_UD",
E1=135e9,
E2=10e9,
G12=5e9,
nu12=0.3,
T1=1.5e9,
C1=1.2e9,
T2=50e6,
C2=250e6,
S1=70e9,
alpha1=-0.3e-6,
alpha2=28e-6,
rho=1.6e3,
kappa1=14.5, #W/m-K
kappa2=4.8, #W/m-K
kappa3=4.8, #W/m-K
cp=1130.0 # J / kg-K
)
12 changes: 7 additions & 5 deletions tacs/caps2tacs/tacs_aim.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ class TacsAim:
only supports shell properties at the moment
"""

def __init__(self, caps_problem, comm=None, project_name="tacs", mesh_morph:bool=False):
def __init__(
self, caps_problem, comm=None, project_name="tacs", mesh_morph: bool = False
):
self.comm = comm

# geometry and design parameters to change the design of the CSM file during an optimization
Expand Down Expand Up @@ -173,13 +175,13 @@ def get_config_parameter(self, param_name: str):
@root_broadcast
def get_output_parameter(self, out_name: str):
return self.geometry.outpmtr[out_name].value

@property
def mesh_morph(self) -> bool:
return self._mesh_morph

@mesh_morph.setter
def mesh_morph(self, new_bool:bool):
def mesh_morph(self, new_bool: bool):
self._mesh_morph = new_bool

@property
Expand Down Expand Up @@ -333,7 +335,7 @@ def post_analysis(self):
"""
self.aim.postAnalysis()
return self

def unlink(self):
if self.comm.rank == 0:
self.aim.input["Mesh"].unlink()
Loading