Skip to content

Commit 7715d0a

Browse files
committed
Add pressure gradient design document
1 parent 41e25a4 commit 7715d0a

File tree

2 files changed

+198
-0
lines changed

2 files changed

+198
-0
lines changed
Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
(omega-design-pressure-grad)=
2+
# Pressure Gradient
3+
4+
5+
## 1 Overview
6+
The pressure gradient will be responsible for computing the horizontal gradients of both the pressure and geopotential terms for the non-Boussinesq primative equations implemented in Omega.
7+
In the non-Boussinesq model, the vertical coordinate will be pressure as opposed to height.
8+
In a pure pressure coordinate the pressure gradient term disappears (since the pressure does not vary along lines of constant pressure), just as how the geopotential term disappears in a pure z coordinate model.
9+
However, similar to MPAS-Ocean's support for tilted height coordinates, Omega will allow for tilted pressure coordinates.
10+
This means that Omega will need to compute both the pressure and geopotential gradients.
11+
12+
## 2 Requirements
13+
14+
### 2.1 Requirement: Support for tilted pressure coordinates for the non-Boussinesq primitive equations
15+
16+
The pressure gradient will compute the horizontal gradients of both the pressure and geopotential to support tilted pressure coordinates in the non-Boussinesq model.
17+
This will allow for the use of a $p^\star$ coordinate, which functions similarly to the $z^\star$ in the Boussinesq MPAS-Ocean model.
18+
19+
### 2.2 Requirement: Initial support for a simple centered pressure gradient
20+
21+
For initial global cases without ice shelf cavities, the pressure and geopotential gradients will be computed with a simple centered difference approximation. In later versions of Omega, one ore more high-order pressure gradients will be implemented and will replace the centered approach in production runs.
22+
However, the centered pressure gradient will remain an option for use in idealized testing.
23+
24+
### 2.3 Requirement: Flexibility to support a high-order pressure gradient
25+
The centered pressure gradient will be insufficient for future versions of Omega that include ice shelf cavities and high resolution shelf breaks.
26+
The pressure gradient framework should be flexible enough to support a high-order pressure gradient in the future.
27+
28+
### 2.4 Requirement: Flexibility to support tidal forcing and sea level change
29+
In later versions of Omega, the pressure gradient will need to be able to include tidal forcing in the geopotential term.
30+
These tidal forcings include both the tidal potential and the self attraction and loading terms.
31+
Additionally, other changes to the geoid
32+
33+
### 2.5 Requirement: Pressure gradient for barotropic mode
34+
35+
For split barotropic-baroclinic timestepping, the pressure gradient should provide the bottom pressure gradient tendency in the barotropic mode.
36+
37+
### Desired:
38+
39+
## 3 Algorithmic Formulation
40+
The non-Boussinesq momentum equation is
41+
$$ \frac{D \mathbf{u}_h}{D t } + f\boldsymbol{k}\times \mathbf{u}_h + \left(v\nabla_A p + \nabla_A \phi \right) = \boldsymbol{\mathcal{F}}. $$
42+
43+
where $\mathbf{u}_h$ is the horizontal velocity, $f$ is the Coriolis parameter, $v = \frac{1}{\rho}$ is the specific volume, $\rho = \rho(T,S,p)$ is the density, $p$ is the hydrostatic pressure, $\phi$ is the geopotential, and $\boldsymbol{\mathcal{F}}$ are the dissipative terms.
44+
The operator $\nabla_A$ is the gradient along a constant surface, $A$, and the total derivative is
45+
46+
$$ \frac{D \mathbf{u}_h}{D t } = \left( \frac{\partial}{\partial t} \right)_A + \mathbf{u}_h\cdot \nabla_A + \omega\frac{\partial}{\partial A}, $$
47+
48+
where $\omega$ is the cross coordinate flow.
49+
In the layered non-Boussinesq equations, the prognostic variable is the pressure thickness $h_k$, so that the geometric thickness (in meters) is a diagnostic variable defined as:
50+
51+
$$ \Delta z_k = v_k h_k. $$
52+
53+
The pressure at vertical cell interfaces is the found by summing the pressure thicknesses:
54+
55+
$$ p_{K+1/2} = p_{surf} + g\sum_{k=1}^K h_k. $$
56+
57+
The geopotential at vertical cell integrates is found by summing the pressure thicknesses multiplied by the specific volume:
58+
59+
$$ \phi_{K+1/2} = g\left(z_b + \sum_{k=K}^{N} v_k h_k\right), $$
60+
61+
where $z_b$ is the (positive-up) bottom depth.
62+
63+
The discrete gradient operator at an edge is:
64+
65+
$$ \nabla {(\cdot)} = \frac{1}{d_e} \sum_{i\in CE(e)} -n_{e,i} (\cdot)_i $$
66+
67+
where $d_e$ is the distance between cell centers, $CE(e)$ are the cells on edge $e$, and $n_{e,i}$ is the sign of the edge normal with respect to cell $i$.
68+
Therefore the centered pressure gradient will be calculated as:
69+
70+
$$ T^p_k = \frac{1}{d_e} \left( \widehat{v}_{k,e} \sum_{i \in CE(e)} n_{e,i} \overline{p}_{k,i} + \sum_{i\in CE(e)} n_{e,i} \overline{\phi}_{k,i}\right), $$
71+
72+
$$ = \frac{1}{d_e} \left( \sum_{i \in CE(e)} n_{e,i} \left( \widehat{v}_{k,e}\overline{p}_{k,i} + \overline{\phi}_{k,i} \right) \right), $$
73+
74+
with the vertical averaging operator defined as:
75+
76+
$$ \overline{(\cdot)} = \frac{1}{2} \left((\cdot)_{k+1/2} + (\cdot)_{k-1/2} \right)$$
77+
78+
and the horizontal averaging operator:
79+
80+
$$\widehat{(\cdot)} = \frac{1}{2} \left( (\cdot)_{i=1} + (\cdot)_{i=2}\right)$$
81+
82+
## 4 Design
83+
84+
### 4.1 Data types and parameters
85+
86+
The `PressureGradient` class will be used to perform the horizontal gradients of the pressure and geopotential
87+
```c++
88+
class PressureGrad{
89+
public:
90+
private:
91+
PressureGradCentered CenteredPGrad;
92+
PressureGradHighOrder HighOrderPGrad;
93+
PressureGradType PressureGradChoice;
94+
I4 NVertLevels;
95+
I4 NChuncks;
96+
Array2DI4 CellsOnEdge;
97+
Array1DReal DvEdge;
98+
Array1DReal EdgeSignOnCell;
99+
}
100+
```
101+
The user will select a pressure gradient option at runtime in the input yaml file under the pressure gradient section:
102+
```yaml
103+
PressureGrad:
104+
PressureGradType: 'centered'
105+
```
106+
An `enum class` will be used to specify options for the pressure gradient used for an Omega simulation:
107+
```c++
108+
enum class PressureGradType{
109+
Centered,
110+
HighOrder
111+
}
112+
```
113+
The functions to compute the centered and high order pressure gradient terms will be implemented as functors and the pressure gradient class will have private instances of these classes.
114+
### 4.2 Methods
115+
116+
```c++
117+
class PressureGrad{
118+
public:
119+
static PressureGrad *create();
120+
void computePressureGrad();
121+
void computePressureGradBtr();
122+
private:
123+
124+
}
125+
```
126+
#### 4.2.1 Creation
127+
128+
The constructor will be responsible for storing any static mesh information as private variables and handling the selection of the user-specified pressure gradient option.
129+
```c++
130+
PressureGrad::PressureGrad(const HorzMesh *Mesh, int NVertLevels, Config *Options);
131+
```
132+
133+
The create method will take the same arguments as the constructor plus a name.
134+
It calls the constructor to create a new pressure gradient instance, and put it in the static map of all pressure gradients.
135+
It will return a pointer to the newly created object.
136+
```c++
137+
PressureGrad *PressureGrad::create(const std::string &Name, const HorzMesh *Mesh, int NVertLevels, Config *Options);
138+
```
139+
140+
#### 4.2.2 Initialization
141+
142+
The init method will create the default pressure gradient and return an error code:
143+
```c++
144+
int PressureGrad::init();
145+
```
146+
147+
#### 4.2.3 Retrieval
148+
149+
There will be methods for getting the default and non-default pressure gradient instances:
150+
```c++
151+
PressureGrad *PressureGrad::getDefault();
152+
PressureGrad *PressureGrad::get(const std::string &Name);
153+
```
154+
155+
#### 4.2.4 Computation
156+
157+
The public `computePressureGrad` method will rely on private methods for each specific pressure gradient option (centered and high order).
158+
```c++
159+
void PressureGrad::computePressureGrad(const Array2DReal &Tend,
160+
const Array2DReal &Pressure,
161+
const Array2DReal &Geopotential,
162+
const Array2DReal &SpecVol) {
163+
OMEGA_SCOPE(LocCenteredPGrad, CenteredPGrad)
164+
OMEGA_SCOPE(LocHighOrderPGrad, HighOrderPGrad)
165+
if (PressureGradChoice == PressureGradType::Centered){
166+
parallelFor("pgrad-centered", {NCellsAll, NChunks},
167+
KOKKOS_LAMBDA(int ICell, int KChunk) {
168+
LocCenteredPGrad(Tend, Pressure, Geopotential, SpecVol);
169+
});
170+
}
171+
else if (PressureGradChoice == PressureGradType::HighOrder){
172+
parallelFor("pgrad-highorder", {NCellsAll, NChunks},
173+
KOKKOS_LAMBDA(int ICell, int KChunk) {
174+
LocHighOrderPGrad(Tend, Pressure, Geopotential, SpecVol);
175+
});
176+
}
177+
```
178+
179+
#### 4.2.5 Destruction and removal
180+
181+
No operations are needed in the destructor.
182+
The erase method will remove a named pressure gradient instance, whereas the clear method will remove all of
183+
them.
184+
Both will call the destructor in the process.
185+
```c++
186+
void PressureGrad::erase(const std::string &Name);
187+
void PressureGrad::clear();
188+
```
189+
190+
## Verification and Testing
191+
192+
### Test: Spatial convergence to exact solution
193+
For a given analytical $v$, $h$, and $b$, the spatial convergence of the pressure gradient can be assessed by computing errors on progressively finer meshes.
194+
195+
### Test: Baroclinic gyre
196+
The baroclinic gyre test case will test the pressure gradient term in the full non-Boussinesq equations.
197+

components/omega/doc/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ design/HorzMeshClass
106106
design/Logging
107107
design/MachEnv
108108
design/Metadata
109+
design/PGrad
109110
design/IO
110111
design/IOStreams
111112
design/Reductions

0 commit comments

Comments
 (0)