-
Notifications
You must be signed in to change notification settings - Fork 2
/
_helpers.py
65 lines (43 loc) · 1.64 KB
/
_helpers.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
from copy import deepcopy
from functools import wraps
from .._variable import Variable
from ..math import cof, det, gradient, trace
def isochoric_volumetric_split(fun):
"""Apply the material formulation only on the isochoric part of the
multiplicative split of the deformation gradient. Optionally, if
the bulk keyword is passed, add a volumetric term."""
@wraps(fun)
def apply_iso(*args, **kwargs):
F = args[0]
J = det(F)
F_iso = J ** (-1 / 3) * F
fun_args = args[1:]
fun_kwargs = deepcopy(kwargs)
if "bulk" in kwargs.keys():
_ = fun_kwargs.pop("bulk")
W = fun(F_iso, *fun_args, **fun_kwargs)
if "bulk" in kwargs.keys():
W += volumetric(J, kwargs["bulk"])
return W
return apply_iso
def volumetric(J, bulk):
return bulk * (J - 1) ** 2 / 2
def displacement_pressure_split(fun):
"""Apply the (u/p)-framework on top of a material formulation (a function
of the deformation gradient which returns the first Piola-Kirchhoff stress)
. The additional hydrostatic stress variable `p` is attached as an
attribute `fun.p` to the augmented function."""
p = Variable("p")
@wraps(fun)
def apply_up(*args, **kwargs):
F = args[0][0]
f = fun(*args, **kwargs)
# check if function is list or tuple
if not (isinstance(f, list) or isinstance(f, tuple)):
f = [f]
P = f[0]
P_vol = trace(P @ F.T) / det(F) / 3
K = trace(gradient(P_vol, F) @ F.T) / det(F) / 3
return [P - (P_vol - p) * cof(F), (P_vol - p) / K, *f[1:]]
apply_up.p = p
return apply_up