Reworked HPG Reference Solution
Creation date: 2026/06/14
Contributors: Xylar Asay-Davis, Claude
Background: the horizontal pressure gradient and its reference solution
Omega is a non-Boussinesq, hydrostatic ocean model whose prognostic vertical
coordinate is pseudo-height, \(\tilde{z} = -p / (\rho_0 g)\), where \(p\) is sea
gauge pressure, \(\rho_0\) is a reference seawater density (RhoSw), and \(g\) is
gravitational acceleration. The ocean/horiz_press_grad task family in Polaris
exists to verify the convergence of Omega’s horizontal pressure-gradient (HPG)
operator against a high-fidelity reference solution, as called for in the Omega
pressure gradient design document
(PGrad.md, “Test: Spatial convergence to exact solution”).
The continuous horizontal pressure-gradient force (HPGF) per unit mass that
Omega’s momentum tendency must reproduce is, from the
Omega V1 governing equations
(OmegaV1GoverningEqns.md),
where \(\alpha = 1/\rho\) is specific volume, \(\Phi = g z\) is the geopotential (neglecting tidal and self-attraction-and-loading terms), and \(\nabla\) is the along-layer horizontal gradient. Using the hydrostatic relation, Omega rewrites this through the Montgomery potential \(M = \alpha p + g z\) as
and discretizes it with a centered scheme in which \(\alpha\) is held constant within each layer, the Montgomery gradient is evaluated at layer interfaces and averaged to the layer midpoint, and the along-layer gradient is a two-cell finite difference across the edge.
The two-column task and its comparisons
Each horiz_press_grad task variant (salinity_gradient,
temperature_gradient, ztilde_gradient) builds a two-column mesh at a set of
paired horizontal and vertical resolutions. Per resolution:
An
Initstep (aPStarInitStep, see the p-star initialization design) builds the p-star coordinate and the initial conservative temperature (CT) and absolute salinity (SA) from piecewise pseudo-height profiles, and computes a Polaris HPGA from a two-cell finite difference of the Montgomery potential.A
Forwardstep runs Omega for a single time step and writes Omega’sNormalVelocityTend, which is just the HPGA.An
Analysisstep performs two comparisons:omega_vs_reference— Omega’s HPGA against the high-fidelity reference solution, fit to a power law to measure the convergence rate.omega_vs_python— Omega’s HPGA against the Polaris/Python HPGA fromInit, a code-correctness check that the two implementations of the same discrete scheme agree to a tight tolerance.
Because each forward run is a single step with no coordinate motion, the
forward layer pseudo-heights and geometric heights are identical to those in
Init; the omega_vs_python comparison therefore needs no special handling.
The current reference solution and why it must be reworked
The current Reference step (reference.py) builds five columns at
\(x = \Delta x_\text{ref}\,[-1.5,-0.5,0,0.5,1.5]\), integrates the hydrostatic
relation upward from each seafloor to obtain geometric height \(z(\tilde z)\),
forms \(M\), and takes a 4th-order finite difference across columns to obtain
\(\partial M/\partial x\) and \(\partial \alpha/\partial x\) at the center column,
giving HPGA \(= -\partial M/\partial x + p\,\partial\alpha/\partial x\). It writes
the result on a vertical grid deliberately refined (via a greatest-common-
divisor construction) so that every test grid’s layer midpoints land exactly on
reference grid points. Analysis then samples the reference by exact z̃
matching with no interpolation.
This design has two structural weaknesses:
Grid-alignment fragility. Exact-match sampling only works when the reference and test pseudo-heights coincide. As soon as a nonzero
SurfacePressureis applied, the p-star coordinate stretches and squashes the column in proportion to the pressure thickness, and partial bottom cells produce interfaces that no longer align across vertical resolutions. The reference must instead be queryable at arbitrary pseudo-height with no loss of accuracy.Breakdown near bathymetry. The cross-column finite-difference stencil requires every neighboring column to be valid at a given \(\tilde z\). Near the seafloor, collocation points in some columns fall below their own bathymetry and the stencil cannot be formed, so those layers are masked out. The accuracy is also only as good as the stencil and the matched grid, which is insufficient for assessing the higher-than-second-order HPG operators planned for Omega.
Summary
This design replaces the multi-column, finite-difference reference solution with a single-column, analytic reference computed at the edge between the two columns (\(x = 0\)). The new capability:
Evaluates the exact continuous HPGF directly via a chain-rule / Leibniz expansion of the along-pseudo-height gradient, using TEOS-10 specific-volume derivatives. Because the continuous HPGF is coordinate-invariant, this single central-column expression is exact in the horizontal — there is no finite-difference truncation and no dependence on neighboring columns, so the near-bathymetry breakdown disappears and the reference is fidelity-limited only by a smooth one-dimensional quadrature.
Is a callable function of \(\tilde z\), so it can be sampled at exactly the pseudo-heights a test produces, eliminating the grid-alignment requirement.
Supports fully general horizontal variation of every prescribed input.
Is consumed directly by
Analysisthrough a shared evaluator module; the separateReferencestep is removed.
The accuracy assessment compares Omega’s along-layer HPGA to the reference using a layer-averaged target: for each model layer, the reference is averaged over that layer’s pseudo-height extent at the edge. This compares like with like (a layer mean against a layer mean) so that legitimate layer tilt and finite layer thickness are accounted for in the target rather than charged as discretization error.
The primary challenges are (a) formulating the continuous reference correctly so that the along-layer computation is judged on its own merits, (b) differentiating the prescribed profiles with respect to the horizontal coordinate at fixed pseudo-height — including the case where the profile node pseudo-heights themselves tilt — and (c) integrating the resulting expression to high accuracy in the vertical. The design is successful if the reference can be evaluated at any pseudo-height without loss of accuracy, remains valid throughout the water column including immediately above the bathymetry, is accurate enough to serve a beyond-second-order HPG operator, supports general horizontal input variation, and reproduces (with re-tuned thresholds) the convergence behavior the existing regression tests check.
Requirements
Requirement: The reference HPGA can be evaluated at an arbitrary pseudo-height without loss of accuracy
Date last modified: 2026/06/14
Contributors: Xylar Asay-Davis, Claude
The reference solution shall be evaluable at any pseudo-height within the water column produced by a test, to high accuracy, without requiring that the reference and test vertical grids coincide. This must hold when a nonzero sea-surface pressure stretches or squashes the p-star column and when partial bottom cells misalign layer interfaces across resolutions.
Requirement: The reference is valid throughout the water column, including immediately above the bathymetry
Date last modified: 2026/06/14
Contributors: Xylar Asay-Davis, Claude
The reference shall remain valid and accurate for every pseudo-height from the free surface down to the seafloor of the column at the edge between the two test columns. It shall not break down or require masking in the layers nearest the bathymetry.
Requirement: The reference is accurate enough to assess HPG operators beyond second order
Date last modified: 2026/06/14
Contributors: Xylar Asay-Davis, Claude
The reference shall be of sufficient fidelity that, when an HPG operator more accurate than the current second-order centered scheme is introduced in Omega, the reference error does not limit the measured convergence. In particular, the reference shall not introduce a fixed-order horizontal truncation error of its own.
Requirement: The reference supports general horizontal variation of the prescribed inputs
Date last modified: 2026/06/14
Contributors: Xylar Asay-Davis, Claude
The reference shall correctly represent horizontal variation of every prescribed input that the task permits: the geometric sea-surface height, the geometric seafloor depth, the seafloor pseudo-height, and the temperature and salinity profile node values and node pseudo-heights. No input variation supported by the task configuration may be assumed to be horizontally uniform.
Requirement: The accuracy assessment evaluates the along-layer scheme on its own merits
Date last modified: 2026/06/14
Contributors: Xylar Asay-Davis, Claude
The comparison between the model’s along-layer HPGA and the reference shall measure only the genuine discretization error of the along-layer scheme. It shall not attribute legitimate, physically correct effects of tilted layers or of finite layer thickness to discretization error. The reference shall represent the exact continuous pressure-gradient force that the along-layer scheme converges to as both horizontal and vertical resolution are refined.
Requirement: The capability integrates with the existing two-column task without a separate precompute step
Date last modified: 2026/06/14
Contributors: Xylar Asay-Davis, Claude
The reference shall be available to the Analysis step on demand at the
pseudo-heights each test produces, without a separate precomputed reference
artifact and without changing the structure of the Init/Forward/Analysis
workflow or the two comparisons (omega_vs_reference and omega_vs_python).
Algorithm Design
Algorithm Design: The continuous, coordinate-invariant reference and the cancellation of layer-slant terms
Date last modified: 2026/06/14
Contributors: Xylar Asay-Davis, Claude
The reference is the exact continuous pressure-gradient acceleration that Omega’s discrete operator must converge to. The key fact that makes a single central-column evaluation correct is that this acceleration is independent of the vertical coordinate used to evaluate the horizontal gradients.
Write the horizontal gradients along a general layer label \(\sigma\) (constant along a model coordinate surface). Pseudo-height is, by definition, a rescaled pressure, \(p = -\rho_0 g\,\tilde z\), so along constant \(\tilde z\) the pressure is constant. Using the hydrostatic relation \(\partial z/\partial \tilde z = \rho_0 \alpha\), the along-\(\sigma\) gradients of pressure and geometric height are
Substituting into \(\mathbf{a}_\text{PGF} = -(\alpha\,\nabla_\sigma p + g\,\nabla_\sigma z)\), the two terms proportional to the coordinate slope \(\left.\partial_x\tilde z\right|_\sigma\) carry the same \(\alpha\) at the same point and cancel exactly:
This is the standard statement that the pressure-gradient force does not depend on the coordinate used to compute it. Consequences for the design:
The reference is \(-g\,\partial_x z|_{\tilde z}\), evaluated at the edge (\(x=0\)). It can be computed entirely at constant \(\tilde z\), which is the convenient frame, without approximation, even when the model layers slant (as in
ztilde_gradient) or bend near the bathymetry (partial cells).The cancellation holds only for the total acceleration. Omega’s discrete pieces \(\nabla M\) and \(p\,\nabla\alpha\) are individually coordinate-dependent and large; the design never compares those pieces to the reference, only the total. The residual between Omega’s along-layer total and the continuous total is therefore the genuine discretization error of the along-layer scheme — including the classic slant-induced pressure-gradient error that the future high-order operator is intended to reduce.
Algorithm Design: Single-column chain-rule / Leibniz expression for the reference
Date last modified: 2026/06/14
Contributors: Xylar Asay-Davis, Claude
Geometric height as a function of pseudo-height in a single column is obtained by integrating the hydrostatic relation from the surface:
where \(\eta(x)\) is the geometric sea-surface height, \(\tilde z_s(x)\) is the
surface pseudo-height (\(\tilde z_s = -p_s/(\rho_0 g)\), zero only when the surface
pressure \(p_s\) is zero), and \(p(\tilde z') = -\rho_0 g\,\tilde z'\) depends only on
\(\tilde z'\) (not on \(x\)). The integral runs downward, so for \(\tilde z < \tilde
z_s\) it is negative and \(z < \eta\), as required. The reference is anchored at
the surface rather than the seafloor because that is the boundary the model
honours: Init/Omega build the p-star column from the prescribed sea-surface
height and surface pressure, so the HPGA vanishes at the surface (for zero
surface slope) and grows downward. Anchoring elsewhere — e.g. at the configured
seafloor pseudo-height, which is a coordinate buffer below the deepest valid
layer rather than a honoured geometric boundary — would reconstruct a different
\(z(\tilde z)\) and miss the model by a constant offset.
Differentiating with respect to \(x\) at fixed \(\tilde z\), the lower integration limit depends on \(x\), so the Leibniz rule contributes a boundary term:
Because \(p\) is fixed along constant \(\tilde z'\), the integrand involves only the horizontal variation of the thermohaline state through the TEOS-10 specific volume:
where \(\alpha_{S_A} = \partial \alpha / \partial S_A\) and \(\alpha_{\Theta} = \partial \alpha / \partial \Theta\) are the first derivatives of specific volume from the equation of state, evaluated at the central column’s \((S_A, \Theta, p)\). The reference acceleration is then
Notable properties:
No geometric-height integration is required for the HPGA. Everything is expressed through the prescribed profiles \(S_A(\tilde z'), \Theta(\tilde z')\) and the analytic pressure \(p(\tilde z') = -\rho_0 g\,\tilde z'\) at the central column, plus the input slopes \(\eta'\) and \(\tilde z_s'\). The only quadrature is the smooth one-dimensional integral of \(\partial_x\alpha\). (A geometric-height integration may still be performed for optional diagnostics.)
Single column, valid to the seafloor. The expression is evaluated only at \(x = 0\) and is well defined for every \(\tilde z \in [\tilde z_b(0), \tilde z_s(0)]\). Integrating from the surface loses none of this validity — it reaches every pseudo-height down to and immediately above the bathymetry — and it never references neighboring columns, so it cannot break down above the bathymetry.
Exact in the horizontal. The horizontal gradient is analytic; there is no \(\Delta x\) truncation, satisfying the beyond-second-order fidelity requirement.
The boundary term uses \(\tilde z_s(0) = \) the surface pseudo-height (the
shallowest z_tilde node) and \(\alpha(\tilde z_s)\) evaluated from the profiles
at \(\tilde z_s(0)\). The slopes \(\eta'\) (from geom_ssh_grad) and \(\tilde z_s'\)
(from the surface z_tilde_grad node) are read from the configuration gradients
(converted from per-km to per-m and projected onto the edge normal). They are
kept fully general: a nonzero sea-surface height or surface pressure makes
\(\eta'\) and/or \(\tilde z_s'\) (and \(\tilde z_s\) itself) nonzero, and the formula
already accounts for them. A regression test that exercises a nonzero surface
pressure is deferred to a follow-up PR; the present tasks all use zero surface
slope and pressure.
Algorithm Design: Horizontal derivatives of the prescribed profiles at fixed pseudo-height
Date last modified: 2026/06/14
Contributors: Xylar Asay-Davis, Claude
The factors \(\partial_x S_A|_{\tilde z'}\) and \(\partial_x \Theta|_{\tilde z'}\)
are the horizontal gradients of the prescribed profiles at fixed pseudo-height.
The profiles are defined by node values and node pseudo-heights, each of which
varies linearly in \(x\) (configuration *_mid plus *_grad\(\cdot x\)), and a
monotone PCHIP interpolant in pseudo-height (the same interpolant Init uses, so
the reference and the test describe the same physical state).
The profile value at fixed \(\tilde z'\) depends on \(x\) through both the node
values and, in the general case (z_tilde_grad \(\neq 0\)), the node
pseudo-heights. Because PCHIP is nonlinear in its node data, the horizontal
derivative is obtained by differencing the analytic input profiles: the
interpolant is constructed at \(x = \pm\varepsilon\) from the exactly known linear
node functions and evaluated at \(\tilde z'\), and a centered difference is taken,
and similarly for \(\Theta\). Since the nodes are exactly linear in \(x\) and the interpolant is smooth in \(x\), this is accurate to round-off for a suitably chosen \(\varepsilon\) (optionally refined by Richardson extrapolation). This single construction handles all task variants uniformly, including tilted node pseudo-heights, satisfying the general-input requirement.
The specific-volume derivatives \(\alpha_{S_A}\) and \(\alpha_{\Theta}\) are obtained from the
equation of state at the central column’s \((S_A(\tilde z'), \Theta(\tilde z'),
p(\tilde z'))\) — concretely, from gsw.specvol_first_derivatives for TEOS-10.
Algorithm Design: Building the reference profile and the layer-averaged comparison
Date last modified: 2026/06/14
Contributors: Xylar Asay-Davis, Claude
The reference is needed as a layer mean over each model layer. Define the cumulative integral
The integrand is smooth, so \(I(\tilde z)\) — and therefore \(a(\tilde z)\) — is evaluated with a high-order quadrature (the existing Gauss–Legendre / adaptive machinery; see Implementation). \(a(\tilde z)\) is thus available as an accurate callable of pseudo-height.
For the comparison, each model layer \(k\) spans, at the edge, the pseudo-height interval \([\tilde z^{\text{bot}}_{k}, \tilde z^{\text{top}}_{k}]\), where the edge interfaces are the average of the two cells’ interface pseudo-heights (the edge lies midway between the columns; for linearly varying inputs this average equals the central-column value). The reference target for layer \(k\) is the layer mean
evaluated by high-order quadrature within the layer. This compares the model’s layer-mean acceleration to the true layer-mean acceleration, so finite layer thickness and layer tilt are folded into the target rather than counted as error (satisfying the “on its own merits” requirement). As both resolutions refine, \(\overline{a}_k \to a(\tilde z_k)\) and the residual is the scheme’s genuine discretization error.
The model layer interfaces are taken from the test output (identical between
Init and Forward), so the reference is sampled at exactly the test’s
pseudo-heights and the partial-cell bottom geometry is honored automatically. As
in the current analysis, the single deepest valid model layer (which abuts the
bathymetry) is excluded from the error metric.
The sign/orientation of \(a\) must match the edge-normal convention used by the
model output: the horizontal coordinate \(x\) increases from the first to the
second cell on the internal edge. Analysis determines that orientation from
the mesh cell positions and applies it consistently to the input slopes and the
reference acceleration.
Algorithm Design: Removal of the separate reference step
Date last modified: 2026/06/14
Contributors: Xylar Asay-Davis, Claude
Because the reference is an inexpensive callable evaluated at the test’s
pseudo-heights, it does not need to be precomputed by a dedicated step. The
Reference step is removed. Analysis constructs the reference evaluator from
the configuration (which fully determines the central column) and evaluates the
layer-averaged target per resolution. The greatest-common-divisor reference
grid, the five-column construction, the cross-column finite-difference stencil,
and the exact-match sampling are all retired.
Implementation
Implementation: Analysis consumes the reference directly
Date last modified: 2026/06/14
Contributors: Xylar Asay-Davis, Claude
In analysis.py:
Remove the
referencedependency, thereference_solution.ncinput, and_sample_reference_without_interpolation.In
setup, drop the reference-step input wiring; keep the per-resolutioninit,forward,culled_mesh, andvert_coordinputs.In
run, construct a singleReferenceColumnfromself.config(its orientationx_signis derived once from the mesh, see below). Then for each resolution:Identify the internal edge and its two cells with the existing
_get_internal_edge.Determine
x_signfrom the cells’xCell(sign ofxCell[cell1] - xCell[cell0]), so the reference gradient matches the model edge-normal convention. The current Python HPGA inInit(_compute_montgomery_and_hpga) usesx = horiz_res*[-0.5, 0.5]for cells[0, 1]; the new orientation logic must reproduce the same sign the existingomega_vs_pythoncomparison relies on.Read the edge layer-interface pseudo-heights as the average of the two cells’
ZTildeInterfacefrom the forward output (equivalentlyInit).Compute
ref_layer_mean = reference.layer_mean_hpga(edge_interfaces).Restrict to valid layers via
maxLevelCell(shallowest of the two cells, as today) and drop the deepest valid layer (abuts bathymetry).RMS-difference Omega’s
NormalVelocityTendat the edge againstref_layer_mean; accumulate per resolution.
The power-law fit, threshold checks, plots, and
omega_vs_pythoncomparison are unchanged in structure. Optionally overlay the reference layer-mean profile on a diagnostic plot at the finest resolution.
Implementation: task wiring and configuration
Date last modified: 2026/06/14
Contributors: Xylar Asay-Davis, Claude
task.py: remove theReferencestep creation and its entry in theAnalysisdependencies dict ({'init': ..., 'forward': ...}only).horiz_press_grad.cfg: removereference_horiz_res(no neighboring columns). Keepreference_quadrature_methodfor the one-dimensional integral and the layer mean. Retain theomega_vs_reference_*threshold and convergence-rate options; their values will likely need re-tuning now that the reference is exact in the horizontal (see Testing).Delete the now-unused machinery in the old
reference.py: the five-column setup,_get_reference_vert_resand_fraction_gcd, the 4th-order stencil (_compute_4th_order_gradient,_check_gradient), the per-column geometric-height integration used for the cross-column difference, and thereference_solution.ncoutput. Keep and relocate the quadrature helpers used byReferenceColumn.
Implementation: orientation and consistency safeguards
Date last modified: 2026/06/14
Contributors: Xylar Asay-Davis, Claude
The reference must use the same \(+x\) orientation as
Init/Forward. Derive it fromxCelland assert that the resulting sign reproduces the existingomega_vs_pythonagreement at the coarsest resolution as a guard against a flipped gradient.The edge surface pseudo-height (average of the two cells’ surface pseudo-heights) equals \(\tilde z_s(0)\) for linearly varying inputs; assert this equality to a tolerance to catch configuration or averaging mistakes.
Keep the EOS path restricted to TEOS-10 (as the task already requires Omega), and guard
dalpha_dxagainst requestingspecvol_first_derivativesoutside gsw’s valid range.
Testing
Testing and Validation: arbitrary-pseudo-height evaluation and near-bathymetry validity
Date last modified: 2026/06/14
Contributors: Xylar Asay-Davis, Claude
Add unit tests for ReferenceColumn (e.g.
tests/ocean/horiz_press_grad/test_reference.py):
Constant-density column. With a configuration giving spatially constant \(\alpha\) (so \(\partial_x\alpha = 0\)),
hpgamust equal the closed form \(-g[\eta' - \rho_0\alpha\,\tilde z_s']\) at every pseudo-height, to round-off, for several arbitrary \(\tilde z\) including values that fall between any plausible grid points. (With a nonzero surface pseudo-height slope \(\tilde z_s'\), evaluate the boundary term at the surface, where the integral is exactly zero.)Zero horizontal variation. With all input gradients zero,
hpgamust be identically zero (no spurious pressure-gradient signal) for arbitrary \(\tilde z\), including immediately above the seafloor.Independence from sampling. Evaluate
hpgaon two unrelated pseudo-height sets (one of which deliberately does not align with any uniform grid) and on a shifted set emulating a nonzero surface pressure; values at coincident pseudo-heights must agree to round-off, demonstrating freedom from grid alignment.
Testing and Validation: fidelity beyond second order
Date last modified: 2026/06/14
Contributors: Xylar Asay-Davis, Claude
Brute-force gradient cross-check. For a \(\tilde z\) comfortably above the seafloor, compare
ReferenceColumn.hpgato a high-accuracy finite-difference estimate formed by fully integrating \(z(\tilde z; x)\) at \(x = \pm\delta\) and differencing at constant \(\tilde z\), for a sequence of shrinking \(\delta\). The analytic value must agree with the Richardson-extrapolated finite difference to many digits, confirming the chain-rule/Leibniz implementation and that the reference carries no fixed-order horizontal truncation error.Quadrature convergence. Confirm that refining the quadrature panel count changes
hpgaby amounts decreasing at the expected high order and that the result is converged well below the model HPGA error levels.
Testing and Validation: general horizontal input variation
Date last modified: 2026/06/14
Contributors: Xylar Asay-Davis, Claude
Tilted nodes. With
z_tilde_grad\(\neq 0\) (tilted profile node pseudo-heights), verifydalpha_dxagainst an independent finite difference of \(\alpha\) in \(x\) at fixed \(\tilde z\), confirming the analytic-input differencing handles moving nodes.Each gradient in isolation. Exercise nonzero
salinity_grad,temperature_grad,geom_ssh_grad, and the surfacez_tilde_gradnode one at a time and confirm the corresponding boundary or integrand contribution appears with the correct sign and magnitude. The surface boundary terms (geom_ssh_grad, surfacez_tilde_grad) are kept general so a follow-up nonzero-surface-pressure test needs no further changes.
Testing and Validation: layer-averaged comparison and regression behavior
Date last modified: 2026/06/14
Contributors: Xylar Asay-Davis, Claude
Layer-mean correctness. For a known smooth \(a(\tilde z)\), verify
layer_mean_hpgareturns the analytic layer averages, and that for vanishing layer thickness it approaches the pointwise value.Regression suite. Run all three task variants (
salinity_gradient,temperature_gradient,ztilde_gradient) in theomega_prsuite. Confirm theomega_vs_pythoncomparison still passes at its tight tolerance (unchanged scheme), and thatomega_vs_referenceproduces a convergence slope in the expected range. Because the reference is now exact in the horizontal, re-tuneomega_vs_reference_convergence_rate_min/max,omega_vs_reference_high_res_rms_threshold, andomega_vs_reference_convergence_fit_max_resolutionto the observed behavior; document the updated values and the resolution at which curvature in the convergence plot appears.Tilted-layer case. Pay particular attention to
ztilde_gradient, whose slanted layers exercise the slant-induced pressure-gradient error; confirm the layer-averaged comparison yields a clean convergence rather than a spurious floor from charging layer tilt as error.