Skip to content

UWTN 2026-015: Testing a solver against exact solutions - #22

Open
lmoresi wants to merge 7 commits into
mainfrom
note/analytic-solutions
Open

UWTN 2026-015: Testing a solver against exact solutions#22
lmoresi wants to merge 7 commits into
mainfrom
note/analytic-solutions

Conversation

@lmoresi

@lmoresi lmoresi commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

Draft note on uw.analytic and how the suite checks itself. The preview link on this PR is the way to read it — drafts are excluded from the production toc, so pixi run build on main will not show it.

What it says

The solutions are the well-known part; the note is mostly about the checks. Each solution is validated by differentiating its own symbolic fields and substituting them into the momentum balance, incompressibility and the constitutive relation — consulting neither the paper, nor the C kernel the transcription came from, nor the solver being tested.

That found four defects:

  • solA.c's $\sigma_{zz}$ is missing its viscosity factor. The error is exactly $\tau_{zz}(1-Z)/Z$, so it vanishes identically at $Z=1$ — the only case the kernel's own driver exercises, and the default in our transcription. Anyone running that kernel at a viscosity other than 1 has a wrong $\sigma_{zz}$.
  • AnalyticSolM.hpp computes its stress with $2(\eta-1)\dot\varepsilon$ where $\eta$ belongs. The published $\tau$ matches $2(\eta-1)\dot\varepsilon$ to exactly zero, which is what distinguishes a defect in the source from a slip in transcription.
  • solC.c publishes a density where its siblings publish a force.
  • Our own EllipticalInclusion scaled the viscosity but not the pressure, so the two halves of $\sigma$ were in different units.

Plus SolKz, which is not an erratum but is the sharpest transcription trap in the family: the kernel returns the total stress and says so, while our transcriber's cut point captures the deviator.

Evidence

The measurement table ships its generating script at examples/convention_audit.py, per house policy. It runs against the landed suite and reproduces the table verbatim. The negative-control column (momentum residual with the body force negated) is in the table rather than in the prose — it is what makes a column of $10^{-16}$ mean anything.

Two things for you to decide

The Barr & Houseman errata are deliberately not here. The audit turned up an extension-positive pressure convention in Barr & Houseman (1996) plus two typos in printed (A9b) — a sign that contradicts (A8b), and a $\cos(3\theta/2)$ where $\sin(3\theta/2)$ belongs. That is the most citable material of the lot, and gthyagi found both typos and confirmed the sign numerically against a UW3 solve. It belongs either in this note with him as a co-author, or in its own note. It also rests on PR #550, which has not merged. Left out rather than published under a single byline.

Whether solA is worth reporting upstream. The kernel is widely vendored and the defect is silent at the default.

pixi run validate passes; pixi run build succeeds with the expected draft exclusion.

UWTN 2026-012, draft. The uw.analytic suite and, more to the point, the
decision to check each solution by differentiating it into the momentum
balance rather than by comparing it against the kernel it was transcribed
from. Four defects, two of them in vendored published sources.

The measurement table's generating script ships in examples/.

Underworld development team with AI support from Claude Code
@github-actions

github-actions Bot commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

Preview

Or the whole site.

Built from 6efdc0e. Shows notes at draft and review, which the published site withholds. Not indexed, no comments, and not the citable version. Confirmed serving this commit before this was posted.

Underworld development team with AI support from Claude Code
…cator reissuing a number

UWTN 2026-012 was allocated twice: to the annulus and spherical-shell
benchmarks (#11) and to this note. The benchmarks note claimed it first and
keeps it.

The allocator read only the working tree, so a number claimed by a note in
review on its own branch was invisible to it and was offered again. It now also
searches every local and remote-tracking ref, which covers open pull requests as
far as they have been fetched.

Underworld development team with AI support from Claude Code
@lmoresi lmoresi changed the title Note: testing a solver against exact solutions (UWTN 2026-012, draft) Note: testing a solver against exact solutions (UWTN 2026-015, draft) Aug 16, 2026
@lmoresi

lmoresi commented Aug 16, 2026

Copy link
Copy Markdown
Contributor Author

Renumbered to UWTN 2026-015. This branch and #11 had both been allocated 2026-012; #11 claimed it first and keeps it.

scripts/new_article.py read only the working tree, so a number claimed by a note in review on its own branch was invisible and got offered again. It now searches every local and remote-tracking ref as well, which covers open PRs as far as they have been fetched. Verified: the allocator now reports 012 and 014 as taken and offers 016.

The note stamped software_version as 'underworld3 0.0.0', and the audit script
said the same. That identifies nothing: uw.__version__ reports 0.0.0 for every
build, which is exactly the point the sibling note's scripts make. Both now
carry the commit the numbers came from, 0addec15 — verified by re-running
convention_audit.py against that build, which reproduces the note's table cell
for cell.

The banner is the note's own sentence about what the family covers — a
viscosity jump, an exponentially varying viscosity, a laterally oscillating one
— drawn as SolCx, SolKz and SolM's own fn_viscosity evaluated onto the render
points. Generated from the solutions rather than a stock photograph, so there
is nobody to credit.

Status published, dated 2026-08-17, following UWTN 2026-011 and 2026-014.

Underworld development team with AI support from Claude Code
@lmoresi

lmoresi commented Aug 17, 2026

Copy link
Copy Markdown
Contributor Author

Adversarial review — UWTN 2026-015

Reviewed for merge, so that UWTN 2026-014 can stop pointing at a page that does not exist. Two decisions are yours; the rest is fixed on the branch.

Verified rather than assumed

  • The central table reproduces exactly. examples/convention_audit.py re-run against development at 0addec15 returns every cell as published — all thirteen rows, including the negative-control column moving from 1e-16 to order unity, and SolC's 1.8 and SolCx's 1.7 and SolDB2d's 0.5. This is the check the note argues for, applied to the note.
  • The code sample runs verbatim. Copied out of "Using them" and executed unchanged: it builds the mesh, applies the boundary conditions, solves, and reports a velocity error of 8.8e-06. A published sample that does not run is the easiest defect to ship and the most embarrassing.
  • pixi run validate clean, pixi run test-unit 130 passed, check_build_assets 2236 references all present, PDF builds to 7 pages.

Fixed on the branch

  1. software_version: underworld3 0.0.0. That identifies nothing — uw.__version__ reports 0.0.0 for every build, which is precisely the point this note's sibling makes in its own scripts. A note whose subject is provenance and whose central claim is "we found errors in sources that were vendored for twenty years" should not itself be unattributable to a commit. Now development @ 0addec15, in both the front matter and the audit script, and verified by the reproduction above.
  2. No banner. Every other article has one. Added, generated from the solutions themselves: SolCx, SolKz and SolM's fn_viscosity, which is the note's own sentence about a viscosity jump, an exponentially varying viscosity and a laterally oscillating one.
  3. status: draft → published, dated, following 2026-011 and 2026-014.

Two decisions, both yours

1. Barr & Houseman, and @gthyagi's attribution. The note omits the Barr & Houseman 1996 errata — the extension-positive pressure convention and two typos in printed (A9b). That is arguably the most citable material of the lot, and it is missing for a good reason: @gthyagi found both typos and confirmed the sign numerically, and it rests on underworld3#550, which is unmerged. It belongs either in this note with him as a co-author, or in one of his own. Publishing this note as it stands is the "his own note" choice, taken by default rather than deliberately. Worth deciding on purpose before it is on the record.

2. Reporting solA.c upstream. The note ends that section with "anyone using this kernel at a viscosity other than 1 has a wrong sigma_zz and no reason to suspect it." That is true of a kernel vendored across the community since the 1990s, and the note publishes the finding without saying whether the authors have been told. Either is defensible; silence about which reads as an omission in a note that is otherwise careful about provenance.

Observations, not blockers

  • The build emitted four Error: spawn EBADF lines during the typst pass. The PDF is complete and valid, and 42 article PDFs built, so this looks like concurrent-spawn noise rather than a fault in this note. Flagging in case it recurs.
  • figures: 0 is correct and stays: the note carries tables, not figures, and the banner is not a figure.

Underworld development team with AI support from Claude Code

@lmoresi lmoresi changed the title Note: testing a solver against exact solutions (UWTN 2026-015, draft) UWTN 2026-015: Testing a solver against exact solutions Aug 17, 2026
…uthor

The note previously stopped at the Velic family. The Barr & Houseman 1996
appendix contains the same kind of problem and the method resolves it the same
way, so it belongs here rather than being held back.

Their half-integer sine terms of u_theta carry one sign in the boundary datum
(A8b) and the opposite in the solution (A9b), with the same mismatch in the
plane-stress pair. Two printed equations disagree and reading them again will
not say which is right. Incompressibility does: div u = 0 forces
g' = -(3/2) A f, which integrates to (A8b)'s sign, and flipping it back makes
the divergence non-zero purely in the fault's own half-integer modes. That is
the note's argument applied to a paper rather than to a C kernel.

The transcription is in review as underworld3#550 and follows the
implementation Thyagarajulu Gollapalli has been using for fault benchmarking,
so the note carries their name.

Also, per review: a footnote on the SolA row. It reads clean because
uw.analytic carries the correction, while the published kernel still does not —
the row certifies the transcription, not the source.

Underworld development team with AI support from Claude Code
@lmoresi

lmoresi commented Aug 17, 2026

Copy link
Copy Markdown
Contributor Author

@gthyagi — you are now listed as a co-author of this note, so it should not merge until you have read it.

What changed. The note previously stopped at the Velic family and left the Barr & Houseman material out, on the grounds that it is your work and rests on the unmerged underworld3#550. It is now in, as its own section, because the argument the note makes is exactly the one that settles it: two printed equations in the appendix disagree — the half-integer sine terms of $u_\theta$ carry one sign in (A8b) and the opposite in (A9b), with the same mismatch in (A12b)/(A13b) — and incompressibility decides between them without anyone adjudicating a scanned minus sign. $\nabla\cdot\mathbf{u} = 0$ forces $g' = -\tfrac{3}{2} A f$, which integrates to (A8b)'s sign, and flipping it back puts the divergence entirely in the fault's own half-integer modes.

Two things to check, please.

  1. That the section describes your finding accurately, and credits it correctly. It says the transcription in #550 follows the implementation you have been using for fault benchmarking. If your route to the sign was different from the incompressibility argument as written — a numerical confirmation, say — tell us and it goes in as you found it, not as we reconstructed it.
  2. The two conventions, since they are what anyone comparing against this will trip on: extension-positive pressure, so the force balance is $\partial_j \tau_{ij} + \partial_i p = 0$; and plane strain only, the thin-viscous-sheet solution of (A10)–(A13) having non-zero in-plane divergence.

Everything is drawn from #550's own write-up. Nothing that could not be verified there has been included — in particular no claim about a second typo, and no error percentage — so if there is more to the story it is missing rather than wrong, and worth adding.

Affiliation is taken from authors.yml (Monash University, ORCID 0000-0001-9394-4104). Say if either should change.

Underworld development team with AI support from Claude Code

…from a convention

Underworld3 #550 is merged, so FaultedMedium is registered and the audit script
picks it up on its own: the measurement table gains a row, and the note no
longer describes the transcription as in review.

Two additions from Thyagarajulu Gollapalli's reading of the papers and his
independent implementation.

Printed (A9b) carries a second typo besides the sign: cos(3 theta / 2) where
sin(3 theta / 2) belongs. The form implemented reproduces (A8b) at r = R0, is
divergence-free and satisfies both momentum components symbolically with U0, R0
and eta free; printed (A9b) fails boundary matching and incompressibility
together, so neither reading is an alternative convention.

The pressure sign is where a convention and an error look alike from one run.
A resolution sweep separates them: against the negated pressure the error falls
with the mesh (13.1%, 6.9%, 3.3% at h = 0.20, 0.10, 0.05) and against the
paper's own sign it sits near 199% at every resolution. Differentiating the
transcription agrees without a solver — momentum residual 3.6e-16 negated
against 1.06 as printed.

FaultedMedium shares EllipticalInclusion's footnote: both are boundary-driven
with no body force, so the negated-body-force control cannot fire and the
momentum residual carries the whole weight. That is why the sign measurement is
stated separately rather than left to the table.

Version 1.1.0.

Underworld development team with AI support from Claude Code
The version bump in the previous commit was wrong. Versioning exists to relate
a new deposit to an earlier one, and this note has no earlier one: it is absent
from deposit-queue.txt and carries neither archive_doi nor
repository_record_id, so no DOI has been minted and there is nothing for a
1.1.0 to supersede.

Publishing to the site is not depositing. Per PUBLISHING.md the deposit happens
only when somebody merges the request that adds a slug to the queue, so a note
can be `status: published` and still be at its first version. The content
changes stand; only the number goes back.

Underworld development team with AI support from Claude Code
@gthyagi

gthyagi commented Aug 19, 2026

Copy link
Copy Markdown

I have checked the Barr & Houseman section against the BH92 and BH96 papers, the analytical implementation in underworld3#550, and the independent UW3 slit-disc numerical model. The A8b/A9b sign disagreement, the cos/sin error in A9b, and the extension-positive pressure convention are described correctly.

The numerical sweep reproducing the 13.1%, 6.9%, and 3.3% pressure errors is available here.

My only requested change is the affiliation. Please list Australian National University, or Australian National University and Monash University. I have no further changes.

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