Repository navigation
Particle stress history: refill reads the right rows after a removal (#784), and the inflow datum reaches the particles that entered (#783) - #785
Conversation
…emoval (#784) PETSc removes a point by copying the last point into the freed slot, so a removal reorders the surviving particles in storage. repopulate kept its coordinate array in the original filtered order while reading the values for the reconstruction fresh from PETSc, so a particle created in a call that also removed took the values of unrelated particles. The same moves are now replayed on the local coordinate and cell arrays. Measured on a Maxwell Poiseuille channel with the particle stress history: per-particle shear-stress error median 0.12, maximum 4.8 with sign flips on a field whose maximum is 3.2; now median 0.008. The cells proxy averaged the garbage down, which is why the closed-flow validations did not see it. Regression test: a call that both thins a band and refills the emptied one reproduces a linear field to 1e-8 (97 before). Underworld development team with AI support from Claude Code Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017kSkAq7oJ5J3XisuvLBovo
…ntered (#783) No particle arrives from outside: the population control creates the particles of an emptied inlet cell and gives them a reconstruction from the nearest old particles, the wrong state for fluid that has just entered. The manager now runs the refill itself after the advection, so it knows which particles it created, and gives inflow_value to every particle whose back-trace leaves the domain where the boundary velocity crosses inward: one step back for a particle that moved, one cell crossing for one created this step. A no-slip wall has no boundary velocity and a free-slip wall only a tangential one, so a trace through a wall does not count. _write_inflow (with its units reduction) and _nondim_timestep move to the base class; the Lagrangian flavour now carries _components and _psi_units. Measured on a Maxwell Poiseuille channel, inlet column after 50 steps: shear-stress error 0.17 with no datum, 0.002 with it. Underworld development team with AI support from Claude Code Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017kSkAq7oJ5J3XisuvLBovo
mesh.data is the deprecated accessor and fails the Charter deprecated-pattern gate on this branch (36eb788). Same shape and sum, so the stamp is unchanged. Underworld development team with AI support from Claude Code Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017kSkAq7oJ5J3XisuvLBovo
|
Adversarial review before the push, two independent passes over the diff. What they found and what we did: Defects, fixed in the pushed commits
Recorded, not fixed here
Checked and fine: PETSc's removal semantics (verified empirically), the descending removal order, storage order after |
Why this is red, and what it needsThe two CI failures are not this PR's. They are byte-identical across #785, #789, #795 and #800: Both tests were already fixed on
So this branch is stale, not broken — 58 commits behind The merge is not clean, and the conflicts are the same on all four
The fifth, at the top of Order mattersAll four touch Found in the backlog sweep (#819). No commits pushed to this branch. |
The same two files and the same five hunks as the other stale transport branches, resolved the same way. scripts/test.sh keeps this branch's broader `tests/test_110*py`; development narrowed it to `test_1100*py`, which leaves the other test_110* files matching no glob at all — #721 recurring. scripts/check_test_coverage.py verifies it. Four of the five ddt.py hunks have a zero-line development side: they are this branch's own `applies_inflow_value`, `commits_flux_in_post_solve` and the inflow-value docstrings (#745/#783), flagged only because surrounding context moved. None exists on development. The fifth takes both sides — this branch's base-class `update_exp_coefficients` / `_exp_alpha` / `_exp_phi` (#739) and development's `_note_history_shift`. Verified on the merged tree: exactly one definition of each of the four, because the branch's own change already removed the three April per-flavour copies. Underworld development team with AI support from Claude Code
This branch is the base of a four-PR stack (#785 -> #789 -> #795 -> #800) and was 71 commits behind development, which is why all four showed the same two CI failures: tests development had already renamed (test_1060_nitsche_freeslip's absolute 1e-4 bound and test_1070_free_surface_plume's strong-vs-penalty ratio). The refresh belongs here, at the root, so each PR's diff against its base stays its own work rather than growing development's history. Two conflicts, both this branch's own additions. scripts/test.sh keeps the broader `tests/test_110*py` glob -- development narrowed it to `test_1100*py`, which matches none of the other test_110* files here (#721 recurring); scripts/check_test_coverage.py verifies it. Four of the five ddt.py hunks have an empty development side, and the fifth takes both: this branch's base-class `update_exp_coefficients` / `_exp_alpha` / `_exp_phi` (#739, which replaced three per-flavour copies dating from b6b0e7a in April) and development's `_note_history_shift`. Verified on the merged tree: one definition of each. Underworld development team with AI support from Claude Code
Two defects in the particle Lagrangian stress history, found on the cross-slot cell of the 2026-09-23 domain-of-applicability sweep.
#784, the refill after a removal. PETSc removes a point by copying the last point into the freed slot.
Swarm.repopulatekept its coordinate array in the original order while reading the reconstruction values in storage order, so a particle created in a call that also removed took the values of unrelated particles. TheLagrangianflavour caps over-full cells every step, and any clamped outflow pile-up trips the cap, so on an open flow every refill was garbage. The proxy's per-cell least-squares fit averaged it down, which is why the closed-flow validations did not see it. Fix: replay the same moves on the local arrays.#783, the inflow datum. The flavour declared
applies_inflow_value = False; a refilled inlet cell carried a reconstruction from stale neighbours. The manager now runs the refill itself after the advection, so it knows which particles it created, and givesinflow_valueto every particle whose back-trace leaves the domain where the boundary velocity crosses inward. The trace is one step for a particle that moved and one cell crossing for one created this step. A no-slip wall has no boundary velocity and a free-slip wall only a tangential one, so a trace through a wall does not count.Maxwell Poiseuille channel, 50 steps,
stress_transport="lagrangian":Tests:
test_0068::test_a_refill_after_a_removal_reads_the_right_neighbours(97 before, 1e-8 after) andtest_0075_lagrangian_history_inflow_value(baseline 0.01 against 0.002 measured, negative control 0.1 against 0.17). The particle-history, stress-transport, restart and integration-point files pass (71 tests).Also moved:
_write_inflow(with its units reduction) and_nondim_timestepto the base class. One extra commit replaces the deprecatedmesh.datain the forward flavour's geometry stamp, which failed the Charter gate on this branch.Not fixed here, marked
TODO(BUG): the particle flavours write the evaluatedpsi_fninto non-dimensional storage without a units reduction. Not covered: a parallel test with a rank that creates no particles.The cross-slot cell is not rescued. Re-run with both fixes: clean to step 26, then a linear-solve divergence and a 329 s step, stalled by the guard, with the stagnation point jumping. That is the same failure family as the nodal flavour on that cell at solvent fraction zero, so it is a solver question, not a refill one. The sweep's lagrangian column ran with #784 present and is not a measurement of the scheme.
Fixes #783, fixes #784.
Underworld development team with AI support from Claude Code
🤖 Generated with Claude Code
https://claude.ai/code/session_017kSkAq7oJ5J3XisuvLBovo