sdf.measure.mass.material_mass

sdf.measure.mass.material_mass(
    sdf,
    points=None,
    cell_volume=None,
    *,
    bounds=(-3, -3, -3),
    size=(6, 6, 6),
    resolution=50,
    epsilon=0.01,
)

Estimate the mass of an SDF from its material field, as a JAX scalar.

The mass counterpart of :func:~cadjoint.sdf.measure.volume.volume, and deliberately the same integral: the smooth interior indicator sigma(-d/eps) is weighted by the density the scene’s material field reports at each sample point. It therefore reduces to rho * volume for a single-material body and picks up the real per-region densities for a multi-material one. Because the material field blends smoothly across CSG interfaces, the result is differentiable with respect to the shape parameters that move those interfaces and with respect to any density marked free.

Use it to regularize an optimization by mass rather than by volume. For a single material the two differ only by a constant; as soon as a design can trade copper for aluminium, mass is the quantity that actually matters. A scene that already regularizes on its own sample lattice swaps in directly::

# volume regularizer
cell_volume * jnp.sum(jax.nn.sigmoid(-sdf(cells) / 0.03))
# the same thing, weighted by what each cell is made of
material_mass(scene, cells, cell_volume, epsilon=0.03)

A mesh-based counterpart — exact on the elements a study solved on, rather than on a sampling lattice — is :func:cadjoint.fem.properties.total_mass.

Parameters

Name Type Description Default
sdf SDF The SDF to measure; its materials must specify a density. required
points Array | None Optional (M, 3) sample points. When omitted, samples are taken on the regular lattice given by bounds / size / resolution, exactly like volume. None
cell_volume float | None Volume each sample stands for. Required with points; derived from the lattice otherwise. None
bounds tuple[float, float, float] Lower corner (x, y, z) of the sampling box (lattice mode). (-3, -3, -3)
size tuple[float, float, float] Extent (dx, dy, dz) of the sampling box (lattice mode). (6, 6, 6)
resolution int Samples per axis, resolution**3 total (lattice mode). 50
epsilon float Smoothing width. Smaller -> sharper / more accurate; larger -> smoother gradients. 0.01

Returns

Name Type Description
Array Differentiable scalar mass estimate in kg, for geometry in metres and
Array densities in kg/m^3.

Raises

Name Type Description
ValueError If any material in the tree does not specify a density (reported by name, rather than silently returning NaN), or if points is given without cell_volume.