Skip to content

feat(constitutive): power-mean yield soft-min smoother + rampable delta constant#380

Open
lmoresi wants to merge 1 commit into
developmentfrom
feature/yield-powermean
Open

feat(constitutive): power-mean yield soft-min smoother + rampable delta constant#380
lmoresi wants to merge 1 commit into
developmentfrom
feature/yield-powermean

Conversation

@lmoresi

@lmoresi lmoresi commented Jul 22, 2026

Copy link
Copy Markdown
Member

What

Adds the power-mean soft-min yield smoother and makes the soft-min softness δ a constants[] atom (runtime-rampable with no JIT recompile) on the ViscousFlowModel base class, so the visco-plastic subclasses inherit one implementation. This is the generalisable, scalable substrate for a yield homotopy toward the sharp Min surface (companion to the solver difficulty/bounded-solve tooling in #377).

Base class (ViscousFlowModel):

  • _combine_yield(eta_ve, eta_pl) -- the shared viscous/plastic combination, keyed on yield_mode: "min" (exact hard Min), "harmonic", or "softmin" (the δ soft-min in the family chosen by yield_smoother). Development's tri-modal yield_mode semantics are preserved exactly (the source branch had collapsed "softmin" into "min"; that is deliberately NOT adopted).
  • _get_yield_softness / _get_yield_offset -- δ and the onset offset held as constants[] UWexpression atoms (the offset defined symbolically in terms of δ = one symbol in the stress tensor, no tensor blow-up; one δ update repacks both). Ramping δ via the atom + solver._update_constants() forces no recompile.
  • yield_smoother property/setter -- "sqrt" (default; overshoots τ_y in the transition) or "powermean" (undershoots τ_y -- eta_eff <= Min always -- overflow-safe on geodynamic ranges).

Models (Stage 1 -- isotropic, test-covered):

  • ViscoPlasticFlowModel (Drucker-Prager): defaults to yield_mode="min" == today's exact hard Min (zero behaviour change), and gains yield_mode / yield_softness knobs so it can opt into the softmin / power-mean homotopy -- the model the hard-case DP homotopy needs.
  • ViscoElasticPlasticFlowModel (VEP): its inline sqrt soft-min routed through _combine_yield; δ moves float -> atom (value-identical); yield_softness setter syncs the atom.

Why

The power-mean smoother is the preferred, physically-admissible (undershoot) homotopy family; holding δ as a rampable constant is what makes a scalable δ-continuation cheap (no recompile per step).

Safety -- zero behaviour change at stock settings

_combine_yield at default settings is bit-identical to the previous inline law (verified numerically, diff 0.00e+00) -- δ merely moves from a baked float to a constants[] symbol evaluated to the same number. Power-mean and runtime-δ are entirely opt-in. The distrusted in-solve enable_yield_homotopy ramp driver is intentionally not part of this PR.

Scope

Stage 1 (this PR): base helper + δ-atom + power-mean, wired to the DP and VEP models. Stage 2 (follow-up): the TI-VEP / TI-VEP-Split anisotropic sites (4 sites feeding rank-4 split/lagged tensors), gated by the TI solver tests.

Tests

tests/test_1055_yield_smoother.py: δ=0 exact Min; power-mean undershoot + overflow-safety + ->Min as δ->0; smoother validation/default; runtime δ ramp no-recompile; DP opt-in.

level_1 and tier_a gate green: 402 passed, 0 failed, 0 errors (1 pre-existing unrelated xfail).

Note: 3 test_1052_VEP_stability_regression (level_2) tests are red, but they fail identically on the development baseline without this change (bisected) -- pre-existing, unrelated.

Underworld development team with AI support from Claude Code

…ta constant

Add the power-mean soft-min yield smoother and make the soft-min softness delta a
constants[] atom (runtime-rampable with no JIT recompile) on the ViscousFlowModel base
class, so the visco-plastic subclasses inherit one implementation. This is the
generalisable, scalable substrate for a yield homotopy toward the sharp Min surface.

Base class (ViscousFlowModel):
- _combine_yield(eta_ve, eta_pl): the shared viscous/plastic combination, keyed on
  yield_mode -- "min" (exact hard Min), "harmonic", or "softmin" (the delta soft-min in
  the family chosen by yield_smoother). Development's tri-modal yield_mode semantics are
  preserved exactly (unlike the source branch, which collapsed "softmin" into "min").
- _get_yield_softness / _get_yield_offset: delta and the onset offset held as constants[]
  UWexpression atoms (the offset defined symbolically in terms of delta -- one symbol in
  the stress tensor, so no tensor blow-up -- so one delta update repacks both). Ramping
  delta via the atom + solver._update_constants() forces no recompile.
- yield_smoother property/setter: "sqrt" (default; overshoots tau_y in the transition) or
  "powermean" (undershoots tau_y -- eta_eff <= Min always -- overflow-safe on geodynamic
  viscosity ranges). Selecting "powermean" from delta=0 bumps delta to 1 (s=1 harmonic
  mean), since delta=0 is the singular Min limit.

Models (Stage 1 -- isotropic, test-covered):
- ViscoPlasticFlowModel (Drucker-Prager): defaults to yield_mode="min" == today's exact
  hard Min (zero behaviour change), and GAINS yield_mode / yield_softness knobs so it can
  opt into the softmin / power-mean homotopy -- the model the hard-case DP homotopy needs.
- ViscoElasticPlasticFlowModel (VEP): its inline sqrt soft-min routed through _combine_yield;
  delta moves float -> atom (value-identical); yield_softness setter syncs the atom.

Zero behaviour change at stock settings: _combine_yield at default settings is
bit-identical to the previous inline law (delta merely moves from a baked float to a
constants[] symbol evaluated to the same number). Power-mean and runtime-delta are opt-in.
The distrusted in-solve enable_yield_homotopy ramp driver is intentionally NOT part of
this PR. TI-VEP / TI-VEP-Split (4 anisotropic sites) are a Stage-2 follow-up.

Tests: tests/test_1055_yield_smoother.py -- delta=0 exact Min; power-mean undershoot +
overflow-safety + ->Min; smoother validation/default; runtime delta ramp no-recompile;
DP opt-in. level_1/tier_a gate green (402 passed, 0 failed). VEP _combine_yield verified
bit-identical to the prior float law at defaults.

Underworld development team with AI support from Claude Code
Copilot AI review requested due to automatic review settings July 22, 2026 01:50

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants