Pressure Gradient (PGrad)

Omega includes a PressureGrad class that computes horizontal pressure gradient tendencies for the non-Boussinesq momentum equation. The implementation supports a centered difference scheme as the default, with a placeholder for future high-order methods. The class follows the same factory pattern used by other Omega modules.

PressureGradType enum

An enumeration of the available pressure gradient schemes is defined in PGrad.h:

enum class PressureGradType { Centered, HighOrder1, HighOrder2 };

This is used to select which pressure gradient method is applied at runtime.

Initialization

An instance of PressureGrad requires both a HorzMesh and a VertCoord, so these classes and all of their dependencies must be initialized before PressureGrad can be initialized. The static method:

OMEGA::PressureGrad::init();

initializes the default PressureGrad instance using the default HorzMesh and VertCoord instances and the global Omega configuration. A pointer to the default instance can be retrieved at any time using:

OMEGA::PressureGrad* DefPGrad = OMEGA::PressureGrad::getDefault();

Creating additional instances

Additional named instances can be created using:

OMEGA::PressureGrad* MyPGrad =
    OMEGA::PressureGrad::create("MyPGrad", Mesh, VCoord, Options);

where Mesh is a pointer to a HorzMesh, VCoord is a pointer to a VertCoord, and Options is a pointer to the Config. A named instance can be retrieved later using:

OMEGA::PressureGrad* MyPGrad = OMEGA::PressureGrad::get("MyPGrad");

Constructor behavior

The constructor reads the PressureGrad section from the configuration, stores references to mesh and vertical coordinate data needed for computation, and enables the appropriate functor based on the configured PressureGradType. It also allocates placeholder arrays for tidal potential and self-attraction/loading, which are intended to be populated by a future tidal forcing module. Currently these arrays are initialized to zero.

Computing the pressure gradient

To compute pressure gradient tendencies and accumulate them into a tendency array:

PGrad->computePressureGrad(Tend, State, VCoord, EqState, TimeLevel);

where:

  • Tend is a 2D array (NEdgesAll × NVertLayers) that the pressure gradient tendency is accumulated into

  • State is the current OceanState, from which layer thickness is extracted at the given TimeLevel

  • VCoord provides pressure, interface height, and geopotential fields

  • EqState provides the specific volume field

  • TimeLevel selects which time level of the state to use

The method uses hierarchical Kokkos parallelism: an outer parallelForOuter loop iterates over edges, and an inner parallelForInner loop iterates over vertical chunks. The appropriate functor is dispatched based on PressureGradChoice.

Functors

PressureGradCentered

This functor implements a centered difference approximation of the pressure gradient tendency. For each edge, it first computes the layer-invariant tidal and self-attraction/loading contribution:

GradGeoPot = grad(TidalPotential) + grad(SelfAttractionLoading)

Then, for each vertical layer K, it computes three terms:

  1. Montgomery potential gradient: The average of the horizontal gradients of the Montgomery potential (\(\alpha p + g z\)) at the top (interface K) and bottom (interface K+1) of the layer. This compactly represents the combined effect of the pressure gradient and the geopotential contribution from tilted coordinate surfaces.

  2. Specific volume correction: A correction term equal to the edge-averaged pressure at mid-layer multiplied by the horizontal gradient of specific volume. This accounts for horizontal density variations that are not captured by the Montgomery potential form.

  3. Tidal and geopotential forcing (GradGeoPot): The external geopotential contribution from tidal forcing and self-attraction/loading, applied uniformly across all layers at an edge.

The tendency update for each layer is:

Tend(IEdge, K) += EdgeMask(IEdge, K) * (-GradMontPot + PGradAlpha - GradGeoPot)

where EdgeMask is applied to enforce land boundary conditions. The functor operator signature is:

KOKKOS_FUNCTION void operator()(const Array2DReal &Tend, I4 IEdge, I4 KChunk,
                                const Array2DReal &PressureMid,
                                const Array2DReal &PressureInterface,
                                const Array2DReal &ZInterface,
                                const Array1DReal &TidalPotential,
                                const Array1DReal &SelfAttractionLoading,
                                const Array2DReal &SpecVol) const;

PressureGradHighOrder

This functor is a placeholder for a future high-order pressure gradient implementation suitable for ice shelf cavities and complex bathymetry. Currently it performs no computation (a no-op).

Configuration

The pressure gradient type is selected in the input YAML file:

PressureGrad:
   PressureGradType: 'centered'

Valid options for PressureGradType are:

  • 'centered' or 'Centered': centered difference approximation (default)

  • 'HighOrder1': first high-order method (placeholder, future implementation)

If an unrecognized value is provided, the implementation falls back to the centered scheme and logs an informational message.

Data members

The PressureGrad class stores the following key data:

Member

Type

Description

NEdgesAll

I4

Total number of edges including halo

NChunks

I4

Number of vertical chunks for vectorization

NVertLayers

I4

Number of vertical layers

NVertLayersP1

I4

Number of vertical layers plus one

MinLayerEdgeBot

Array1DI4

Minimum active layer index for each edge

MaxLayerEdgeTop

Array1DI4

Maximum active layer index for each edge

TidalPotential

Array1DReal

Tidal potential (placeholder, currently zero)

SelfAttractionLoading

Array1DReal

Self-attraction and loading term (placeholder, currently zero)

CenteredPGrad

PressureGradCentered

Centered pressure gradient functor

HighOrderPGrad

PressureGradHighOrder

High-order pressure gradient functor

PressureGradChoice

PressureGradType

Selected pressure gradient method

Removal

To remove all PressureGrad instances:

OMEGA::PressureGrad::clear();

To remove a specific named instance:

OMEGA::PressureGrad::erase("MyPGrad");