|
| 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 | +
|
0 commit comments