Skip to content

shear_viscosity_min: the floor's rounding scale is tied to yield_mode (and the VEP path silently skips it) #472

Description

@lmoresi

What

Constitutive_Model._apply_floor (src/underworld3/constitutive_models.py:1160) picks the
rounding scale for a viscosity/yield-stress floor from yield_mode:

rounding = 0 if getattr(self, "_yield_mode", "min") == "min" \
    else self._get_yield_softness() * floor
return uw.maths.smooth_max(value, floor, rounding)

Two consequences, and they are the two halves of the same design gap — the floor has no
smoothing parameter of its own.

1. Under yield_mode="min" the floor is a hard sympy.Max. That is correct for the
frozen/Picard tangent, but consistent_jacobian=True differentiates through the kink and
the solve dies immediately. Measured on the Spiegelman notch, isolated with a
floor-on/off × Newton/frozen 2×2 — the only failing cell is (floor on, Newton), at
nl=0, DIVERGED_LINEAR_SOLVE. So a user who sets a physically sensible viscosity floor
silently loses the consistent tangent.

2. Under yield_mode="softmin" the rounding is δ·floor, so it vanishes as δ→0.
The floor is smooth at the start of a yield homotopy and hard at the end — i.e. the
smoothing disappears exactly where the march is trying to land. δ is the yield corner's
regularisation parameter; the floor is a different corner and should not inherit it.

Why it matters now

A viscosity floor that is relaxed toward zero is one of the classical continuation
routes for viscoplastic Stokes (it bounds the plastic viscosity from below and is then
removed — structurally the same idea as the Perzyna-style rate term ξ). That route cannot
be measured against the soft-min homotopies at all while (1) forces it onto the Picard
tangent and (2) couples its smoothing to the parameter being marched.

Suggested shape of a fix

Give the floor its own rounding scale rather than deriving one from yield_mode:

  • an explicit smoothing parameter on the floor (absolute, or relative to the floor with
    its own coefficient), defaulting to 0 so today's min behaviour is unchanged;
  • _apply_floor uses that parameter regardless of yield_mode.

There is a related TODO(DESIGN) already in the same function (lines 1180-1186) about the
relative rounding collapsing for a tension cutoff at floor = 0 — the two want settling
together, since both are "this corner has no length scale of its own".

Underworld development team with AI support from Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions