Third Medium Contact
This tutorial demonstrates frictionless contact simulation using the third-medium method with HuHu-LuLu Hessian-based regularization. We reproduce the FElupe ex20 benchmark: two elastic bodies approaching each other through a compliant background medium on a single mesh.
Overview
The third-medium method avoids explicit contact detection by filling the gap between bodies with a soft artificial medium. When bodies approach each other, this medium compresses and transmits contact forces naturally through the variational formulation.
Key ingredients:
- Single mesh with two material regions: stiff body and soft medium
- Neo-Hookean compressible hyperelasticity for both regions, with the medium scaled down by
- Biharmonic regularization (HuHu-LuLu) on the medium to prevent mesh distortion
- Incremental loading with non-symmetric BC elimination (
symmetric_elimination=False)
References
- G. L. Bluhm et al., "Internal contact modeling for finite strain topology optimization", Comput. Mech. 67, 1099–1114 (2021).
- A. H. Frederiksen et al., "Topology optimization of self-contacting structures", Comput. Mech. 73, 967–981 (2023).
Problem Setup
Geometry and Mesh
A structured QUAD9 mesh covers the domain :
from feax.mechanics.tmc import ThirdMediumContact, classify_medium_cells
L, H, t = 1.0, 0.5, 0.1
mesh = fe.mesh.rectangle_mesh(
Nx=33, Ny=15,
domain_x=1.1, domain_y=0.5,
ele_type='QUAD9',
)
Cells are classified as body (solid) or medium (background) from their centroid
using classify_medium_cells, which evaluates a predicate f(cx, cy) per cell (the
centroid is taken from the first n_corner_nodes nodes of each element):
is_medium = classify_medium_cells(
mesh,
lambda cx, cy: (t < cx < L and t < cy < (H - t)) or cx > L,
n_corner_nodes=4,
)
Material Parameters
Both regions use the same Neo-Hookean model but with different stiffness:
| Region | Shear modulus | Bulk modulus |
|---|---|---|
| Body | ||
| Medium |
where is the medium scaling factor:
G = 5.0 / 14.0 # body shear modulus
K = 5.0 / 3.0 # body bulk-like Lamé constant
gamma0 = 5e-7 # medium scaling (very soft void)
kr = 5e-7 # regularization prefactor
You pass the body moduli G, K and the scaling gamma0 to ThirdMediumContact.create
(below), which assembles the per-cell properties internally as
mu_cell = where(is_medium, G*gamma0, G) and lmbda_cell = where(is_medium, K*gamma0, K).
Energy Formulation
The energy density and regularization below are implemented inside the
ThirdMediumContact class — you do not write them yourself. They are reproduced here to
explain what ThirdMediumContact.create() assembles for you. Skip to
Building the Problem if you only want the usage API.
Neo-Hookean Energy Density
The compressible Neo-Hookean energy density in plane strain is (as implemented by ThirdMediumContact.get_energy_density):
where , , . The "+1" accounts for the plane-strain contribution to .
A smooth quadratic extension replaces below to prevent NaN when Newton overshoots into element inversion — a common occurrence with the extremely soft medium ():
def get_energy_density(self):
J_min = 1e-4
def safe_lnJ(J):
lnJ_min = np.log(J_min)
s = (J - J_min) / J_min
ext = lnJ_min + s - 0.5 * s ** 2
return np.where(J > J_min, np.log(J), ext)
def psi(u_grad, mu, lmbda, *_unused):
F = u_grad + np.eye(2)
C = F.T @ F
J = np.linalg.det(F)
lnJ = safe_lnJ(J)
return mu / 2.0 * (np.trace(C) + 1.0) - mu * lnJ + lmbda / 2.0 * lnJ ** 2
return psi
The energy density takes mu and lmbda as per-cell arguments from TracedParams, so the same function serves both body and medium cells.
HuHu-LuLu Biharmonic Regularization
Without regularization, the soft medium mesh distorts severely under compression. The HuHu-LuLu regularization penalizes displacement curvature in the medium: