Skip to content

Commit 23830b8

Browse files
Merge pull request #222 from alicebarthel/ocn/add-eos
Add Equation of State (EOS) to omega
2 parents 9b535ce + dd173d0 commit 23830b8

File tree

18 files changed

+1247
-14
lines changed

18 files changed

+1247
-14
lines changed

.gitmodules

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,3 +88,9 @@
8888
[submodule "components/omega/external/yaml-cpp"]
8989
path = components/omega/external/yaml-cpp
9090
url = https://github.com/jbeder/yaml-cpp.git
91+
[submodule "components/omega/external/GSW-C"]
92+
path = components/omega/external/GSW-C
93+
url = [email protected]:E3SM-Project/GSW-C.git
94+
[submodule "components/omega/external/yaml-cpp"]
95+
path = components/omega/external/yaml-cpp
96+
url = https://github.com/jbeder/yaml-cpp.git

components/omega/OmegaBuild.cmake

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,9 +82,12 @@ macro(read_cime_config)
8282
set(NEWCASE_COMMAND "${NEWCASE_COMMAND} --project ${OMEGA_CIME_PROJECT}")
8383
endif()
8484

85-
if(NOT IS_DIRECTORY "${CASEROOT}")
85+
if(NOT EXISTS ${CASEROOT})
8686
run_bash_command("${NEWCASE_COMMAND}" NEWCASE_OUTPUT)
87+
else()
88+
message(WARNING "Reusing ${CASEROOT}")
8789
endif()
90+
8891
run_bash_command("cd ${CASEROOT} && ./case.setup" CASESETUP_OUTPUT)
8992
run_bash_command("source ${CASEROOT}/.env_mach_specific.sh && env" ENV_OUTPUT)
9093

components/omega/configs/Default.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@ Omega:
4242
Tracers:
4343
Base: [Temperature, Salinity]
4444
Debug: [Debug1, Debug2, Debug3]
45+
Eos:
46+
EosType: teos10
47+
Linear:
48+
DRhoDT: -0.2
49+
DRhoDS: 0.8
50+
RhoT0S0: 1000.0
4551
IOStreams:
4652
# InitialState should only be used when starting from scratch.
4753
# For restart runs, the frequency units should be changed from

components/omega/doc/design/EOS.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
(omega-design-eos)=
2-
# Equation of State
2+
3+
# Equation of State (EOS)
34

45
## 1 Overview
56
The equation of state relates density to the prognostic state variables temperature and salinity. In the case of a non-Boussinesq model, it is also dependent on prognostic pressure. The prognostic temperature, $\theta$, is either potential temperature or Conservative Temperature, depending on the chosen equation of state, and $S$ is the absolute salinity (linear eos could use practical salinity). Given that the Omega governing equations are non-Boussinesq, the equation of state class will provide specific volume from the state variables. It will provide methods for computing the specific volume, and its first derivatives.

components/omega/doc/design/VerticalMixingCoeff.md

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
## 1 Overview
44

5-
Representation of unresolved vertical fluxes of momentum, heat, salt, and biogeochemical tracers in ocean models is essential to simulations fidelity. Models of turbulent fluxes spans a wide range of complexity, but the models generally fall into a few categories: simply polynomial relationships, equilibrium turbulence models, and prognostic turbulence models.
5+
Representation of unresolved vertical fluxes of momentum, heat, salt, and biogeochemical tracers in ocean models is essential to simulations fidelity. Models of turbulent fluxes spans a wide range of complexity, but the models generally fall into a few categories: simply polynomial relationships, equilibrium turbulence models, and prognostic turbulence models.
66

77
## 2 Requirements
88

@@ -18,7 +18,7 @@ $$
1818
\overline{w' \phi'}\approx \kappa(\overline{\rho},\overline{u},\overline{v}) \left(\frac{\partial \overline{\phi}}{\partial z} + \gamma(\overline{\rho},\overline{u},\overline{v}) \right)\,.
1919
$$
2020

21-
Here, $\phi$ is a generic tracer, $\overline{w'\phi'}$ is the vertical turbulent flux of that tracer, $\kappa$ is the vertical diffusivity, and $\gamma$ is the gradient free portion of the flux (often referred to as 'non-local'). The vertical diffusivity $\kappa$ can be as simple as a constant value, to complex functions of quantities like shear and stratification. A similar equation can be written for turbulent momentum fluxes and vertical viscosity ($\nu$).
21+
Here, $\phi$ is a generic tracer, $\overline{w'\phi'}$ is the vertical turbulent flux of that tracer, $\kappa$ is the vertical diffusivity, and $\gamma$ is the gradient free portion of the flux (often referred to as 'non-local'). The vertical diffusivity $\kappa$ can be as simple as a constant value, to complex functions of quantities like shear and stratification. A similar equation can be written for turbulent momentum fluxes and vertical viscosity ($\nu$).
2222

2323
Invocation of the gradient diffusion hypothesis is a simplifying assumption for turbulence closures that casts turbulence as a purely diffusive process and allows the mixing problem to be cast implicitly in a tridagonal solve. For more physical mixing closures, other methods can be explored, e.g., direct and iterative implicit solvers or subcycling.
2424

@@ -100,7 +100,7 @@ So that homogenization only occurs for unstable stratification (assuming $N^2_{c
100100

101101
## 4 Design
102102

103-
Vertical chunking, as is, does not work well for vertical derivatives, so a first design of the vertical mixing coefficients computation does not do vertical chunking and just computes with the full-depth column.
103+
Vertical chunking, as is, does not work well for vertical derivatives, so a first design of the vertical mixing coefficients computation does not do vertical chunking and just computes with the full-depth column.
104104

105105
Additionally, to start, only the down gradient contribution to vertical mixing will be added, with contributions to the vertical viscosity and diffusivity coming from the shear (Richardson number mixing), convective, and background mixing models detailed in the prior section. However, in future developments, the K Profile Parameterization [(KPP; Large et al., 1994)](https://agupubs.onlinelibrary.wiley.com/doi/abs/10.1029/94rg01872) and other non-local and/or higher-order mixing models will be added. Some of these parameterizations require vertical derivatives, full-depth integrals, and/or formulate $\kappa$ and $\gamma$ in Eq. (1) Section 2.1 as functions of surface forcing, which require either full-depth column or surface forcing information at depth, thus we design the mixing coefficients routine with this in mind. A solution that allows chunking with vertical operations such as derivatives and integrals and/or surface forcing values would be advantageous, but is outside of the scope of this design document.
106106

@@ -139,11 +139,11 @@ It is assumed that viscosity and diffusivity will be stored at cell centers. Add
139139
parallelFor(
140140
{NCellsAll, NVertLevels}, KOKKOS_LAMBDA(int ICell, int K) {
141141

142-
// Add background contribution to viscosity and diffusivity
142+
// Add background contribution to viscosity and diffusivity
143143
VertViscosity(ICell, K) = BackgroundViscosity;
144144
VertDiffusivity(ICell, K) = BackgroundDiffusivity;
145145

146-
// If shear mixing true, add shear contribution to viscosity and diffusivity
146+
// If shear mixing true, add shear contribution to viscosity and diffusivity
147147
if (EnableShearMix) {
148148
const Real InvAreaCell = 1._Real / AreaCell(ICell);
149149
// Calculate the square of the shear
@@ -163,7 +163,7 @@ parallelFor(
163163
VertDiffusivity(ICell, K) = VertDiffusivity(ICell, K) + VertViscosity(ICell, K) / (1 + ShearAlpha * RichardsonNum(ICell, K));
164164
}
165165

166-
// If conv mixing true, add conv contribution to viscosity and diffusivity
166+
// If conv mixing true, add conv contribution to viscosity and diffusivity
167167
if (EnableConvectiveMix) {
168168
if (BruntVaisalaFreq(ICell, K) < ConvectiveTriggerBVF) {
169169
VertViscosity(ICell, K) = VertViscosity(ICell, K) + ConvectiveDiffusivity;
@@ -181,4 +181,3 @@ A no-flux condition should be applied to both the vertical mixing of momentum an
181181
Unit tests can be initialized with linear-with-depth initial conditions (velocity and density) and use a linear equation of state. Expected values of the Richardson number, vertical viscosity, and vertical diffusion coefficients can be computed and compared to. Tests for both the shear, convective, and combined mixing contributions should be made to test requirement (2.1).
182182
183183
This assumes that the displaced density has already been tested. Vertical fluxes of momentum and tracers will be tested separately with the [tridiagonal solver](./TridiagonalSolver.md).
184-
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
(omega-dev-eos) =
2+
3+
# Equation of State (EOS)
4+
5+
Omega includes an `Eos` class that provides functions that compute `SpecVol` and `SpecVolDisplaced`.
6+
Current EOS options are a linear EOS or an EOS computed using the TEOS-10 75 term expansion from
7+
[Roquet et al. 2015](https://www.sciencedirect.com/science/article/pii/S1463500315000566). If
8+
`SpecVolDisplaced` is calculated with the linear EOS option, it will be equal to `SpecVol` as there
9+
is no pressure/depth dependence for the linear EOS. `SpecVolDisplaced` computes specific volume
10+
adiabatically displaced to `K + KDisp`.
11+
12+
## Eos type
13+
14+
An enumeration listing all implemented schemes is provided. It needs to be extended every time an
15+
EOS is added. It is used to identify which EOS method is to be used at run time.
16+
17+
```c++
18+
enum class EosType { Linear, Teos10Poly75t };
19+
```
20+
21+
## Initialization
22+
23+
An instance of the `Eos` class requires a [`HorzMesh`](#omega-dev-horz-mesh), so the mesh class
24+
and all of its dependencies need to be initialized before the `Eos` class can be. The static method:
25+
26+
```c++
27+
OMEGA::Eos::init();
28+
```
29+
30+
initializes the default `Eos`. A pointer to it can be retrieved at any time using:
31+
32+
```c++
33+
OMEGA::Eos* DefEos = OMEGA::Eos::getInstance();
34+
```
35+
36+
## Computation of Eos
37+
38+
To compute `SpecVol` for a particular set of temperature, salinity, and pressure arrays, do
39+
40+
```c++
41+
Eos.computeSpecVol(ConsrvTemp, AbsSalinity, Pressure);
42+
```
43+
44+
`SpecVolDisplaced` is calculated using local temperature and salinity values, but a pressure
45+
value at `K + KDisp`. To compute `SpecVolDisplaced` for a particular set of temperature, salinity,
46+
and pressure arrays and displaced vertical index level, do
47+
48+
```c++
49+
Eos.computeSpecVolDisp(ConsrvTemp, AbsSalinity, Pressure, KDisp);
50+
```
51+
52+
where `KDisp` is the number of `k` levels you want to displace each specific volume level to.
53+
For example, to displace each level to one below, set `KDisp = 1`.
54+
55+
## Removal of Eos
56+
57+
To clear the Eos instance do:
58+
59+
```c++
60+
OMEGA::Eos::destroyInstance();

components/omega/doc/index.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ userGuide/Logging
3030
userGuide/Driver
3131
userGuide/Decomp
3232
userGuide/Dimension
33+
userGuide/EOS
3334
userGuide/Error
3435
userGuide/Field
3536
userGuide/IO
@@ -62,6 +63,7 @@ devGuide/DataTypes
6263
devGuide/MachEnv
6364
devGuide/Config
6465
devGuide/Driver
66+
devGuide/EOS
6567
devGuide/Broadcast
6668
devGuide/CMakeBuild
6769
devGuide/Logging
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
(omega-user-eos)=
2+
3+
# Equation of State (EOS)
4+
5+
The equation of state (EOS) for the ocean describes the relationship between specific volume of seawater (in $\textrm{m}^3/\textrm{kg}$; the reciprocal of density) and temperature (in $^{\circ}\textrm{C}$), salinity (in $\textrm{g/kg}$), and pressure (in $\textrm{dbar}$). Through the hydrostatic balance (which relates density/specific volume gradients to pressure gradients), the equation of state provides a connection between active tracers (temperature and salinity) and the fluid dynamics.
6+
7+
Two choices of EOS are provided by Omega: a linear EOS and a TEOS-10 EOS. The linear EOS simplifies the relationship by excluding the influence of pressure and using constant expansion/contraction coefficients, making the specific volume a simple linear function of temperature and salinity. However, this option is only recommended for simpler idealized test cases as its accuracy is not sufficient for real ocean simulations. The TEOS-10 EOS is a 75-term polynomial expression from [Roquet et al. 2015](https://www.sciencedirect.com/science/article/pii/S1463500315000566) that approximates the [Thermodynamic Equation of Seawater 2010](https://www.teos-10.org/pubs/TEOS-10_Manual.pdf) , but in a less complex and more computationally efficient manner, and is the preferred EOS for real ocean simulations in Omega.
8+
9+
The user-configurable options are: `EosType` (choose either `Linear` or `Teos-10`), as well as the parameters needed for the linear EOS.
10+
11+
```yaml
12+
Eos:
13+
EosType : teos10
14+
Linear:
15+
DRhoDT: -0.2
16+
DRhoDS: 0.8
17+
RhoT0S0: 1000.0
18+
```
19+
20+
where `DRhoDT` is the thermal expansion coefficient ($\textrm{kg}/(\textrm{m}^3 \cdot ^{\circ}\textrm{C})$), `DRhoDS` is the saline contraction coefficient ($\textrm{kg}/\textrm{m}^3$), and `RhoT0S0` is the reference density at (T,S)=(0,0) (in $\textrm{kg}/\textrm{m}^3$).
21+
22+
In addition to `SpecVol`, the displaced specific volume `SpecVolDisplaced` is also calculated by the EOS. This calculates the density of a parcel of fluid that is adiabatically displaced by a relative `k` levels, capturing the effects of pressure/depth changes. This is primarily used to calculate quantities for determining the water column stability (i.e. the stratification) and the vertical mixing coefficients (viscosity and diffusivity). Note: when using the linear EOS, `SpecVolDisplaced` will be the same as `SpecVol` since the specific volume calculation is independent of pressure/depth.

components/omega/external/CMakeLists.txt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,26 @@
11
# Add external packages
22

3+
include(ExternalProject)
4+
5+
# Add GSW-C project
6+
ExternalProject_Add(
7+
gswteos
8+
BINARY_DIR ${OMEGA_BUILD_DIR}/external/GSW-C
9+
DOWNLOAD_COMMAND ${CMAKE_COMMAND} -E copy_directory
10+
${OMEGA_SOURCE_DIR}/external/GSW-C
11+
${OMEGA_BUILD_DIR}/external/GSW-C
12+
CONFIGURE_COMMAND ""
13+
BUILD_COMMAND make CC=${CMAKE_C_COMPILER} all
14+
INSTALL_COMMAND ""
15+
BUILD_BYPRODUCTS ${OMEGA_BUILD_DIR}/external/GSW-C/libgswteos-10.so
16+
${OMEGA_BUILD_DIR}/external/GSW-C/gsw_check
17+
)
18+
19+
add_library(gswteos-10 SHARED IMPORTED)
20+
set_target_properties(gswteos-10 PROPERTIES
21+
IMPORTED_LOCATION ${OMEGA_BUILD_DIR}/external/GSW-C/libgswteos-10.so
22+
)
23+
324
# Add the spdlog library
425
if (NOT TARGET spdlog::spdlog)
526
add_subdirectory(

components/omega/external/GSW-C

Submodule GSW-C added at 007026a

0 commit comments

Comments
 (0)