Skip to content

liblaf.apple.warp.energies.elastic.hyperelastic.func ¤

Functions:

I1 ¤

I1(S: mat33) -> scalar

\(I_1\).

\[ I_1 = \operatorname{tr}(R^T F) = \operatorname{tr}(S) \]
Source code in src/liblaf/apple/warp/energies/elastic/hyperelastic/func/_identities.py
 9
10
11
12
13
14
15
16
17
@wp.func
def I1(S: mat33) -> scalar:
    r"""$I_1$.

    $$
    I_1 = \operatorname{tr}(R^T F) = \operatorname{tr}(S)
    $$
    """
    return wp.trace(S)

I2 ¤

I2(F: mat33) -> scalar

\(I_2\).

\[ I_2 = I_C = \|F\|_F^2 \]
Source code in src/liblaf/apple/warp/energies/elastic/hyperelastic/func/_identities.py
20
21
22
23
24
25
26
27
28
@wp.func
def I2(F: mat33) -> scalar:
    r"""$I_2$.

    $$
    I_2 = I_C = \|F\|_F^2
    $$
    """
    return wp.ddot(F, F)

I3 ¤

I3(F: mat33) -> scalar

\(I_3\).

\[ I_3 = J = \det(F) \]
Source code in src/liblaf/apple/warp/energies/elastic/hyperelastic/func/_identities.py
31
32
33
34
35
36
37
38
39
@wp.func
def I3(F: mat33) -> scalar:
    r"""$I_3$.

    $$
    I_3 = J = \det(F)
    $$
    """
    return wp.determinant(F)

Qs ¤

Qs(U: mat33, V: mat33) -> tuple[mat33, mat33, mat33]
Source code in src/liblaf/apple/warp/energies/elastic/hyperelastic/func/_misc.py
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
@wp.func
@no_type_check
def Qs(U: mat33, V: mat33) -> tuple[mat33, mat33, mat33]:
    _2 = U.dtype(2.0)
    _sqrt2 = wp.sqrt(_2)
    U0 = U[:, 0]
    U1 = U[:, 1]
    U2 = U[:, 2]
    V0 = V[:, 0]
    V1 = V[:, 1]
    V2 = V[:, 2]
    Q0 = (wp.outer(U1, V0) - wp.outer(U0, V1)) / _sqrt2
    Q1 = (wp.outer(U1, V2) - wp.outer(U2, V1)) / _sqrt2
    Q2 = (wp.outer(U0, V2) - wp.outer(U2, V0)) / _sqrt2
    return Q0, Q1, Q2

dRdF_vjp ¤

dRdF_vjp(
    M: mat33,
    lambdas: vec3,
    Q0: mat33,
    Q1: mat33,
    Q2: mat33,
) -> mat33
Source code in src/liblaf/apple/warp/energies/elastic/hyperelastic/func/_misc.py
10
11
12
13
14
15
16
@wp.func
def dRdF_vjp(M: mat33, lambdas: vec3, Q0: mat33, Q1: mat33, Q2: mat33) -> mat33:
    return (
        lambdas[0] * wp.ddot(M, Q0) * Q0
        + lambdas[1] * wp.ddot(M, Q1) * Q1
        + lambdas[2] * wp.ddot(M, Q2) * Q2
    )

deformation_gradient ¤

deformation_gradient(u: mat43, dhdX: mat43) -> mat33

\(F = \pdv{u}{x} + I\).

Source code in src/liblaf/apple/warp/energies/elastic/hyperelastic/func/_deformation.py
16
17
18
19
20
@wp.func
@no_type_check
def deformation_gradient(u: mat43, dhdX: mat43) -> mat33:
    r"""$F = \pdv{u}{x} + I$."""
    return gradient(u, dhdX) + wp.identity(3, dtype=u.dtype)

deformation_gradient_jvp ¤

deformation_gradient_jvp(dhdX: mat43, p: mat43) -> mat33

\(\pdv{F}{x} p\).

Source code in src/liblaf/apple/warp/energies/elastic/hyperelastic/func/_deformation.py
23
24
25
26
27
@wp.func
@no_type_check
def deformation_gradient_jvp(dhdX: mat43, p: mat43) -> mat33:
    r"""$\pdv{F}{x} p$."""
    return wp.transpose(p) @ dhdX

deformation_gradient_vjp ¤

deformation_gradient_vjp(dhdX: mat43, p: mat33) -> mat43

\(\pdv{F}{x}^T p\).

Source code in src/liblaf/apple/warp/energies/elastic/hyperelastic/func/_deformation.py
30
31
32
33
34
@wp.func
@no_type_check
def deformation_gradient_vjp(dhdX: mat43, p: mat33) -> mat43:
    r"""$\pdv{F}{x}^T p$."""
    return dhdX @ wp.transpose(p)

g1 ¤

g1(R: mat33) -> mat33

Gradient of \(I_1\) w.r.t. \(F\).

\[ g_1 = vec(R) \]
Source code in src/liblaf/apple/warp/energies/elastic/hyperelastic/func/_gradients.py
 8
 9
10
11
12
13
14
15
16
17
@wp.func
@no_type_check
def g1(R: mat33) -> mat33:
    r"""Gradient of $I_1$ w.r.t. $F$.

    $$
    g_1 = vec(R)
    $$
    """
    return R

g2 ¤

g2(F: mat33) -> mat33

Gradient of \(I_2\) w.r.t. \(F\).

\[ g_2 = 2 vec(F) \]
Source code in src/liblaf/apple/warp/energies/elastic/hyperelastic/func/_gradients.py
20
21
22
23
24
25
26
27
28
29
@wp.func
@no_type_check
def g2(F: mat33) -> mat33:
    """Gradient of $I_2$ w.r.t. $F$.

    $$
    g_2 = 2 vec(F)
    $$
    """
    return F.dtype(2.0) * F

g3 ¤

g3(F: mat33) -> mat33

Gradient of \(I_3\) w.r.t. \(F\).

\[ g_3 = vec([f_1 \cp f_2, f_2 \cp f_0, f_0 \cp f_1]) \]
Source code in src/liblaf/apple/warp/energies/elastic/hyperelastic/func/_gradients.py
32
33
34
35
36
37
38
39
40
41
42
@wp.func
@no_type_check
def g3(F: mat33) -> mat33:
    r"""Gradient of $I_3$ w.r.t. $F$.

    $$
    g_3 = vec([f_1 \cp f_2, f_2 \cp f_0, f_0 \cp f_1])
    $$
    """
    f0, f1, f2 = F[:, 0], F[:, 1], F[:, 2]
    return wp.matrix_from_cols(wp.cross(f1, f2), wp.cross(f2, f0), wp.cross(f0, f1))

gradient ¤

gradient(u: mat43, dhdX: mat43) -> mat33

\(\pdv{u}{x}\).

Source code in src/liblaf/apple/warp/energies/elastic/hyperelastic/func/_deformation.py
 9
10
11
12
13
@wp.func
@no_type_check
def gradient(u: mat43, dhdX: mat43) -> mat33:
    r"""$\pdv{u}{x}$."""
    return wp.transpose(u) @ dhdX

h1_diag ¤

h1_diag(dhdX: mat43, g1: mat33) -> mat43

\(diag(h_1)\).

Source code in src/liblaf/apple/warp/energies/elastic/hyperelastic/func/_hess_diag.py
15
16
17
18
19
@wp.func
@no_type_check
def h1_diag(dhdX: mat43, g1: mat33) -> mat43:
    """$diag(h_1)$."""
    return math.cw_square(deformation_gradient_vjp(dhdX, g1))

h1_prod ¤

h1_prod(p: mat43, dhdX: mat43, g1: mat33) -> mat43

\(h_1 p\).

Source code in src/liblaf/apple/warp/energies/elastic/hyperelastic/func/_hess_prod.py
13
14
15
16
17
18
@wp.func
@no_type_check
def h1_prod(p: mat43, dhdX: mat43, g1: mat33) -> mat43:
    """$h_1 p$."""
    dFdxT_g = deformation_gradient_vjp(dhdX, g1)  # mat33
    return wp.ddot(dFdxT_g, p) * dFdxT_g

h1_quad ¤

h1_quad(p: mat43, dhdX: mat43, g1: mat33) -> scalar

\(p^T h_1 p\).

Source code in src/liblaf/apple/warp/energies/elastic/hyperelastic/func/_hess_quad.py
16
17
18
19
20
@wp.func
@no_type_check
def h1_quad(p: mat43, dhdX: mat43, g1: mat33) -> scalar:
    """$p^T h_1 p$."""
    return math.square(wp.ddot(deformation_gradient_jvp(dhdX, p), g1))

h2_diag ¤

h2_diag(dhdX: mat43, g2: mat33) -> mat43

\(diag(h_2)\).

Source code in src/liblaf/apple/warp/energies/elastic/hyperelastic/func/_hess_diag.py
22
23
24
25
26
@wp.func
@no_type_check
def h2_diag(dhdX: mat43, g2: mat33) -> mat43:
    """$diag(h_2)$."""
    return math.cw_square(deformation_gradient_vjp(dhdX, g2))

h2_prod ¤

h2_prod(p: mat43, dhdX: mat43, g2: mat33) -> mat43

\(h_2 p\).

Source code in src/liblaf/apple/warp/energies/elastic/hyperelastic/func/_hess_prod.py
21
22
23
24
25
26
@wp.func
@no_type_check
def h2_prod(p: mat43, dhdX: mat43, g2: mat33) -> mat43:
    """$h_2 p$."""
    dFdxT_g = deformation_gradient_vjp(dhdX, g2)  # mat33
    return wp.ddot(dFdxT_g, p) * dFdxT_g

h2_quad ¤

h2_quad(p: mat43, dhdX: mat43, g2: mat33) -> scalar

\(p^T h_2 p\).

Source code in src/liblaf/apple/warp/energies/elastic/hyperelastic/func/_hess_quad.py
23
24
25
26
27
@wp.func
@no_type_check
def h2_quad(p: mat43, dhdX: mat43, g2: mat33) -> scalar:
    """$p^T h_2 p$."""
    return math.square(wp.ddot(deformation_gradient_jvp(dhdX, p), g2))

h3_diag ¤

h3_diag(dhdX: mat43, g3: mat33) -> mat43

\(diag(h_3)\).

Source code in src/liblaf/apple/warp/energies/elastic/hyperelastic/func/_hess_diag.py
29
30
31
32
33
@wp.func
@no_type_check
def h3_diag(dhdX: mat43, g3: mat33) -> mat43:
    """$diag(h_3)$."""
    return math.cw_square(deformation_gradient_vjp(dhdX, g3))

h3_prod ¤

h3_prod(p: mat43, dhdX: mat43, g3: mat33) -> mat43

\(h_3 p\).

Source code in src/liblaf/apple/warp/energies/elastic/hyperelastic/func/_hess_prod.py
29
30
31
32
33
34
@wp.func
@no_type_check
def h3_prod(p: mat43, dhdX: mat43, g3: mat33) -> mat43:
    """$h_3 p$."""
    dFdxT_g = deformation_gradient_vjp(dhdX, g3)  # mat33
    return wp.ddot(dFdxT_g, p) * dFdxT_g

h3_quad ¤

h3_quad(p: mat43, dhdX: mat43, g3: mat33) -> scalar

\(p^T h_3 p\).

Source code in src/liblaf/apple/warp/energies/elastic/hyperelastic/func/_hess_quad.py
30
31
32
33
34
@wp.func
@no_type_check
def h3_quad(p: mat43, dhdX: mat43, g3: mat33) -> scalar:
    """$p^T h_3 p$."""
    return math.square(wp.ddot(deformation_gradient_jvp(dhdX, p), g3))

h4_diag ¤

h4_diag(
    dhdX: mat43,
    U: mat33,
    sigma: vec3,
    V: mat33,
    *,
    clamp: bool = True,
) -> mat43

\(diag(h_4)\).

Source code in src/liblaf/apple/warp/energies/elastic/hyperelastic/func/_hess_diag.py
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
@wp.func
@no_type_check
def h4_diag(
    dhdX: mat43, U: mat33, sigma: vec3, V: mat33, *, clamp: bool = True
) -> mat43:
    """$diag(h_4)$."""
    lambdas = _misc.lambdas(sigma, clamp=clamp)  # vec3
    Q0, Q1, Q2 = _misc.Qs(U, V)  # mat33, mat33, mat33
    W0 = deformation_gradient_vjp(dhdX, Q0)  # mat43
    W1 = deformation_gradient_vjp(dhdX, Q1)  # mat43
    W2 = deformation_gradient_vjp(dhdX, Q2)  # mat43
    return (
        lambdas[0] * math.cw_square(W0)
        + lambdas[1] * math.cw_square(W1)
        + lambdas[2] * math.cw_square(W2)
    )

h4_prod ¤

h4_prod(
    p: mat43,
    dhdX: mat43,
    U: mat33,
    sigma: vec3,
    V: mat33,
    *,
    clamp: bool = True,
) -> mat43

\(h_4 p\).

Source code in src/liblaf/apple/warp/energies/elastic/hyperelastic/func/_hess_prod.py
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
@wp.func
@no_type_check
def h4_prod(
    p: mat43, dhdX: mat43, U: mat33, sigma: vec3, V: mat33, *, clamp: bool = True
) -> mat43:
    """$h_4 p$."""
    lambdas = _misc.lambdas(sigma, clamp=clamp)  # vec3
    Q0, Q1, Q2 = _misc.Qs(U, V)
    dFdxT_q0 = deformation_gradient_vjp(dhdX, Q0)  # mat33
    dFdxT_q1 = deformation_gradient_vjp(dhdX, Q1)  # mat33
    dFdxT_q2 = deformation_gradient_vjp(dhdX, Q2)  # mat33
    return (
        lambdas[0] * wp.ddot(dFdxT_q0, p) * dFdxT_q0
        + lambdas[1] * wp.ddot(dFdxT_q1, p) * dFdxT_q1
        + lambdas[2] * wp.ddot(dFdxT_q2, p) * dFdxT_q2
    )

h4_quad ¤

h4_quad(
    p: mat43,
    dhdX: mat43,
    U: mat33,
    sigma: vec3,
    V: mat33,
    *,
    clamp: bool = True,
) -> scalar

\(p^T h_4 p\).

Source code in src/liblaf/apple/warp/energies/elastic/hyperelastic/func/_hess_quad.py
37
38
39
40
41
42
43
44
45
46
47
48
49
50
@wp.func
@no_type_check
def h4_quad(
    p: mat43, dhdX: mat43, U: mat33, sigma: vec3, V: mat33, *, clamp: bool = True
) -> scalar:
    """$p^T h_4 p$."""
    dFdx_p = deformation_gradient_jvp(dhdX, p)  # mat33
    lambdas = _misc.lambdas(sigma, clamp=clamp)  # vec3
    Q0, Q1, Q2 = _misc.Qs(U, V)
    return (
        lambdas[0] * math.square(wp.ddot(Q0, dFdx_p))
        + lambdas[1] * math.square(wp.ddot(Q1, dFdx_p))
        + lambdas[2] * math.square(wp.ddot(Q2, dFdx_p))
    )

h5_diag ¤

h5_diag(dhdX: mat43) -> mat43

\(diag(h_5)\).

Source code in src/liblaf/apple/warp/energies/elastic/hyperelastic/func/_hess_diag.py
54
55
56
57
58
59
60
61
62
63
64
65
66
67
@wp.func
@no_type_check
def h5_diag(dhdX: mat43) -> mat43:
    """$diag(h_5)$."""
    t0 = wp.length_sq(dhdX[0])
    t1 = wp.length_sq(dhdX[1])
    t2 = wp.length_sq(dhdX[2])
    t3 = wp.length_sq(dhdX[3])
    return dhdX.dtype(2.0) * wp.matrix_from_rows(
        wp.vector(t0, t0, t0),
        wp.vector(t1, t1, t1),
        wp.vector(t2, t2, t2),
        wp.vector(t3, t3, t3),
    )

h5_prod ¤

h5_prod(p: mat43, dhdX: mat43) -> mat43

\(h_5 p\).

Source code in src/liblaf/apple/warp/energies/elastic/hyperelastic/func/_hess_prod.py
55
56
57
58
59
60
@wp.func
@no_type_check
def h5_prod(p: mat43, dhdX: mat43) -> mat43:
    """$h_5 p$."""
    dFdx_p = deformation_gradient_jvp(dhdX, p)  # mat33
    return p.dtype(2.0) * deformation_gradient_vjp(dhdX, dFdx_p)

h5_quad ¤

h5_quad(p: mat43, dhdX: mat43) -> scalar

\(p^T h_5 p\).

Source code in src/liblaf/apple/warp/energies/elastic/hyperelastic/func/_hess_quad.py
53
54
55
56
57
58
@wp.func
@no_type_check
def h5_quad(p: mat43, dhdX: mat43) -> scalar:
    """$p^T h_5 p$."""
    dFdx_p = deformation_gradient_jvp(dhdX, p)  # mat33
    return dhdX.dtype(2.0) * math.fro_norm_square(dFdx_p)

h6_diag ¤

h6_diag(dhdX: mat43, F: mat33) -> mat43

\(diag(h_6)\).

Source code in src/liblaf/apple/warp/energies/elastic/hyperelastic/func/_hess_diag.py
70
71
72
73
74
@wp.func
@no_type_check
def h6_diag(dhdX: mat43, F: mat33) -> mat43:  # noqa: ARG001
    """$diag(h_6)$."""
    return wp.matrix(shape=(4, 3), dtype=dhdX.dtype)

h6_prod ¤

h6_prod(p: mat43, dhdX: mat43, F: mat33) -> mat43

\(h_6 p\).

Source code in src/liblaf/apple/warp/energies/elastic/hyperelastic/func/_hess_prod.py
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
@wp.func
@no_type_check
def h6_prod(p: mat43, dhdX: mat43, F: mat33) -> mat43:
    """$h_6 p$."""
    dFdx_p = deformation_gradient_jvp(dhdX, p)  # mat33
    f0 = F[:, 0]  # vec3
    f1 = F[:, 1]  # vec3
    f2 = F[:, 2]  # vec3
    p0 = dFdx_p[:, 0]  # vec3
    p1 = dFdx_p[:, 1]  # vec3
    p2 = dFdx_p[:, 2]  # vec3
    Hp = wp.matrix_from_cols(
        wp.cross(f1, p2) - wp.cross(f2, p1),
        wp.cross(f2, p0) - wp.cross(f0, p2),
        wp.cross(f0, p1) - wp.cross(f1, p0),
    )  # mat33
    return deformation_gradient_vjp(dhdX, Hp)

h6_quad ¤

h6_quad(p: mat43, dhdX: mat43, F: mat33) -> scalar

\(p^T h_6 p\).

Source code in src/liblaf/apple/warp/energies/elastic/hyperelastic/func/_hess_quad.py
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
@wp.func
@no_type_check
def h6_quad(p: mat43, dhdX: mat43, F: mat33) -> scalar:
    """$p^T h_6 p$."""
    dFdx_p = deformation_gradient_jvp(dhdX, p)  # mat33
    f0 = F[:, 0]
    f1 = F[:, 1]
    f2 = F[:, 2]
    p0 = dFdx_p[:, 0]
    p1 = dFdx_p[:, 1]
    p2 = dFdx_p[:, 2]
    return (
        wp.dot(p0, wp.cross(f1, p2) - wp.cross(f2, p1))
        + wp.dot(p1, wp.cross(f2, p0) - wp.cross(f0, p2))
        + wp.dot(p2, wp.cross(f0, p1) - wp.cross(f1, p0))
    )

lambdas ¤

lambdas(sigma: vec3, *, clamp: bool = True) -> vec3
Source code in src/liblaf/apple/warp/energies/elastic/hyperelastic/func/_misc.py
19
20
21
22
23
24
25
26
27
28
29
30
31
@wp.func
@no_type_check
def lambdas(sigma: vec3, *, clamp: bool = True) -> vec3:
    _2 = sigma.dtype(2.0)
    if clamp:
        lambda0 = _2 / wp.max(sigma[0] + sigma[1], _2)
        lambda1 = _2 / wp.max(sigma[1] + sigma[2], _2)
        lambda2 = _2 / wp.max(sigma[2] + sigma[0], _2)
    else:
        lambda0 = _2 / (sigma[0] + sigma[1])
        lambda1 = _2 / (sigma[1] + sigma[2])
        lambda2 = _2 / (sigma[2] + sigma[0])
    return wp.vector(lambda0, lambda1, lambda2)

make_activation_mat33 ¤

make_activation_mat33(activation: vec6) -> mat33
Source code in src/liblaf/apple/warp/energies/elastic/hyperelastic/func/_misc.py
34
35
36
37
38
39
40
41
@wp.func
@no_type_check
def make_activation_mat33(activation: vec6) -> mat33:
    return wp.identity(3, activation.dtype) + wp.matrix_from_rows(
        wp.vector(activation[0], activation[3], activation[4]),
        wp.vector(activation[3], activation[1], activation[5]),
        wp.vector(activation[4], activation[5], activation[2]),
    )