Skip to content

yield_continuation: the documented cold-start guarantee does not hold, and the step control is effectively one-shot #473

Description

@lmoresi

Two independent defects in src/underworld3/systems/yield_continuation.py, both found
while marching the Spiegelman notch. Filed together because a maintainer will want to look
at the march loop once.

1. The cold-start claim is false on a Piecewise yield stress

The docstring promises:

Starting δ is deliberately large, where the power-mean soft-min stays bounded by the
background viscosity even as ε̇ → 0. That is what makes the first (cold) solve well posed,
and why no separate viscous pre-solve is needed.

Measured on the notch: the cold power-mean entry at delta0 = 1 fails at all four
regime points tested
. Every driver in that study needs an explicit viscous pre-solve
first, which is precisely what the docstring says is unnecessary.

Suspected cause (not yet isolated): the notch's yield stress is a sympy.Piecewise with a
deliberately unreachable τ_y in the weak inclusion, so the "bounded by the background
viscosity" argument does not hold pointwise across the material discontinuity. If that is
the cause then the claim is true only for a single-material yield law and the docstring
should say so.

tests/test_1057 covers the claim on a simpler model, where it does hold — so the test
suite does not currently see this.

2. The adaptive step is one-shot in practice

if nit <= max(2, budget // 5):
    step = max(step * step, 0.05)        # accelerate
elif nit >= 0.8 * budget:
    step = min(step ** 0.5, 0.95)        # decelerate
d *= step

With the default step_maxit = 10 (and with 13, as used in the study) budget // 5 is 2,
so the accelerate branch requires a warm δ-step to converge in ≤ 2 nonlinear
iterations
— the threshold does not scale with the budget in the regime where the budget
is actually set. In the study runs the branch fired once at entry and never again, leaving
step pinned at ×1/4 for the rest of the march.

The deeper issue is that step has no return path to the nominal down: each branch
mutates it monotonically and only the opposite branch can move it back. So a single
early decision persists for the whole march. That matches the non-monotone stalls observed
on both sweep axes.

Suggested: make the accelerate threshold a fraction of the budget with a sane floor that
is reachable for a warm step, and relax step back toward down on an ordinary
(neither-branch) success so one early sample cannot set the pace of the entire march.

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