Skip to content

Integration-point stress history grows an inlet instability when dt is halved (Wi 5 cylinder) #737

Description

@lmoresi

On the viscoelastic DFG cylinder (pure Maxwell, Wi 5, 1/20 mesh, DEVSS eta_a = nu/4, EulerianSUPG momentum) the integration_point stress history is stable at dt = 1/120 for 240 steps and grows an instability at dt = 1/240 that starts at the inlet, not at the cylinder. The eulerian (grid) history at the same two time steps is unchanged to 0.7% in drag.

Wi 5, 1/20, drag window t = 0.67 to 1, near-cylinder stress L2, max stress peak:

history dt cd near L2 peak max
grid 1/120 1.112 0.0034 0.109
grid 1/240 1.120 0.0036 0.116
IP 1/120 1.193 0.0033 0.090
IP 1/240 0.932 0.0347 2.281

Stress peak on the IP dt = 1/240 run by step (dt = 1/240, so step 240 is t = 1): 140: 0.15, 160: 0.27, 180: 0.49, 200: 1.04, 220: 1.60, 240: 2.28. Doubling every ~25 steps, still growing at the end of the run. The stress invariant frames show it as a faceted, cell-scale stress structure attached to the inlet boundary and spreading downstream to the cylinder; the grid run is clean there.

Candidate mechanism, not yet tested. The trace-back flavours do not use inflow_value; a departure point that lands outside the domain is restored to the boundary and takes the transported field's value there (docstring on inflow_value). At the inlet that is an exact carry of the boundary value from the committed flux, with no relaxation applied on the way, so a boundary node whose stress is above the relaxed inflow stress feeds itself through the memory term. The same exact-carry-at-a-boundary mechanism is the candidate for #735 at the no-slip wall. The grid history is clean because it has a real inflow condition (-uw_stress_inflow 1 in the benchmark script, the relaxed stress of the incoming flow).

Predictions being tested: the nodal trace-back at the same dt and Wi should show the same inlet growth (same boundary carry); the IP history at Wi 1 and dt = 1/240 should not, or much more slowly (relaxation per step is five times stronger).

Runs: ~/+Simulations/stress_transport/cylinder/{w5_grid,w5dt_grid,w5_ip,w5dt_ip}, script run_wi5_dt.sh; frames frames_w5dt_tauII (steps 120, 168, 232). Worktree branch feature/levelset-supg at b5bfc29.

Activity

  1. lmoresi commented on Sep 13, 2026

    @lmoresi
    MemberAuthor

    Discriminators run (1/20, dt = 1/240, DEVSS eta_a = nu/4, 240 steps to t = 1). Stress peak by step:

    run 100 140 180 220 240
    IP, Wi 5 0.087 0.146 0.493 1.602 2.281
    nodal, Wi 5 0.178 0.268 0.330 0.365 0.371
    IP, Wi 1 0.175 0.242 0.252 0.254 0.254
    grid, Wi 5 0.088 0.099 0.112 0.116 0.114

    The nodal trace-back at the same dt and Wi does not grow, so the boundary-carry candidate in the report above is not the mechanism: the clamp at the inlet is shared by both trace-back flavours and only the integration-point one grows. The IP history at Wi 1 does not grow either. The growth needs all three of: the integration-point sampling, the halved time step (Courant about 0.3 at the inlet centre instead of 0.6), and the long relaxation time (per-step retention 0.992 at Wi 5 against 0.958 at Wi 1).

    That is the low-Courant growing mode of the integration-point scheme (#703 analysis: inter-cell aliasing of the shifted sampled field, a creep of ~1e-3 per step on the scalar problem) with the viscoelastic memory term as its amplifier: whatever the transport gains at grid scale is re-injected almost in full at high Wi, which turns a creep into a doubling every ~25 steps. It shows at the inlet first, where the flow is unidirectional and the stress signal is smallest, so the mode is not masked.

    The damping the #703 analysis calls for, kappa_stab = eps h^2 / (pi^2 dt), has no diffusion term to attach to in a stress history; the analogue here is a smoothing weight on the per-step commit projection (SNES_MultiComponent_Projection, currently smoothing 0). A run with that weight set from the formula is the confirming test, and if it holds the option belongs with the stabilisation contributions being collected on the planning list, off by default.

  2. lmoresi commented on Sep 13, 2026

    @lmoresi
    MemberAuthor

    Ruling (Louis): the integration-point history is operated at Courant ~1, as settled for the scalar case, and the damping term is not the remedy — it was not liked then and any use of it needs a careful look first. Below Courant 1 the scheme is to be treated with care, more so with a memory term. For convergence checks on this history, refine h and dt together at fixed Courant rather than halving dt alone. The grid history is unaffected by dt and remains the reference for a dt sweep.

  3. lmoresi commented on Sep 14, 2026

    @lmoresi
    MemberAuthor

    Integrator check. ETD-1 on the integration-point history reproduces BDF-1 step for step: flat at dt 1/120 for 240 steps at Wi 2, 5 and 10, and at Wi 5, dt 1/240 the same growth with the same doubling time (stress peak 0.14 to 2.10 over steps 140 to 240, against 0.15 to 2.28 for BDF-1). Consistent with the mechanism as stated: the amplifier is the per-step retention of the carried stress, and e^{-dt/lambda} and lambda/(lambda+dt) agree to four digits there. The integrator is an accuracy lever on this history, not a stability one.

  4. lmoresi commented on Sep 14, 2026

    @lmoresi
    MemberAuthor

    Order 2 on the integration-point history, revisited. BDF-2 on IP at Wi 5, dt 1/120 doubles every ~10 steps from step 60 (peak 5.06 by step 120) where BDF-1 and ETD-1 are flat. ETD-2 with a traced forcing history (5e1266e: the strain rate sampled at the same departure point as the stress) is flat for 240 steps at the same settings, peak 0.09 throughout. So the second level itself is not the problem; extrapolating the stress across two levels with opposite-sign weights is. The Courant floor of this history is unchanged by the integrator (ETD-1 = BDF-1 step for step at dt 1/240), and order 2 is now available on it without lowering that floor.

  5. lmoresi commented on Sep 15, 2026

    @lmoresi
    MemberAuthor

    Cross-reference #745: on a plain box channel with no cylinder the integration-point history grows at the inlet from t ~ 0.8 at Wi 1 and Wi 5, at dt 1/60 and 1/120 alike and with DEVSS off, while nodal and grid are stable. That inlet growth is dt-independent there, so it is a different mechanism from the low-Courant mode discussed here, though the dt 1/240 cylinder case above also grew at the inlet first.

  6. lmoresi commented on Sep 16, 2026

    @lmoresi
    MemberAuthor

    A benchmark with an exact reference (Waters & King 1970 start-up, El = 1, beta = 0) sharpens this from "do not halve dt alone" to a monotone degradation with a mechanism.

    All at 1/32, the same mesh, only the step changing:

    dt Courant peak settles to ripple (t 7-10)
    0.04 1.28 0.95757 0.50493 0.0203
    0.02 0.64 0.96949 0.49038 0.0165
    0.01 0.32 0.97830 0.37367 0.2786
    0.005 0.16 diverged at t 3.02
    reference 0.99880 0.50550 0.0230

    Clean, clean, bounded ringing, divergence. The mesh is not involved: 1/16 and 1/32 at dt = 0.02 agree to four digits (0.96955 / 0.96949).

    Integrator-independent, as this issue says. At 1/32, dt = 0.01, ETD-1 rings identically to BDF-1 (peak 0.97598 vs 0.97830, settles to 0.37644 vs 0.37367, ripple 0.277 vs 0.279). At dt/lambda = 0.01 the two retention factors differ by 5e-5, so there is nothing for the integrator to change.

    Proposed mechanism. The integration-point history stores at quadrature points and must rebuild its field from a per-cell fit to be sampled at a departure point. That fit error is spatial, so it is injected once per step and is roughly independent of dt, while relaxation only damps what is already present, by exp(-dt/lambda) per step. For dt << lambda the noise floor is then ~ eps*lambda/dt: halving the step doubles it. Beyond some point injection outruns damping and bounded ringing becomes growth, which is the 0.01 -> 0.005 transition above.

    The control that makes the case. The nodal trace-back on the same problem, same mesh, same steps:

    dt peak settles to ripple
    0.01 0.97835 0.50537 0.0221
    0.005 0.98468 0.50543 0.0223

    It converges first order in dt toward a spatial floor near 0.8% of the peak, with the settled value and the physical ripple unmoved. Waters & King is unidirectional, so the stress is x-independent while the trace-back displacement is purely in x: exact transport is the identity, and a nodal interpolation reproduces a field constant along the displacement direction exactly — zero injection. The integration-point reconstruction does not, which is the whole difference.

    If that is right, the fix is on the reconstruction (a representation that is exact for the fields it is asked to carry, or an update that does not round-trip through a fit every step), not on the integrator and not on the timestep heuristic.

  7. lmoresi commented on Sep 20, 2026

    @lmoresi
    MemberAuthor

    Diagnosis update (2026-09-20), Waters & King 1/32, dt 0.01, and the confined cylinder.

    • Both trace-back flavours store the stress after every solve by the same global L2 projection onto continuous P1; the IP flavour only samples that field at the quadrature points instead of the vertices. Nothing is carried at the points between steps.
    • The per-cell element null space of the point values is real and grows with the blow-up, but removing it every step changes nothing to six digits over 500 steps (regular and irregular meshes). It is a symptom, not the driver.
    • Private nodes per cell (continuous=False, degree 1 and 2) diverge by t 2 at 1/16, dt 0.0125. Shared vertices are what damp the inter-cell jump mode.
    • DEVSS at eta_a = eta_p does not affect the ringing.
    • A Laplacian term in the store projection does: alpha ≈ gamma·dt·(h/pi)^2, gamma the measured growth rate (2.4 per unit time on the Maxwell WK case, 1.8 at beta = 0.2). Measured window at 1/32, dt 0.01: 3e-6 rings, 1e-5 stable over the run (0.1% on the peak), 3e-5 unconditionally (0.5%), 1e-4 too strong (3%). As a field, alpha = c·h(x)^2 with c = 0.07 on the irregular mesh: peak 0.9747 / settled 0.4882 against nodal 0.9784 / 0.4864.
    • On the cylinder (beta 0.59) the mode does not appear over the run lengths used; the failures there were the timestep against the wall strain rate (conformation lost in the first step at dt 0.4; admissible everywhere at dt 0.04 to Wi 0.6).

    Not yet in the code: the smoothing is applied by wrapping the commit projection's solve in the run scripts (~/+Simulations/stress_transport/waters_king/wk_smooth_field.py, cylinder_ob/ob_cylinder.py -uw_store_smooth c). The natural home is an option on IntegrationPointSemiLagrangian setting _commit_projection.smoothing = c * mesh.cell_size()**2.

    Underworld development team with AI support from Claude Code

  8. lmoresi commented on Sep 20, 2026

    @lmoresi
    MemberAuthor

    Implemented on feature/stress-transport-ddt (71bb82d): IntegrationPointSemiLagrangian.store_smoothing (alpha = c·h², c ≈ 0.03–0.07), ViscoElasticPlasticFlowModel.max_elastic_timestep(safety) and conformation_min_eigenvalue(), hard-baseline tests, and docs/developer/subsystems/stress-transport.md. Closes with the branch PR.

    Underworld development team with AI support from Claude Code

  9. lmoresi commented on Oct 8, 2026

    @lmoresi
    MemberAuthor

    Fixed by #833, merged to development (f4733d4f).

    store_smoothing on IntegrationPointSemiLagrangian puts a Laplacian in the store projection with alpha = c * cell_size^2 — a field, so the dose follows the local cell. c = 0.07 holds the 1/32 case unconditionally at 0.5% on the peak, and the irregular mesh needs that value.

    The mechanism, for the record: the history stores the stress by a global L2 projection onto the continuous space and samples it back at the quadrature points, and that cycle has no dissipation at the cell scale — so below Courant one a cell-scale mode grows from round-off, measured at 2.4 per unit time on the Maxwell Waters-King start-up. Three things that did not work, so nobody retries them: removing the element null space (inert), private nodes per cell (diverge), DEVSS (does not touch it).

    Guarded by the ringing test at 1/16, dt 0.0125, which asserts the measured growth and its suppression — and reads the content after the trace-back, because after the store it is zero by construction.

    Closing manually: this repo's Closes lines fire when development reaches main, and merges to main are infrequent.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions