Repository navigation
Conversation
Rename PressureGradType::HighOrder1 to FiniteVolume and drop the unimplemented HighOrder2, leaving a commented stub for a future variant. Rename the functor class PressureGradHighOrder to PressureGradFiniteVolume and the PressureGrad member HighOrderPGrad to FiniteVolumePGrad. Accept 'FiniteVolume' or 'finiteVolume' in place of 'HighOrder1' when parsing PressureGradType, and update the PGrad dev and user guides accordingly. The new scheme uses the same two-cell horizontal stencil as the centered scheme and is second order, so naming the class for an order it does not have would misdescribe what ships. FiniteVolume names the layer-integrated control-volume form instead. This is answer-neutral: a pure rename plus a config-facing string change. PressureGradCentered is untouched. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Add HorzOrder, VerticalReconstruction and QuadraturePoints to the PressureGrad configuration group, parsed and validated in the PressureGrad constructor and cached on the PressureGradFiniteVolume functor. All three are optional, so a configuration written before they existed still parses; where a key is absent the default (HorzOrder 2, VerticalReconstruction 'linear', QuadraturePoints 2) is used. Reject values that are not implemented, such as HorzOrder 4 and VerticalReconstruction 'ppm', with a clear "not implemented" error rather than falling back silently, which would make a run requesting them look like a run that used them. QuadraturePoints is an accuracy knob only: the matched-pressure integrand is zero pointwise on the exact set, so no quadrature rule can break the robustness property. There is no 'constant' reconstruction and no setting that reduces the scheme to Centered. Add accessors for the configured type and options, and extend PGradTest with a parse and dispatch check that creates a FiniteVolume instance. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Widen PressureGrad::computePressureGrad and PressureGradFiniteVolume::operator() to take the layer-mean conservative temperature and absolute salinity and the Eos specific volume derivatives. PressureGradCentered is untouched: its operator() keeps its existing signature and the Centered dispatch branch passes the same arguments it always did. Update the Tendencies call site to supply Theta and S from the tracer array and the Eos instance it already holds. Switch AuxiliaryState::computeMomVertAux to call Eos::computeSpecVolAndDerivs in place of Eos::computeSpecVol when the FiniteVolume scheme is selected. computeSpecVolAndDerivs fills SpecVol as well, so it replaces rather than accompanies computeSpecVol; the branch keeps a Centered run from paying for the derivative arithmetic. The FiniteVolume path is still a no-op, so Centered answers are unchanged. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Assert design section 3.9's identity directly in PGradTest: with the tidal and self-attraction-and-loading potentials zero, PressureGradCentered is exactly -g/d_e times the fixed-pressure shift S = 1/2 (dZ_k + dZ_k+1) + alphaBar / (2 g) (dq_k + dq_k+1) with dZ and dq the cross-edge differences of GeomZInterface and PressureInterface. The check runs over a sweep of interface tilts and is scaled by the size of the hydrostatic terms the centered functor forms and cancels, since agreement is to round-off rather than bit-for-bit. Factor the two-column state construction out of the refinement loop into setupTwoColumnState so the sweep can rebuild it at each tilt. The refinement loop is unchanged in what it computes. This is the permanent regression test of design section 5.5, not a transitional one. Because the two expressions read the mesh, VertCoord and Eos state through independently written code, their agreement tests the shared upstream state -- edge masks, interface indexing, VertCoord conventions -- and not just the pressure gradient arithmetic. A guard asserts that dropping the pressure half of S misses by far more than the tolerance, so a pass cannot come from both sides being trivially equal. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Make an unrecognized PressureGradType a fatal error instead of falling back to the centered scheme with an informational message. A silent fallback turns a typo, or a configuration naming a scheme that no longer exists such as the former 'HighOrder1', into a run that looks like a passing centered run. This is the same hazard unimplemented sub-option values are already rejected for. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Add PGradRecon.h, holding the mean-preserving linear reconstruction of conservative temperature and absolute salinity in pressure that the FiniteVolume pressure gradient uses. The slope is a centered difference of the layer means with respect to mid-layer pressure, one-sided in the shallowest and deepest valid layer of a column and zero where a column has a single valid layer. Differencing against the actual mid-layer pressures rather than against layer index is what makes the estimator exact for a profile linear in pressure on Omega's non-uniform vertical grid: the mean of a linear function over a layer is its value at the layer's midpoint, so the layer means lie exactly on the line as a function of mid-layer pressure. A formula that assumed uniform thickness would pass a uniform-thickness test and fail on a real grid. The deviation integrates to zero over the layer because PressureMid is the exact arithmetic midpoint of the two interface pressures, which is also what makes VertCoord's midpoint rule the exact layer integral of a linear reconstruction and so spares VertCoord any change. There is no limiter. The functions take scalars so they can be unit tested without a mesh. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Check the mean-preserving linear reconstruction on a single column, without a mesh. Layer means are sampled from a profile exactly linear in pressure, so the recovered slope must match the profile's slope to round-off in every layer, including the two that use a one-sided difference. The layer thicknesses are deliberately non-uniform, which is the case the test exists for: a formula that assumed uniform thickness would pass the uniform control that runs alongside and fail here. Running both means a failure says which of the two it is. Also asserted are the two properties the scheme leans on: that the reconstruction reproduces the layer mean at mid-layer pressure, and that its deviation integrates to zero over the layer, by two-point Gauss quadrature which is exact for a linear integrand. A single-valid-layer column must give a zero slope, a constant being the only mean-preserving reconstruction available there. This is worth testing separately because it is the most likely place for the exactness gate to fail, and it localizes such a failure immediately. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Add PGradFiniteVolume.h with the first-order equation-of-state expansion shared across an edge layer, built by averaging the two adjacent cells' coefficients and reference states. One set multiplies both columns, which is what the robustness property rests on: give each column its own expansion point and the alpha0 and alphaP terms no longer cancel in the matched-pressure difference, and the scheme generates spurious flow out of nothing but its own equation-of-state approximation. Which set is used is an ordinary accuracy question and cannot break exactness. Add findLayerForPress to PGradRecon.h, the lookup that makes the scheme a fixed-pressure comparison rather than a fixed-layer-index one. At a pressure in edge layer K each column supplies its state from whichever of its own layers contains that pressure, which under tilt is generally not layer K. A pressure outside the column clamps to the outermost valid layer and extrapolates its reconstruction, which is the rule where the edge control volume extends past a column's own floor; exactness survives extrapolation because an extrapolated reconstruction still reproduces a resolved profile. Pin the lookup with direct property tests, on a fabricated column pair without a mesh. These are not optional: no answer-level check anywhere in the test plan can distinguish this from a layer-index lookup, since on a profile linear in pressure every layer's reconstruction is the same line and looking up the wrong layer costs nothing. The tests assert that the returned layer brackets the pressure, that it differs from the edge layer index by up to three layers so the lookup is demonstrably not an index lookup, that the answer is independent of the starting hint so the column scan's incremented cursors cannot disagree with a search, and that a pressure outside the column clamps to the outermost valid layer. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Add matchedPressSpecVolDiff, the central quantity of the scheme: the difference in specific volume between an edge's two columns, evaluated at one pressure with one shared expansion. Because both columns use the same expansion, the SpecVol0 and SpecVolDP terms are identical and cancel, leaving a coefficient times the horizontal contrast in reconstructed temperature and salinity at matched pressure. Compressibility drops out entirely, which is correct physics rather than an approximation: a horizontally uniform compressibility exerts no horizontal pressure gradient. Add the Gauss-Legendre rule for 1 to 4 points, and move MaxPGradQuadPoints alongside it. The number of points is an accuracy setting only, since the integrand is zero at every point on a resolved profile. Unit test on a fabricated column pair, without a mesh, exercising the reconstruction, the pressure lookup and the shared expansion together. Both columns' layer means are the exact layer averages of one prescribed continuous profile, so under the offset between the columns those means genuinely differ. On a profile linear in pressure the integrand is zero at every quadrature point, not merely in the integral, measured at 5.8e-21 m3/kg or 0.9 eps of the terms that had to cancel. A quadratic profile runs as a control and gives 5.3e-10 m3/kg, eleven orders larger, so the linear result is not a statement that everything in the test is zero. The tolerance is scaled by the cancelling terms rather than being an absolute constant. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Accumulate the fixed-pressure height difference down each edge's column, into a per-edge array of interface values. This is a prefix sum with edge-dependent coefficients, so it is not expressible as an independent per-vertical-chunk operation and cannot live in the functor; it is the one structural addition beyond the per-edge, per-chunk pattern the centered scheme uses. It runs as a parallelForOuter over edges with a parallelScanInner down the column, in the same shape as VertCoord::computeGeomZHeight. The scan runs in two passes. The first evaluates the matched-pressure integrand at each edge layer's quadrature points and forms two integrals of it over the same points: the increment of the recurrence, and its first moment about the layer's top interface, which the layer mean will need. The second anchors the column and turns the increments into the height difference at every interface. The per-cell reconstruction slopes are computed once and reused across each cell's edges, so the per-edge work is polynomial arithmetic on cached values. Anchor at the sea floor, per design section 3.7.4, which leaves the end open and prefers this one on conditioning grounds. There turns out to be a second and stronger reason. VertCoord builds geometric height by accumulating a midpoint rule over each column's own layers, and on a curved profile two columns with different layer partitions give sums that differ at second order in layer thickness. Anchored at the surface that discrepancy enters the height difference directly and the exactness gate would not be machine-zero; anchored at the sea floor over a flat floor the height difference is exact input and vanishes identically, and the discrepancy never enters, because the scheme integrates its own reconstruction rather than accumulating VertCoord's height. This is a prediction to be checked against the measurement. The anchor is computed, not assumed: each column's height at the deepest shared interface is shifted to the common pressure by integrating its own reconstruction over half the cross-edge pressure difference, and both short integrals vanish where the two columns' interface pressures agree. Test that the height difference is zero at every interface, not merely in the layer mean, on a two-column state whose layer means are the exact layer averages of one profile linear in pressure -- so that under the offset between the columns those means genuinely differ. The shape of a failure is reported as well as its size, since a residual growing with depth points at the recurrence while one flat with depth points at the anchor. The tolerance is provisional pending the first measurement. Allocate the working arrays only when the FiniteVolume scheme is selected, so a Centered run pays no memory for them. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Turn the column scan's output into the tendency: form the layer mean of the fixed-pressure height difference from its value at the layer's bottom interface and the first moment of the integrand over the layer, scale by -g/d_e, subtract the tidal and self-attraction-and-loading difference, and accumulate into Tend with EdgeMask exactly as the centered functor does. The edge control volume's pressure thickness is exactly the edge average of the two columns' own. This is the first point at which the FiniteVolume scheme produces a number. Narrow the functor's arguments to the two arrays the column scan fills. Design section 4.1.3's illustrative signature lists the temperature, salinity and specific volume derivative arrays, but it also omits the scan's own array while describing the functor as reading it "like any other input", so it is not self-consistent. With both integrals formed in the scan over one set of quadrature points, which section 3.5.1 requires, the functor reads none of the state the scan consumed; passing it would only invite evaluating the integrand a second time. Report the tendency on the exact-set state alongside PressureGradCentered's on the same state, and require the centered value to be nonzero, so that the FiniteVolume result is a cancellation against a known nonzero reference rather than a comparison with zero. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The gating test of design section 5.2, in three groups. Exactness. On a two-column state whose layer means are the exact layer averages of one profile linear in pressure, with a horizontally uniform surface pressure, the tendency and the fixed-pressure height difference must both be zero to machine precision. Measured at commit 10: tendency 1.6e-18 m/s2 against PressureGradCentered's 1.6e-05 m/s2 on the same state, and height difference 6.7e-16 m, both 0.027 eps of the terms that had to cancel. The gates replace commit 9's provisional value with four eps, which leaves over a hundredfold margin while still catching drift, and they track Real's epsilon and the size of the hydrostatic terms rather than a physical tolerance. Absolute tendencies are reported alongside the centered scheme's, so a pass is a cancellation of thirteen orders against a known nonzero reference. The maximum is the right norm here, since the claim is a zero at every edge and layer. Convergence. Quadratic and cubic profiles, which the linear reconstruction does not resolve, over 15, 30 and 60 layers at fixed tilt. The residual must shrink at second order in layer thickness; a rate below that means one of the scheme's conditions has been broken somewhere and is a bug to find, not a tolerance to widen. The rate is measured on the RMS rather than the maximum: a maximum is set by whichever layer happens to be worst, and that layer moves under refinement, which makes the rate noisy and non-monotone. RMS is also the norm the design's measured rates were taken in, so the two are comparable. Guards. Guard (a), tilt sensitivity, runs on the kernel and is the only one that can fire where every other check passes. Guards (b), (c) and (d) need the scheme's rules switched off one at a time, so they run against a host reference assembled from the same helper functions the kernel uses. That reference is only trusted after it reproduces the kernel, and the fidelity check that has content is on a curved profile where both sides are large -- agreeing at 1e-18 on the exact set would also be satisfied by a harness that computed nothing. Note that the reference shares the helper functions, so the guards establish that the three rules are load-bearing rather than independently verifying the arithmetic; that verification comes from the centered identity and from the Omega-versus-Polaris comparison. Guard (b), a cell-local expansion point, must fire: two expansion points mean the SpecVol0 and SpecVolDP terms no longer cancel. Guard (d), the anchor taken as the raw height difference, must fire where the two columns' end pressures differ and must be flat with depth, which is what distinguishes it from (b); at a sea-floor anchor that means a surface pressure contrast reaching the bottom interface. Guard (c), a layer-index lookup in place of the pressure lookup, is recorded rather than required to fire. It cannot fire on the exact set, because the profile is a single line in pressure and every layer's reconstruction is that same line, so writing it as a guard that must fire would assert something false. It is logged either way, and if it ever does fire an answer-level check on the lookup has become available. Until then the lookup is pinned only by the property tests. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Add PGRAD_SINGLE_PRECISION_TEST, which builds PGradTest against the single-precision library. Design section 3.7.5 predicts the exactness gate should pass there: the scheme differences the integrand before integrating it, so every quantity in the column scan is already a horizontal contrast and no large quantity is formed anywhere. Running PressureGradCentered alongside, which does form and cancel quantities of order a hundred metres, is what makes the result interpretable. The gate is loosened from four epsilons to sixteen in single precision. A build with fewer guard digits accumulates more round-off down the column, so the same measurement in epsilons is expected to be somewhat larger; the tolerance moves with that rather than the claim changing. Skip the convergence rates and guards (b) to (d) in single precision. Those measure truncation errors, and this build cannot resolve them: the round-off floor of the tendency is about 3e-8 m/s2, which swamps the quadratic profile's residual at 60 layers and leaves only a factor of ten between guard (b)'s signal and the noise. They are statements about the discretization rather than about precision, so measuring them once in double precision is enough. The exactness gate and guard (a) run in both, which is what design section 5.2 asks for. Make the matched-pressure integrand's control a ratio of the quadratic result to the linear one rather than a count of epsilons. In single precision the linear result rises with the round-off floor while the quadratic one, being a truncation error, does not, so an absolute epsilon count would fail for a reason that has nothing to do with the property being tested. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Instrument Eos with a count of specific-volume evaluations, one per cell per active layer per call, and assert against it in PGradTest. Requirement 2.2 of the design bounds the number of equation-of-state evaluations at about one per cell per layer per step, independent of the reconstruction order, the stencil width and the quadrature. Nothing else in the test suite would notice that being violated: an evaluation inside the quadrature loop would change run time without changing any answer, so every accuracy gate would still pass. The check is sharper than the requirement. The pressure gradient performs no equation-of-state evaluations at all -- the one per cell per layer the requirement allows is paid once by AuxiliaryState, before the tendency is computed, and the scheme works from the specific volume and derivatives that call leaves behind. So the count across a call to computePressureGrad must be exactly zero, and it is asserted at QuadraturePoints 1 through 4, the quadrature being where a call would most naturally creep in. A count of zero would also be produced by broken instrumentation, so the test additionally confirms that one call to computeSpecVolAndDerivs registers exactly one evaluation per cell per layer. This is a counter comparison rather than a timing measurement, so it is deterministic and suitable for continuous integration. The wall-time comparison against PressureGradCentered remains a separate, non-CI measurement for the pull request description. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Bring the PGrad dev and user guides up to what ships. The user guide gains the three sub-options and their defaults, and says plainly that QuadraturePoints is an accuracy setting only, since the integrand is zero at every point on a resolved profile and no quadrature rule can affect the exactness. It records that unimplemented values are rejected rather than falling back, that an unrecognized PressureGradType aborts, and that no setting reduces the finite-volume scheme to the centered one. The dev guide gains four things the code alone does not make obvious: why the per-edge column scan cannot live in the functor, that it anchors at the sea floor and why, that each column's state is looked up by pressure rather than by layer index -- with the warning that no answer-level test can catch getting that wrong, so the property tests pinning it are not optional -- and that the equation-of-state expansion is shared across each edge, with what is and is not load-bearing about that. Also correct the computePressureGrad call signature in the dev guide, which described arguments the method has never taken. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The dispatch check in PGradTest asserted only that the tendency came out finite, which is weak enough to pass on garbage: a specific volume derivative array still holding the fill value its field was attached with, 9.969e36, propagates through the arithmetic without overflowing a double. Require instead that the tendency be nonzero and no more than three orders of magnitude larger than PressureGradCentered's on the same state. The bound is one-sided on purpose. The two schemes agree to second order in the cross-edge pressure difference, which limits how much larger the finite-volume answer can be but says nothing about how much smaller; on a state whose profile is close to linear in pressure it is legitimately far smaller, which is the whole point of the scheme. A fill value misses the upper bound by thirty orders, in either precision. Also check the result of every PressureGrad::create in this test. create returns null if an instance of that name already exists, and dereferencing that gives a segmentation fault with no message rather than a diagnosable failure. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Make computeReconSlopes and computeColumnScan public. nvcc rejects an extended host-device lambda whose enclosing function is private or protected in its class, which broke the build on GPUs. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Template buildEdgeEos on the array type, as findLayerForPress already is. PGradTest's host-side reference scan calls it with host arrays, which are the same type as device arrays on CPUs but not on GPUs, so PGradTest would not have compiled with nvcc. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The counter only saw host-side calls to the Eos compute methods, which the pressure gradient cannot make through its const Eos pointer. An evaluation inside the quadrature loop would be a device-side call the counter never sees, so the cost check could not catch the regression it was written for. Remove the counter, the check and the references to it. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Launch the reconstruction slopes and the matched-pressure integrals as team loops over each column's active layers, as the other pressure gradient kernels do, instead of flat loops over every layer that skip the inactive ones. The integrals now share the column scan's per-edge team, with a barrier before the scan, so the two passes run as one kernel. Nothing reads these arrays outside the active layers, so the inactive entries no longer need zeroing. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The pressure gradient is exact for linear-in-pressure water only where the two columns' sea floors are at the same pressure. Over a sloping floor the sea-floor anchor leaves a residual that grows with the cube of the floor pressure difference, and on terrain-following layers it approaches the centered scheme's error. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Where the two columns' floors are more than a layer apart in pressure, as with terrain-following layers over a steep slope, compare the shallower floor with the deeper column's own interface just below it, then carry the anchor down to the edge's deepest interface with the matched-pressure integrand. Shifting both floors to their mean pressure with one first-order expansion left an error that grows with the cube of the offset and is the same at every depth. Where the floors are within one layer of each other, on a flat floor or where partial bottom cells cut a sloping one, the anchor is unchanged. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A resting, linear-in-pressure state on terrain-following layers whose floors are 6.4 layers apart. The host reference mirrors the new anchor and must reproduce the kernel, the tendency must stay well below the centered scheme's, and the mean-pressure anchor must fail that gate. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Convergence rate was framed as a secondary diagnostic subordinate to absolute error. Absolute error is the metric that matters for simulations, but the measured convergence rate verifies that the implementation achieves its designed order. Add Requirement 2.6 for verified order of accuracy, make the rate band in the Polaris test a gating criterion rather than a loosened diagnostic, and note that the resolution sweep may need retuning to resolve a fourth-order slope. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The convergence test parametrized only over the legacy centered functor and the fourth-order scheme, so the order-2 verification gate would have measured code this design does not change and left the new scheme's lowest-order path unverified. Add a third test configuration running the new implementation at ReconstructionOrder 2. Record the decision to keep PressureGradCentered as a separate functor rather than reimplementing it as the lowest-order configuration of the new scheme. Keeping it preserves an independent cross-check of shared upstream state and avoids an answer-changing change to the default, at the cost of ~40 redundant lines. Its eventual removal is follow-up work once FiniteVolume becomes the default. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The previous draft required the scheme to return zero PGF whenever layer means are horizontally uniform, for arbitrary tilt and arbitrary vertical profile. That cannot be delivered: under tilt each column reconstructs on its own interfaces, so the two columns describe different water and a nonzero PGF is the correct answer. Replace the claim with the three conditions the implementation must actually meet, and state for each phase which water columns cancel to machine precision. Also record two constraints the earlier draft missed: the EOS expansion point must be shared across an edge rather than taken per cell, and the sloping-interface term needs the pressure-averaged alpha*p along the interface, not the average of the two cells' values. Flag the VertCoord geopotential as an unmet prerequisite, since computeGeomZHeight integrates the layer-mean specific volume and so works from a different alpha than the pressure term would. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The scheme of section 3.5 has now been implemented and measured in the Polaris two-column harness. Exactness holds: the differenced integrand is zero at every quadrature point to 5e-21, the accumulated height difference to 1e-15 m, and the assembled tendency to 2e-18 m/s, across the full tilt sweep at three vertical resolutions. Several claims in this document did not survive contact, and this commit corrects them. Section 3.5's first consequence overreached. Exactness does not depend on the coefficients' values, but it does depend on one set multiplying both columns; give each its own and exactness is lost at 1e-5. The edge-shared expansion point remains load-bearing, for sharing rather than for where the point sits. The recorded diagnosis of the earlier formulation's failure was wrong. It said the cause was sharing the equation-of-state expansion at fixed layer index rather than at fixed pressure. Measured, that choice has no effect at all, because whatever the shared set is, it multiplies a contrast that is zero. The mechanism was never established and, the formulation being abandoned, is left open rather than pursued. State the condition the design actually needs instead: the per-layer version is insufficient because the column integral accumulates from the surface. Requirement 2.3.4 asked for the residual to shrink one order faster in layer thickness than the centered scheme's. It does not, because the premise - that the centered scheme is first order in layer thickness - does not hold on the profiles measured; both converge at roughly second order on a smooth curved resting profile, and the advantage narrows from 6.5x at 256 m layers to 2.4x at 64 m. Express the requirement as absolute error at affordable resolution, which is what section 1 says the metric of success actually is. The first-order behaviour that is robust is in the coordinate tilt, not in layer thickness. The anchor was described in terms of how one test happens to initialize its sea surface, and that had been promoted to a standing condition on the design and a dependency on VertCoord. It is neither. The anchor is computed from the model's sea-surface heights and surface pressures, not assumed, and it is the k=1 instance of the same fixed-pressure comparison every other interface gets. What is a real implementation condition is that the surface difference be shifted to a common pressure rather than taken as the raw height difference, so condition 3 says that. The test-design consequence - that a resting-state gate must be run on a state that is exactly at rest, or must expect the residual its initialization implies - belongs in section 5.2 and is stated there generically. Correct the guard list to match what fires. A cell-local expansion point breaks exactness and is the condition-1 guard; the choice of shared coefficient set does not and is deliberately not a guard. Record prominently that the guard which would catch a column's state being looked up by layer index instead of by pressure cannot be made to fire on any available configuration, so an implementation that gets this wrong will pass every check specified here and must be pinned by direct property tests. Keep the design to requirements and formulation. Statements about what earlier revisions said, and the reasons a requirement changed, belong in section 6 or in the commit history rather than in sections 1 to 5. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The scheme has been implemented and measured in Omega. Four things the design left open or predicted are now fixed, and the text is updated to describe the design as it stands rather than as it was proposed. The column scan anchors at the sea floor. Conditioning favoured it already, but exactness decides it: VertCoord accumulates a midpoint rule over each column's own layers, so on an unresolved profile two columns with different layer partitions give sea-surface heights differing at second order in layer thickness. Anchored at the surface that disagreement enters the anchor directly and the machine-precision property is lost; anchored at the sea floor it never enters. The earlier claim that the two ends agree to round-off held only inside the exact set, where the two columns' sums agree term by term. Assumption A5's rule is stated: clamp to the outermost valid layer of the column and extrapolate that layer's reconstruction. Single precision is measured rather than predicted. The exactness gate returns the same result as double precision scaled by epsilon, while PressureGradCentered is essentially unmoved, since its error is truncation rather than round-off. The functor signature is corrected. It takes the column scan's two output arrays, not the temperature, salinity and derivative arrays: both integrals are formed in the scan over one set of quadrature points, as section 3.5.1 requires, so evaluating the integrand again in the functor would double the cost of the most expensive part of the scheme. The scan's arrays are described with their real extents, and the Eos evaluation counter the cost check needs is recorded. The cost check is sharpened to what the design delivers: zero equation-of-state evaluations in the pressure gradient, the one per cell per layer the requirement allows being paid by AuxiliaryState. Section 5.2 records what each guard did, including that guard (c) is confirmed unable to fire, and states that the guards run against a switchable assembly sharing the kernel's helper functions -- so they establish that the three rules are load-bearing without independently verifying the arithmetic. Section 6.1.1 collects the Omega-side measurements. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Equation (z-increment-exact) states that VertCoord's midpoint rule is the exact layer integral. That is true of the linearized specific volume the pressure gradient uses, and the derivation given -- the mean-preserving deviations and the pressure term both integrating to zero over the layer -- establishes exactly that. It is not true of what VertCoord actually accumulates, which is the exact TEOS-10 specific volume evaluated at the layer-mean state. Specific volume is nonlinear in pressure, so its layer average is not its value at the midpoint state, and the increment is a second-order-accurate approximation rather than an exact integral. Measured on the Polaris side, the gap accumulates to 1.1e-3 m over a column. The conclusion the section draws is unchanged: VertCoord needs no change and no answer-changing baseline step. But the reason is not that its rule is exact. It is that the scheme never accumulates VertCoord's height, using it once as the difference the anchor takes at the sea floor, where over a flat floor with matching maxLevelCell it is exact prescribed input. Where the two columns' floors differ the anchor spans a partial accumulation and the gap enters at the level of the difference between the columns' partial sums, which is what bathymetry_step measures. This also corrects the mechanism given for preferring the sea-floor anchor. That was attributed to profiles the reconstruction does not resolve; the disagreement in fact comes from the equation of state's curvature in pressure, so it is present even on the exact set, where two columns with different layer partitions still accumulate different amounts of midpoint-rule error. The claim that the two anchor ends agree to round-off therefore fails on the exact set as well, not only off it. Reported from the Polaris side. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Section 3.7.5 claimed no large quantity is formed anywhere in the scheme. That is true of the recurrence, every increment of which is a horizontal contrast, and false of the anchor. Where the bathymetry steps, the height difference at the deepest shared interface is of order the step and the anchor's two short integrals span that step and cancel it. Measured on a stepped floor with a profile linear in pressure: 4.0 m cancelled to 1.9e-12 at a floor gradient of 1 m/km, 100 m to 2.6e-8 at 25 m/km, and 205.6 m to 1.7e-7 at 200 m/km -- nine to twelve digits consumed. On the same states the surface anchor forms nothing at all, its height difference being zero and its correction a zero-width integral. The two ends therefore fail in complementary ways, and the choice is a trade-off rather than a settled preference. The sea floor is exact where the coordinate tilts over an unstepped floor, which is the case Requirement 2.3.1 was written for, and the surface is not; the surface forms nothing where the floor steps, and the sea floor does not. Neither gives machine precision at every tilt, thickness and bathymetry, so that requirement is met on an unstepped floor rather than unconditionally. Section 3.7.4 now states this as the open question Phase 1 leaves behind. The stepped-floor residual is not quadrature error: refining from 2 to 16 Gauss points does not move it, which is conclusive rather than suggestive since the reconstruction is linear in pressure and every rule integrates it exactly. What remains is the edge-shared first-order equation-of-state expansion integrated across the whole step, some 2e6 Pa at 200 m/km. That attribution is a scaling argument rather than a measurement; if it holds, the second-order expansion would reduce it, as would re-expanding about the midpoint of each short integral, and neither has been tried. Two things this does not disturb, both measured: the scan stays flat to 1.4e-15 m at every floor gradient, including where a column's reconstruction is evaluated three layers below its own floor, confirming assumption A5 on the geometry it was most doubted on; and the scheme still beats the centered one by a factor of 2e5 on these states. Reported from the Polaris side. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…dition Section 3.5.1 still described the scan as accumulating from the sea surface and wrote the anchor at k = 1, contradicting section 3.7.4, which settles the sea floor and gives the argument. The implementation follows 3.7.4. Rewrite 3.5.1 to match: the recurrence runs upward, the anchor sits at the deepest interface the two columns share, and its short integrals each span half the cross-edge pressure difference there. The surface form is kept as the alternative it is. Also drop the description of the anchor end as a conditioning choice, which it is not, and qualify the conditioning argument as holding where the floor is unstepped. Section 5.2's machine-precision gate needs a condition on how its state was constructed, which it did not previously state. The anchor is the one place a state can inject a residual the scheme cannot remove, so the gate must be run on a state whose anchor inputs vanish identically: at a sea-floor anchor, two columns sharing both a floor depth and a bottom pressure. A state that pins the opposite end instead carries VertCoord's second-order truncation difference into the anchor's input, and then no scheme however exact returns zero -- measured on Polaris-initialized states, whose columns share a floor depth but reach different bottom pressures under tilt, the sea-floor anchor is -7.1e-8 m where the surface anchor is zero to round-off. That residual is the anchor and nothing else, since every increment of the recurrence is still zero and the height difference is still flat down the column, so it leaves the pointwise cancellation untouched. Omega's gate satisfies the condition by construction: it prescribes the pressure grid, so both columns share a surface and a bottom pressure, and prescribes an equal bottom depth from which VertCoord derives height upward. Both anchor inputs are identically zero, which is why its 3.1e-18 m/s2 is a property of the scan alone; the same scheme run on a Polaris-initialized state should return that state's anchor residual instead, and that is the correct answer there. Reported from the Polaris side. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Section 5.1 called for running the temperature and salinity gradient variants at several amplitudes of the cross-edge contrast and requiring the error to grow no faster than linearly. That test cannot work, for three independent reasons, each established by measurement on the Polaris side. The contrast axis is not independent of the resolution axis. A two-column initialization interpolates at plus and minus half the cell spacing, so the state depends on the contrast and the spacing only through their product; contrast 2 at 2 km reproduces contrast 1 at 4 km to every printed digit. A contrast sweep is a coarsening sweep in disguise, which is why the convergence slope collapses from 1.46 to -0.04 across it. A2 and the horizontal stencil's truncation error are confounded by construction. Both scale with the cross-edge contrast, a comparison against the quasi-analytic reference cannot separate them, and the stencil dominates by enough that the two schemes give identical RMS to four significant figures at every contrast. The initialization's shape-preserving limiter is nonlinear in the node values, so the state is not smooth in the contrast: the second difference of layer-mean salinity is 5.75e-2 g/kg on the shipped profile against 7.1e-15 where the limiter has no freedom, and the nonlinearity saturates with contrast rather than scaling with it. What replaces it is stronger. A2 is the claim that the second-order remainder of the equation-of-state expansion across an edge is small, and that remainder is computable straight from the state with no reference comparison, so it is neither confounded with the stencil nor sensitive to how the state was built. Measured that way it is 8.0e-6 relative on temperature_gradient at 4 km, the hardest configuration in the family, with a companion check confirming it vanishes when the two columns coincide. Section 3.7.6's A2 entry and the section 5.7 coverage table are updated to match. Reported from the Polaris side. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The eight Polaris horiz_press_grad variants have been run in Omega with both schemes over shared initial conditions. Every prediction in section 6.5 was reproduced, several to four or five significant figures. Section 5.1 was still written as a specification to be implemented. It now records what was built and measured: the two configurations Phase 1 actually offers rather than the three an earlier draft assumed, the per-variant and per-scheme convergence bands, and the accuracy ratios. The headline is ztilde_gradient, which holds temperature and salinity horizontally uniform and tilts only the coordinate, so the first-order term of [centered-error] is exposed with nothing else mixed in: centered converges at 1.068 there and finite volume at 1.971. The resting-state behaviour of section 3.7.3 and its cure, visible in a convergence rate rather than inferred. Two corrections to guidance this section gave. The accuracy gate's default must assert "not worse" rather than "better": on temperature_gradient and salinity_gradient the schemes agree to five figures, correctly, because level coordinates make matched-pressure and matched-index coincide and the residual is a two-column error both share. And the advantage is not always a constant factor -- where the orders genuinely differ it widens under refinement, 1.80x at 4 km to 14.8x at 0.5 km. Add section 3.7.3's warning that the tilt exponent must not be used to compare the schemes. Both give q = 1.000, for unrelated reasons: the centered scheme because alpha is effectively piecewise constant in pressure within a layer, the finite-volume scheme because its one remaining error term is the anchor, which inherits the tilt's own linearity. Reading q alone would report "no better than centered" for a scheme up to 500 times more accurate. Add section 6.6 with the resting-state advantage per variant, spanning four orders of magnitude, and with bathymetry_step_linear -- a new variant that is both inside the exact set and stepped, so it isolates what a bathymetry step costs. It confirms A5 on the geometry where that assumption was least obvious: D_k stays flat to 1.4e-15 m even where the two columns reach different maxLevelCell and the deepest edge layers extend three layers below one column's floor. Record that omega_vs_polaris measures 4e-19 to 5e-16 for the new scheme, better than the legacy scheme's, and note what maintaining that independence required. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Section 6.6 previously asserted that interior coordinate tilt contributes essentially nothing to the global bottom-layer error and attributed that to section 5.3, which contained no such measurement. The claim was ahead of the evidence as the document stood; the assertion was removed, and this restores it properly by putting the measurement itself in section 5.3 with its numbers and provenance. The measurement is an offline evaluation of the centered scheme's PGF on EC30to60E2r2 with horizontally uniform temperature and salinity, which is an exact resting state on the real mesh and bathymetry, so the whole computed PGF is error -- section 5.2's premise at global scale. It establishes three things. The error is concentrated in the bottom layer and is baroclinic there, matching the bottom-trapped character of the KE response; it is 1.28x to 1.55x the pressure gradient the model actually carries in that layer, which sets the bar for Requirement 2.1 at a factor of 5-10 rather than the ~2x a modest gain would give; and the global IC's interior coordinate is 100-1000x less tilted than the smallest tilt in the Polaris sweep, putting that mechanism some 6000x below the observed interior error. It also calibrates bathymetry_step as a quantitative proxy, within 20-35% over the slope range that dominates the mesh and over-predicting steep edges by 3-10x. It does not settle A4, and the subsection says so at length. Every number is the error rather than its dynamical consequence, which is necessary for A4 but not sufficient: it does not show the error produces the observed bottom-layer KE rather than merely coexisting with it. The one forward-run observation, bottom KE 1.19x the fully forced run, is suggestive and no more. Section 6.6's parenthetical now cites the narrow claim the measurement supports and keeps A4 open, rather than conflating the two. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Section 5.3.1 sets the bar for Requirement 2.1 at a factor of 5-10, from the global resting state where the centered scheme's bottom-layer error is 1.3 to 1.6 times the pressure gradient the model carries there. Section 6.6 reports the advantage per variant. Neither section referred to the other, so the requirement stayed qualitative and the ratios had nothing to be read against. Requirement 2.1 now states the figure and where it comes from. Section 6.6 reads its four ratios against it: three clear the bar, and hydrostatic_consistency does not, at 2.58x. That is not a shortfall, and saying so matters because the number invites the opposite reading. Section 5.3.1 measures the interior coordinate of a realistic global initial condition as 100 to 1000 times less tilted than the smallest tilt in that sweep, putting interior coordinate tilt some 6000 times below the observed global interior error. So the variant is calibrating the scheme on a mechanism that is not the one the bar was set from, and its ratio is not a prediction of global improvement. The stepped-floor variants are the quantitative proxies for that error, and they clear the bar by two to four orders of magnitude. Reported from the Polaris side. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The design specified the A4 diagnostic in three places as a pre-Phase-1 check that could be run immediately with the existing centered scheme. That cannot work, and section 3.7.3's own table is what contradicts it: a profile linear in pressure lies in Phase 1's exact set and not in the centered scheme's, where it stays first order in layer thickness with a coefficient proportional to the coordinate tilt. The diagnostic's inference requires the scheme being run to have zero pressure gradient error on that profile. Run with the centered scheme the linear-in-pressure seamount is not a null configuration, only a slightly cleaner non-null one, and a sigma coordinate over a seamount is the largest tilt in the suite, so the contamination is worst exactly there. The test would measure the thing it was designed to exclude and its result would support neither conclusion. A4 is therefore a post-Phase-1 test and became runnable for the first time when FiniteVolume landed. Section 4.5.3's step 2 is rewritten as what a centered run there can legitimately establish -- that the case exercises the pressure gradient at all, and how large the spurious velocity is -- which is worth doing early but answers a different question. Reported from the Polaris side, after the first Omega seamount runs. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Section 5.3 asked for the seamount test and had no measurement. It now has one, run with TEOS-10 over six days with tracer diffusion and hyperviscosity off so the pressure gradient is what remains. On z-star the scheme passes the section's criterion by a wide margin: 44x lower maximum velocity and 3e4 lower mean kinetic energy than the centered scheme on the realistic profile, and 134x and 1780x at one hour before anything else develops. The centered scheme's error sits in the partial bottom cell, matching section 5.1's bathymetry_step. That is Requirement 2.3 under dynamics. On sigma it does not. The scheme develops density inversions at day 1.5 on the realistic profile and day 3 on the linear-in-pressure one, reaching about 5e-1 m/s by day 6 where the centered scheme on the identical configuration is clean and decaying at about 1e-2. It is not an accuracy failure -- before the growth takes hold the new scheme is five times more accurate than the centered one. Three things point at a grid-scale numerical instability: the disturbance sits at a fixed location on the flank, the same under both equations of state, so it follows the geometry rather than the profile; its grid-scale content rises before any inversion appears; and the temperature anomaly reaches a third of the profile's range. Sigma layers follow the bathymetry, which is the steepest tilt against isobars in the suite and is not what Omega runs, so this does not qualify the result on the configurations Omega uses. It does mean the scheme has a limit on steeply tilted layers that the centered scheme does not share, and that the limit is not understood. The next diagnostic is a re-run with monotonic horizontal advection. An earlier reading attributed the sigma behaviour to a Polaris mixing misconfiguration. Removing that mixing fixed the centered runs and made the finite-volume ones worse, so the attribution was wrong: the diffusion had been damping the mode. The former 5.3.1 becomes 5.3.2. Reported from the Polaris side. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The pressure gradient holds a const Eos pointer, so it cannot call the Eos compute methods, and a counter in those methods could not see an evaluation inside the device-side quadrature loop. Rest the cost requirement on the interface and the wall-time check instead. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The finite-volume pressure gradient is now implemented (Omega E3SM-Project#493, with the anchor refined in E3SM-Project#635), so describe what that code does: - FiniteVolume is the default and Centered is kept as an option and a cross-check; the requirement no longer fixes the default. - The sea-floor anchor's shift to a common pressure never spans more than one layer: the shallower floor is compared with the deeper column's own interface just below it, then carried down with the matched-pressure integrand. Exactness is qualified to columns whose floors share depth and pressure. - The column scan is two passes in one team per edge, filling three per-edge arrays, after a separate kernel forms the reconstruction slopes; the layer mean uses the first moment, not a second one. - Record the reconstruction estimator, the option validation, where the Eos derivatives are computed, and the two helper headers. - Fix the algorithm summary, which still scanned from the sea surface. - Say where the fourth-order scheme attaches to this code. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Add the sloping-floor anchor test and its guard to the unit test section, and name the unit test's parts. - Replace the August seamount figures with the runs made with tracer diffusion explicitly off, and record what has been ruled out as the cause of the sigma instability: the anchor, unlimited tracer advection and vertical resolution. It tracks the slope. - Record the 10-day realistic global run, which supports A4 over the open ocean, and the measured cost of the pressure gradient. - Note that the Omega-vs-Polaris check caught the anchor rule, that only an overflow smoke test has been run, and which horiz_press_grad steps the anchor rule changes. - Close the harness limits that the Polaris task runs have since covered, and update the coverage summary. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
PGrad.md records the reasoning behind the centered pressure gradient as it was developed, so restore its text and keep only one change: the sentence promising a future design document now points to the higher-order design, which also revises the form given there. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The functor's inputs now match the design's signature, so drop the claim that they differ and keep only the reason. The sea-floor anchor is chosen for exactness, not conditioning, as design section 3.7.4 now says. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Choose the unlimited piecewise parabolic method of Colella and Woodward: interface values from the polynomial through the cumulative integral at the five nearest interfaces, built from divided differences of the layer means, and a mean-preserving parabola through them. Short columns take the polynomial through all their interfaces. - At the ends of a column take the coefficients from that polynomial's own derivatives at the layer midpoint, so a thin bottom cell does not amplify round-off when its reconstruction is extrapolated below the floor. - Record the measurements behind the choice over a parabola fitted to three layer means, and what the default two-point rule costs the parabolic reconstruction. - Say what the reconstruction adds to the tests. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- The parabolic reconstruction ships first, on its own with the two-cell stencil, then the wide stencil, then the second-order equation-of-state expansion; in each, Polaris gains the change first, written from the design. - The second-order expansion is kept unless measurement with the parabolic reconstruction and the wide stencil shows it does not help. - The defaults stay linear with the two-cell stencil until a realistic configuration shows the gain is worth the cost. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Confirm the parabolic reconstruction in Omega: the unit test, the ten horiz_press_grad variants against the Polaris kernel, and the seamount for six days. - On the sigma seamount it makes the instability grow three to five times faster; record that where the instability is described. - Qualify the third-order statement of section 6.7, whose refinement holds the displacement at a fixed number of layers, against the rates the unit test measures at fixed tilt. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
VerticalReconstruction: ppm now selects the unlimited piecewise parabolic method that the design specifies. Each layer's parabola keeps the layer mean and takes, at its interfaces, the derivative of the polynomial through the cumulative integral at the five nearest interfaces, built from divided differences of the layer means. Short columns use the polynomial through all their interfaces, and at the ends of a column the coefficients come from that polynomial's own derivatives, so a thin bottom cell does not amplify round-off when it is extrapolated below the floor. The column scan's three evaluation sites -- the integrand of each edge layer, the anchor's short integrals and its carry-down -- all go through one function, reconEval, so they cannot describe different water. The linear reconstruction is evaluated exactly as before and remains the default. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- The estimator on a single column: a quadratic reproduced everywhere, beyond the column included; a cubic met at every interface; the layer integral of the deviation; columns of one to three layers; and a thin bottom cell extrapolated below the floor, against the interface form, which this test shows amplifying round-off. - The matched-pressure integrand zero at every quadrature point on a quadratic, with a cubic as the control. - On the two-column state: the exactness gate on linear and quadratic profiles in both precisions, the linear reconstruction as the control, the host assembly's fidelity to the kernel, and a cubic converging faster than with the linear reconstruction. The host assembly now evaluates the reconstruction through reconEval, as the kernel does. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The user guide gives VerticalReconstruction's two values and what 'ppm' makes exact. The developer guide describes how the coefficients are formed, why the end layers take theirs from the polynomial's own derivatives, and that every evaluation goes through reconEval, and it lists the curvature arrays. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
TestingChrysalis, Intel, OpenMPI: CTests 62/62 at 88631ec, including the new parabolic tests in double and single precision, with no new build warnings. With E3SM-Project/polaris#902, run on an earlier build of the same model source, all 10 Posted by Claude Code on @xylar's behalf. The testing, analysis and wording above are AI-authored; please check them accordingly. |
What the parabolic reconstruction doesAgainst the quasi-analytic reference, At rest, any tendency is error. With T and S quadratic in pressure, Over a stepped sea floor with T and S quadratic in pressure, On the z-star seamount, kinetic energy after 6 days is 3.7 times lower with Scripts: https://web.lcrc.anl.gov/public/e3sm/diagnostic_output/xasaydavis/fv_hpg_ppm_20261025/scripts/ Posted by Claude Code on @xylar's behalf. The figures, analysis and wording above are AI-authored; please check them accordingly. |




Add a parabolic vertical reconstruction to the FiniteVolume pressure gradient, selected with VerticalReconstruction: ppm. It makes the scheme exact for resting profiles quadratic in pressure, not only linear ones, and it is more accurate than the linear reconstruction on most of the Polaris two-column tests. The linear reconstruction stays the default until a realistic configuration shows the gain is worth the cost. Builds on #635 and the design in #448; only the last six commits are new.
The design is revised here rather than in #448, which records it as it stood when the second-order scheme merged. The first three new commits update
PGradHighOrder.md(rendered).On sigma layers over the seamount,
ppmmakes the existing instability grow faster, which is one more reasonlinearstays the default.The Polaris reference and tests are in E3SM-Project/polaris#902.
Checklist
Documentation:
Linting
Building
Testing
aurora, intel, mpich
aurora, intelgpu, mpich
chrysalis, intel, openmpi
frontier, craygnu, mpich
frontier, craygnu-mphipcc, mpich
pm-cpu, gnu, mpich
pm-gpu, gnugpu, mpich
Provide relevant details in a comment to the PR titled
TestingNew tests:
Posted by Claude Code on @xylar's behalf. The wording above is AI-authored; please check it accordingly.
🤖 Generated with Claude Code