Skip to content

Commit

Permalink
Merge pull request #61 from pyiron/get_rid_of_elaston_units
Browse files Browse the repository at this point in the history
Get rid of elaston units
  • Loading branch information
samwaseda authored Jan 3, 2025
2 parents 34582cf + 32def03 commit ba07113
Show file tree
Hide file tree
Showing 11 changed files with 153 additions and 388 deletions.
66 changes: 47 additions & 19 deletions elaston/elastic_constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
import numpy as np
from typing import Optional
from elaston import tools
from elaston.units import units, optional_units
from semantikon.typing import u
from semantikon.converter import units

__author__ = "Sam Waseda"
__copyright__ = (
Expand Down Expand Up @@ -56,17 +57,13 @@ def check_is_tensor(**kwargs):
return False


@units(
outputs=lambda C_tensor, C_11, C_12, C_13, C_22, C_33, C_44, C_55, C_66: optional_units(
C_tensor, C_11, C_12, C_13, C_22, C_33, C_44, C_55, C_66
)
)
def get_elastic_tensor_from_tensor(
C_tensor: Optional[np.ndarray] = None,
C_11: Optional[float] = None,
C_12: Optional[float] = None,
C_13: Optional[float] = None,
C_22: Optional[float] = None,
C_23: Optional[float] = None,
C_33: Optional[float] = None,
C_44: Optional[float] = None,
C_55: Optional[float] = None,
Expand All @@ -81,6 +78,7 @@ def get_elastic_tensor_from_tensor(
C_12 (float): Elastic constant
C_13 (float): Elastic constant
C_22 (float): Elastic constant
C_23 (float): Elastic constant
C_33 (float): Elastic constant
C_44 (float): Elastic constant
C_55 (float): Elastic constant
Expand All @@ -90,9 +88,7 @@ def get_elastic_tensor_from_tensor(
np.ndarray: Elastic tensor in Voigt notation
"""
if C_tensor is not None:
if np.shape(C_tensor) == (6, 6):
return np.asarray(C_tensor)
elif np.shape(C_tensor) == (3, 3, 3, 3):
if np.shape(C_tensor) in [(6, 6), (3, 3, 3, 3)]:
return tools.C_to_voigt(C_tensor)
else:
raise ValueError(
Expand All @@ -108,6 +104,8 @@ def get_elastic_tensor_from_tensor(
raise ValueError("Out of C_11, C_12, and C_44 at least two must be given")
if C_13 is None:
C_13 = C_12
if C_23 is None:
C_23 = C_12
if C_22 is None:
C_22 = C_11
if C_33 is None:
Expand All @@ -116,19 +114,34 @@ def get_elastic_tensor_from_tensor(
C_55 = C_44
if C_66 is None:
C_66 = C_44
C = _convert_elastic_constants(C_11, C_12, C_13, C_22, C_23, C_33, C_44, C_55, C_66)
return C


@units
def _convert_elastic_constants(
C_11: u(float, units="=A"),
C_12: u(float, units="=A"),
C_13: u(float, units="=A"),
C_22: u(float, units="=A"),
C_23: u(float, units="=A"),
C_33: u(float, units="=A"),
C_44: u(float, units="=A"),
C_55: u(float, units="=A"),
C_66: u(float, units="=A"),
) -> u(np.ndarray, units="=A"):
return np.array(
[
[C_11, C_12, C_13, 0, 0, 0],
[C_12, C_22, C_13, 0, 0, 0],
[C_13, C_13, C_33, 0, 0, 0],
[C_12, C_22, C_23, 0, 0, 0],
[C_13, C_23, C_33, 0, 0, 0],
[0, 0, 0, C_44, 0, 0],
[0, 0, 0, 0, C_55, 0],
[0, 0, 0, 0, 0, C_66],
]
)


@units(outputs=lambda E, nu, mu: optional_units(E, nu, mu))
def get_elastic_tensor_from_moduli(
E: Optional[float] = None,
nu: Optional[float] = None,
Expand Down Expand Up @@ -156,6 +169,15 @@ def get_elastic_tensor_from_moduli(
"Out of Young's modulus, Poisson's ratio, and shear modulus"
" at least two must be given"
)
return _convert_elastic_moduli(E, nu, mu)


@units
def _convert_elastic_moduli(
E: u(float, units="=A"),
nu: u(float, units="=A"),
mu: u(float, units="=A"),
) -> u(np.ndarray, units="=A"):
return np.linalg.inv(
[
[1 / E, -nu / E, -nu / E, 0, 0, 0],
Expand All @@ -168,7 +190,6 @@ def get_elastic_tensor_from_moduli(
)


@units(outputs=lambda C: C.u)
def get_voigt_average(C):
"""
Get the Voigt average of the elastic constants
Expand All @@ -185,7 +206,18 @@ def get_voigt_average(C):
return dict(zip(["C_11", "C_12", "C_44"], tools.voigt_average(C_11, C_12, C_44)))


@units(outputs=lambda C: C.u)
@units
def _get_reuss_average_values(
C: u(np.ndarray, units="=A")
) -> u(np.ndarray, units="=A"):
S = np.linalg.inv(C)
S[3:, 3:] /= 4
S = get_voigt_average(S)
S = get_elastic_tensor_from_tensor(**S)
C = np.linalg.inv(S)
return C


def get_reuss_average(C):
"""
Get the Reuss average of the elastic constants
Expand All @@ -196,11 +228,7 @@ def get_reuss_average(C):
Returns:
dict: Reuss average
"""
S = np.linalg.inv(C)
S[3:, 3:] /= 4
S = get_voigt_average(S)
S = get_elastic_tensor_from_tensor(**S)
C = np.linalg.inv(S)
C = _get_reuss_average_values(C)
return dict(zip(["C_11", "C_12", "C_44"], [C[0, 0], C[0, 1], C[3, 3] / 4]))


Expand Down
7 changes: 3 additions & 4 deletions elaston/linear_elasticity.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,10 +160,9 @@ def get_elastic_tensor(self, voigt=False, rotate=True):

def get_compliance_tensor(self, rotate=True, voigt=False):
"""Compliance matrix in Voigt notation."""
S = np.linalg.inv(self.get_elastic_tensor(voigt=True, rotate=rotate))
if voigt:
return S
return tools.C_from_voigt(S, inverse=True)
return tools.get_compliance_tensor(
self.get_elastic_tensor(voigt=True, rotate=rotate), voigt=voigt
)

def get_zener_ratio(self):
"""
Expand Down
20 changes: 19 additions & 1 deletion elaston/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ def C_to_voigt(C_in: u(np.ndarray, units="=C")) -> u(np.ndarray, units="=C"):
Returns:
numpy.ndarray: Elastic tensor in Voigt notation.
"""
if np.shape(C_in) == (6, 6):
return np.asarray(C_in)
C = np.zeros((6, 6))
for i in range(3):
for j in range(i + 1):
Expand All @@ -134,7 +136,12 @@ def C_to_voigt(C_in: u(np.ndarray, units="=C")) -> u(np.ndarray, units="=C"):
return C


def voigt_average(C_11: float, C_12: float, C_44: float):
@units
def voigt_average(
C_11: u(float, units="=C"),
C_12: u(float, units="=C"),
C_44: u(float, units="=C"),
) -> u(np.ndarray, units="=C"):
"""Make isotropic elastic tensor from C_11, C_12, and C_44."""
return np.array([[3, 2, 4], [1, 4, -2], [1, -1, 3]]) / 5 @ [C_11, C_12, C_44]

Expand Down Expand Up @@ -206,3 +213,14 @@ def _rotate_tensor(tensor, orientation, inverse, axes=None):
*len(axes) * [orthonormalize(orientation)],
v,
).reshape(tensor.shape)


@units
def get_compliance_tensor(
elastic_tensor: u(np.ndarray, units="=C"),
voigt: bool = False,
) -> u(np.ndarray, units="=1/C"):
S = np.linalg.inv(elastic_tensor)
if voigt:
return S
return C_from_voigt(S, inverse=True)
Loading

0 comments on commit ba07113

Please sign in to comment.