simkit.energies.stable_neo_hookean#
Smith-Goes-Kim stable Neo-Hookean elastic energy.
Implements the final stable Neo-Hookean formulation from Smith, de Goes, and Kim, “Stable Neo-Hookean Flesh Simulation” (TOG / SIGGRAPH 2018): https://dl.acm.org/doi/10.1145/3180491
Per-element energy density:
- psi(F) = (mu / 2) * (I_C - dim)
(mu / 2) * log(I_C + 1)
(lam / 2) * (det(F) - alpha)**2
alpha = 1 + dim * mu / ((dim + 1) * lam) (dim-dependent shift) I_C = ||F||_F**2 = sum_{i,j} F_{ij}**2
The alpha shift makes the rest configuration (F = I) a critical
point of the energy: dpsi/dF |_{F=I} = 0. Unlike Macklin-Mueller, the
rest energy psi(F=I) is a non-zero constant (this is a feature of the
formulation, not a bug). The log term penalises shrink toward F = 0
without diverging there, so the energy remains finite even at collapsed
configurations – the “stable” property of the paper.
Follows the standardized three-tier layout (see simkit.energies.arap
for the reference). This energy has only the deformation gradient (F)
representation, so there is no _S tier:
- Element tier (
*_element_F) Per-element density and derivative blocks. Material parameters
muandlamonly: no quadrature weightvol, no summation, no operator.- Global explicit tier (
*_x) Takes a prebuilt deformation Jacobian
Jand weightsvol, calls the element tier, weights, and assembles.- Self-contained tier (no suffix)
Builds
Jandvolfrom rest geometry(X, T).
Notes
Closed-form gradient and Hessian derived symbolically by
scripts/derive_stable_neo_hookean.py. The mat2py ordering helpers
reindex from the column-major (MATLAB/C++) flat layout to the row-major
F layout used throughout the library.
Functions#
|
Per-element Smith-Goes-Kim stable Neo-Hookean energy density. |
|
Per-element first Piola-Kirchhoff stress (gradient w.r.t. |
|
Per-element Hessian of the density w.r.t. |
|
Assembled stable Neo-Hookean energy at positions |
|
Assembled stable Neo-Hookean gradient w.r.t. positions |
|
Assembled stable Neo-Hookean Hessian w.r.t. positions |
|
Assembled stable Neo-Hookean energy at displacement |
|
Assembled stable Neo-Hookean gradient w.r.t. displacement |
|
Assembled stable Neo-Hookean Hessian w.r.t. displacement |
|
Stable Neo-Hookean energy, building the operator and weights from rest geometry. |
|
Stable Neo-Hookean gradient, building the operator and weights from rest geometry. |
|
Stable Neo-Hookean Hessian, building the operator and weights from rest geometry. |
Module Contents#
- simkit.energies.stable_neo_hookean.stable_neo_hookean_energy_element_F(F: numpy.ndarray, mu: numpy.ndarray, lam: numpy.ndarray) numpy.ndarray#
Per-element Smith-Goes-Kim stable Neo-Hookean energy density.
- Parameters:
- Returns:
psi – Per-element energy densities. No quadrature weighting applied. Note:
psi(F=I)is a non-zero constant; the rest state is a stationary point (gradient zero) but not the zero of the energy.- Return type:
np.ndarray (t, 1)
- simkit.energies.stable_neo_hookean.stable_neo_hookean_gradient_element_F(F: numpy.ndarray, mu: numpy.ndarray, lam: numpy.ndarray) numpy.ndarray#
Per-element first Piola-Kirchhoff stress (gradient w.r.t.
F).- Parameters:
- Returns:
P – Per-element PK1 stress blocks. No quadrature weighting applied.
- Return type:
- simkit.energies.stable_neo_hookean.stable_neo_hookean_hessian_element_F(F: numpy.ndarray, mu: numpy.ndarray, lam: numpy.ndarray) numpy.ndarray#
Per-element Hessian of the density w.r.t.
F(vectorized blocks).- Parameters:
- Returns:
H – Per-element Hessian blocks in vectorized
Flayout. No quadrature weighting applied. Not PSD-projected; projection happens in the global tier.- Return type:
np.ndarray (t, dim*dim, dim*dim)
- simkit.energies.stable_neo_hookean.stable_neo_hookean_energy_x(X: numpy.ndarray, J: scipy.sparse.spmatrix, mu: numpy.ndarray, lam: numpy.ndarray, vol: numpy.ndarray) float#
Assembled stable Neo-Hookean energy at positions
X.- Parameters:
X (np.ndarray (n, dim)) – Current vertex positions.
J (scipy.sparse matrix (t*dim*dim, n*dim)) – Deformation Jacobian.
mu (np.ndarray (t, 1)) – Per-element shear modulus.
lam (np.ndarray (t, 1)) – Per-element first Lame parameter.
vol (np.ndarray (t, 1)) – Per-element quadrature weights.
- Returns:
E – Total stable Neo-Hookean energy.
- Return type:
- simkit.energies.stable_neo_hookean.stable_neo_hookean_gradient_x(X: numpy.ndarray, J: scipy.sparse.spmatrix, mu: numpy.ndarray, lam: numpy.ndarray, vol: numpy.ndarray) numpy.ndarray#
Assembled stable Neo-Hookean gradient w.r.t. positions
X.- Parameters:
X (np.ndarray (n, dim)) – Current vertex positions.
J (scipy.sparse matrix (t*dim*dim, n*dim)) – Deformation Jacobian.
mu (np.ndarray (t, 1)) – Per-element shear modulus.
lam (np.ndarray (t, 1)) – Per-element first Lame parameter.
vol (np.ndarray (t, 1)) – Per-element quadrature weights.
- Returns:
g – Assembled energy gradient.
- Return type:
np.ndarray (n*dim, 1)
- simkit.energies.stable_neo_hookean.stable_neo_hookean_hessian_x(X: numpy.ndarray, J: scipy.sparse.spmatrix, mu: numpy.ndarray, lam: numpy.ndarray, vol: numpy.ndarray, psd: bool = True) scipy.sparse.spmatrix#
Assembled stable Neo-Hookean Hessian w.r.t. positions
X.- Parameters:
X (np.ndarray (n, dim)) – Current vertex positions.
J (scipy.sparse matrix (t*dim*dim, n*dim)) – Deformation Jacobian.
mu (np.ndarray (t, 1)) – Per-element shear modulus.
lam (np.ndarray (t, 1)) – Per-element first Lame parameter.
vol (np.ndarray (t, 1)) – Per-element quadrature weights.
psd (bool, optional) – If
True(default), project each per-element block to the nearest positive semi-definite matrix before assembly.
- Returns:
Q – Assembled energy Hessian.
- Return type:
scipy.sparse.csc_matrix (n*dim, n*dim)
- simkit.energies.stable_neo_hookean.stable_neo_hookean_energy_u(u: numpy.ndarray, J: scipy.sparse.spmatrix, Jx_bar: numpy.ndarray, mu: numpy.ndarray, lam: numpy.ndarray, vol: numpy.ndarray) float#
Assembled stable Neo-Hookean energy at displacement
ufrom a referencex_bar.Equivalent to
stable_neo_hookean_energy_x()evaluated atx_bar + ubut avoids recomputingJ @ x_baron every call. The referencex_baris arbitrary (not required to be the rest pose).- Parameters:
u (np.ndarray (n, dim)) – Displacement from the reference configuration.
J (scipy.sparse matrix (t*dim*dim, n*dim)) – Deformation Jacobian.
Jx_bar (np.ndarray (t*dim*dim, 1)) – Precomputed
J @ x_bar.reshape(-1, 1)– the flattened deformation gradient at the reference configuration.mu (np.ndarray (t, 1)) – Per-element shear modulus.
lam (np.ndarray (t, 1)) – Per-element first Lame parameter.
vol (np.ndarray (t, 1)) – Per-element quadrature weights.
- Returns:
E – Total stable Neo-Hookean energy.
- Return type:
- simkit.energies.stable_neo_hookean.stable_neo_hookean_gradient_u(u: numpy.ndarray, J: scipy.sparse.spmatrix, Jx_bar: numpy.ndarray, mu: numpy.ndarray, lam: numpy.ndarray, vol: numpy.ndarray) numpy.ndarray#
Assembled stable Neo-Hookean gradient w.r.t. displacement
u.Because
dF/du = J(the same asdF/dX), this returns the same assembled vector asstable_neo_hookean_gradient_x()atx_bar + u.- Parameters:
u (np.ndarray (n, dim)) – Displacement from the reference configuration.
J (scipy.sparse matrix (t*dim*dim, n*dim)) – Deformation Jacobian.
Jx_bar (np.ndarray (t*dim*dim, 1)) – Precomputed
J @ x_bar.reshape(-1, 1).mu (np.ndarray (t, 1)) – Per-element shear modulus.
lam (np.ndarray (t, 1)) – Per-element first Lame parameter.
vol (np.ndarray (t, 1)) – Per-element quadrature weights.
- Returns:
g – Assembled energy gradient.
- Return type:
np.ndarray (n*dim, 1)
- simkit.energies.stable_neo_hookean.stable_neo_hookean_hessian_u(u: numpy.ndarray, J: scipy.sparse.spmatrix, Jx_bar: numpy.ndarray, mu: numpy.ndarray, lam: numpy.ndarray, vol: numpy.ndarray, psd: bool = True) scipy.sparse.spmatrix#
Assembled stable Neo-Hookean Hessian w.r.t. displacement
u.- Parameters:
u (np.ndarray (n, dim)) – Displacement from the reference configuration.
J (scipy.sparse matrix (t*dim*dim, n*dim)) – Deformation Jacobian.
Jx_bar (np.ndarray (t*dim*dim, 1)) – Precomputed
J @ x_bar.reshape(-1, 1).mu (np.ndarray (t, 1)) – Per-element shear modulus.
lam (np.ndarray (t, 1)) – Per-element first Lame parameter.
vol (np.ndarray (t, 1)) – Per-element quadrature weights.
psd (bool, optional) – If
True(default), project each per-element block to the nearest positive semi-definite matrix before assembly.
- Returns:
Q – Assembled energy Hessian.
- Return type:
scipy.sparse.csc_matrix (n*dim, n*dim)
- simkit.energies.stable_neo_hookean.stable_neo_hookean_energy(X: numpy.ndarray, T: numpy.ndarray, mu: numpy.ndarray, lam: numpy.ndarray, U: numpy.ndarray | None = None) float#
Stable Neo-Hookean energy, building the operator and weights from rest geometry.
- Parameters:
X (np.ndarray (n, dim)) – Rest vertex positions. Used to build
Jandvol.T (np.ndarray (t, dim+1)) – Element connectivity.
mu (np.ndarray (t, 1)) – Per-element shear modulus.
lam (np.ndarray (t, 1)) – Per-element first Lame parameter.
U (np.ndarray (n, dim), optional) – Current vertex positions. Defaults to
X.
- Returns:
E – Total stable Neo-Hookean energy.
- Return type:
- simkit.energies.stable_neo_hookean.stable_neo_hookean_gradient(X: numpy.ndarray, T: numpy.ndarray, mu: numpy.ndarray, lam: numpy.ndarray, U: numpy.ndarray | None = None) numpy.ndarray#
Stable Neo-Hookean gradient, building the operator and weights from rest geometry.
- Parameters:
- Returns:
g – Assembled energy gradient.
- Return type:
np.ndarray (n*dim, 1)
- simkit.energies.stable_neo_hookean.stable_neo_hookean_hessian(X: numpy.ndarray, T: numpy.ndarray, mu: numpy.ndarray, lam: numpy.ndarray, U: numpy.ndarray | None = None, psd: bool = True) scipy.sparse.spmatrix#
Stable Neo-Hookean Hessian, building the operator and weights from rest geometry.
- Parameters:
X (np.ndarray (n, dim)) – Rest vertex positions.
T (np.ndarray (t, dim+1)) – Element connectivity.
mu (np.ndarray (t, 1)) – Per-element shear modulus.
lam (np.ndarray (t, 1)) – Per-element first Lame parameter.
U (np.ndarray (n, dim), optional) – Current vertex positions. Defaults to
X.psd (bool, optional) – Project per-element blocks to PSD before assembly. Default
True.
- Returns:
Q – Assembled energy Hessian.
- Return type:
scipy.sparse.csc_matrix (n*dim, n*dim)