Skip to content

Commit

Permalink
Merge pull request #153 from cbegeman/ocn-port-internal-wave-test
Browse files Browse the repository at this point in the history
Port ocean internal wave test

Here we port the internal gravity wave test case from Compass. This is largely a direct port. The only substantive new code is the transect visualization.
  • Loading branch information
cbegeman authored Jan 8, 2024
2 parents 51b0efe + 47a39b8 commit 968f24b
Show file tree
Hide file tree
Showing 18 changed files with 1,077 additions and 0 deletions.
28 changes: 28 additions & 0 deletions docs/developers_guide/ocean/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,34 @@
viz.Viz.run
```

### internal_wave

```{eval-rst}
.. currentmodule:: polaris.ocean.tasks.internal_wave
.. autosummary::
:toctree: generated/
add_internal_wave_tasks
forward.Forward
forward.Forward.compute_cell_count
forward.Forward.dynamic_model_config
init.Init
init.Init.run
viz.Viz
viz.Viz.run
default.Default
rpe.Rpe
rpe.Rpe.configure
rpe.analysis.Analysis
rpe.analysis.Analysis.run
```


### manufactured_solution

Expand Down
1 change: 1 addition & 0 deletions docs/developers_guide/ocean/tasks/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ cosine_bell
geostrophic
divergent_2d
inertial_gravity_wave
internal_wave
manufactured_solution
nondivergent_2d
rotation_2d
Expand Down
88 changes: 88 additions & 0 deletions docs/developers_guide/ocean/tasks/internal_wave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
(dev-ocean-internal-wave)=

# internal_wave

The internal wave tests in `polaris.ocean.tasks.internal_wave` are
variants of the Internal Wave test case (see
{ref}`ocean-internal-wave`) at 5km horizontal resolution. Here,
we describe the 4 test cases and their shared framework.

(dev-ocean-internal-wave-framework)=

## framework

The shared config options for `internal_wave` tests are described in
{ref}`ocean-internal-wave` in the User's Guide.

Additionally, the tests share a `forward.yaml` file with a few common model
config options related to run duration and default horizontal and vertical
momentum and tracer diffusion, as well as defining `mesh`, `input`, `restart`,
and `output` streams.

### init

The class {py:class}`polaris.ocean.tasks.internal_wave.init.Init`
defines a step for setting up the initial state for each test case.

First, a mesh appropriate for the resolution is generated using
{py:func}`mpas_tools.planar_hex.make_planar_hex_mesh()`. Then, the mesh is
culled to remove periodicity in the y direction. A vertical grid is generated,
with 20 layers of 50-m thickness each by default. Next, the initial
temperature field is computed along with uniform salinity and zero initial
velocity. Finally, if a baseline is available, the step ensures that of
`temperature`, `salinity` and `layerThickness` in the `initial_state.nc` file
identical to those same fields from the baseline run.

The same `init` step is shared by all tasks at a given resolution.

### forward

The class {py:class}`polaris.ocean.tasks.internal_wave.forward.Forward`
defines a step for running MPAS-Ocean from the initial condition produced in
the `init` step. If `nu` is provided as an argument to the
constructor, the associate namelist option (`config_mom_del2`) will be given
this value. Namelist and streams files are updated in
{py:meth}`polaris.ocean.tasks.internal_wave.forward.Forward.dynamic_model_config()`
with time steps determined algorithmically based on config options. The
number of cells is approximated from config options in
{py:meth}`polaris.ocean.tasks.internal_wave.forward.Forward.compute_cell_count()`
so that this can be used to constrain the number of MPI tasks that Polaris
tasks have as their target and minimum (if the resources are not explicitly
prescribed). For MPAS-Ocean, PIO namelist options are modified and a
graph partition is generated as part of `runtime_setup()`. Next, the ocean
model is run. Finally, validation of `temperature`, `salinity`,
`layerThickness` and `normalVelocity` in the `output.nc` file are performed
against a baseline if one is provided when calling {ref}`dev-polaris-setup`.

### validate

The class {py:class}`polaris.ocean.tasks.internal_wave.validate.Validate`
defines a step for validating outputs in two step directories against one
another. This step ensures that `temperature`, `salinity`, `layerThickness`
and `normalVelocity` are identical in `output.nc` files in the two steps.

(dev-ocean-internal-wave-default)=

## default

The {py:class}`polaris.ocean.tasks.internal_wave.default.Default`
test performs a 3-time-step run on 4 cores. Two versions of this test exist,
one with the flux-form vertical advection scheme (``standard``), and one with
vertical Lagrangian-remapping (``vlr``).

(dev-ocean-internal-wave-rpe-test)=

## rpe

The {py:class}`polaris.ocean.tasks.internal_wave.rpe.Rpe`
performs a longer (20 day) integration of the model forward in time at 4
different values of the viscosity. Two versions of this test exist,
one with the flux-form vertical advection scheme (``standard``), and one with
vertical Lagrangian-remapping (``vlr``).

The `analysis` step defined by
{py:class}`polaris.ocean.tasks.internal_wave.rpe.analysis.Analysis`
makes plots of the final results with each value of the viscosity.

This test is resource intensive enough that it is not used in regression
testing.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions docs/users_guide/ocean/tasks/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ cosine_bell
geostrophic
divergent_2d
inertial_gravity_wave
internal_wave
manufactured_solution
nondivergent_2d
rotation_2d
Expand Down
179 changes: 179 additions & 0 deletions docs/users_guide/ocean/tasks/internal_wave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
(ocean-internal-wave)=

# internal wave

The ``ocean/internal_wave`` test group induces internal wave propagation and is documented in
`Ilicak et al. (2012) <https://doi.org/10.1016/j.ocemod.2011.10.003>`_.

(ocean-internal-wave-default)=

## default task

### description

The test case is characterized by stable stratification with a horizontal
perturbation to the stratification that induces internal waves.

```{image} images/internal_wave_initial_temperature.png
:align: center
:width: 500 px
```

Two variants are given for different vertical advection schemes, ``standard``
for flux-form advection and ``vlr`` for vertical Lagrangian-remapping.

### mesh

The domain is planar and periodic on the zonal boundaries and solid on the
meridional boundaries. Only 5km resolution is tested by default, but the
resolution may be changed with the ``resolution`` config option. The domain is
20km by 250km, as given by the config options ``lx`` and ``ly``.

### vertical grid

There are no restrictions on the vertical grid inherent to the test case except
that there should be sufficient vertical levels to capture the stratification
structure.

```cfg
# Options related to the vertical grid
[vertical_grid]
# the type of vertical grid
grid_type = uniform
# Number of vertical levels
vert_levels = 20
# Depth of the bottom of the ocean
bottom_depth = 500.0
# The type of vertical coordinate (e.g. z-level, z-star)
coord_type = z-level
# Whether to use "partial" or "full", or "None" to not alter the topography
partial_cell_type = None
# The minimum fraction of a layer for partial cells
min_pc_fraction = 0.1
```

### initial conditions

Salinity is constant throughout the domain at the value given by the config
option ``background_salinity`` (35 PSU by default). The initial temperature
has a linear background stratification from 20.1 degrees C (config option
``surface_temperature``) to 10.1 degrees C (config option
``bottom_temperature``). There is a sinusoidal perturbation in the center of
the domain with amplitude given by the config option
``temperature_difference``, 2 degrees C by default. The width of the
perturbation is given by 2 times the config option ``amplitude_width_dist`` or
2 times the ``amplitude_width_frac`` times ``ly``.

### forcing

N/A

### time step and run duration

The time step for forward integration is 5 minutes. The run duration is 3 time steps.

### config options

The following config section is specific to this test case:

```cfg
# config options for internal wave test cases
[internal_wave]
# the width of the domain (km)
lx = 20.0
# the length of the domain (km)
ly = 250.0
# the size of grid cells (km)
resolution = 5.0
# Logical flag that determines if locations of features are defined by distance
# or fractions. False means fractions.
use_distances = False
# Temperature of the surface in the northern half of the domain.
surface_temperature = 20.1
# Temperature of the bottom in the northern half of the domain.
bottom_temperature = 10.1
# Difference in the temperature field between top and bottom
temperature_difference = 2.0
# Fraction of domain in Y direction the temperature gradient should be linear
# over.
amplitude_width_frac = 0.33
# Width of the temperature gradient around the center sin wave. Default value
# is relative to a 500km domain in Y.
amplitude_width_dist = 50e3
# Salinity of the water in the entire domain.
salinity = 35.0
# Coriolis parameter for the entire domain
coriolis_parameter = 0.0
```

### cores

The number of cores is determined by `goal_cells_per_core` and
`max_cells_per_core` in the `ocean` section of the config file.

## RPE task

### description

The Reference Potential Energy (RPE) task consists of several forward steps at
different values of the del2 horizontal viscosity. Two variants are given for
different vertical advection schemes, ``standard`` for flux-form advection and
``vlr`` for vertical Lagrangian-remapping. Analysis is run to compare the RPE
evolution through time for each of the forward runs with different viscosities.

### mesh

See default task.

### vertical grid

See default task.

### initial conditions

See default task.

### forcing

N/A

### time step and run duration

The time step for forward integration is 5 minutes. The run duration is 20 days.

### config options

In addition to the config options in section ``internal_wave``, the following
config options are also used:

```cfg
# config options for the internal wave RPE tasks
[internal_wave_rpe]
# Viscosity values to test for rpe test case
viscosities = 0.01, 1, 15, 150
# plot time (days)
plot_time = 20.0
# min and max temperature range
min_temp = 10.0
max_temp = 20.0
```
2 changes: 2 additions & 0 deletions polaris/ocean/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from polaris.ocean.tasks.inertial_gravity_wave import (
add_inertial_gravity_wave_tasks,
)
from polaris.ocean.tasks.internal_wave import add_internal_wave_tasks
from polaris.ocean.tasks.isomip_plus import add_isomip_plus_tasks
from polaris.ocean.tasks.manufactured_solution import (
add_manufactured_solution_tasks,
Expand All @@ -27,6 +28,7 @@ def __init__(self):
# planar: please keep these in alphabetical order
add_baroclinic_channel_tasks(component=self)
add_inertial_gravity_wave_tasks(component=self)
add_internal_wave_tasks(component=self)
add_isomip_plus_tasks(component=self, mesh_type='planar')
add_manufactured_solution_tasks(component=self)

Expand Down
2 changes: 2 additions & 0 deletions polaris/ocean/suites/pr.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ ocean/planar/baroclinic_channel/10km/threads
ocean/planar/baroclinic_channel/10km/decomp
ocean/planar/baroclinic_channel/10km/restart
ocean/planar/inertial_gravity_wave
ocean/planar/internal_wave/standard/default
ocean/planar/internal_wave/vlr/default
# ocean/planar/manufactured_solution
ocean/single_column/cvmix
ocean/single_column/ideal_age
30 changes: 30 additions & 0 deletions polaris/ocean/tasks/internal_wave/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
from polaris.config import PolarisConfigParser
from polaris.ocean.tasks.internal_wave.default import Default
from polaris.ocean.tasks.internal_wave.init import Init
from polaris.ocean.tasks.internal_wave.rpe import Rpe


def add_internal_wave_tasks(component):
"""
Add tasks for different internal wave tests to the ocean component
component : polaris.ocean.Ocean
the ocean component that the tasks will be added to
"""
config_filename = 'internal_wave.cfg'
base_dir = 'planar/internal_wave'
config = PolarisConfigParser(filepath=f'{base_dir}/{config_filename}')
config.add_from_package('polaris.ocean.tasks.internal_wave',
config_filename)

init = Init(component=component, indir=base_dir)
init.set_shared_config(config, link=config_filename)

for vadv_method in ['standard', 'vlr']:
default = Default(component=component, indir=base_dir, init=init,
vadv_method=vadv_method)
default.set_shared_config(config, link=config_filename)
component.add_task(default)

component.add_task(Rpe(component=component, indir=base_dir, init=init,
vadv_method=vadv_method, config=config))
Loading

0 comments on commit 968f24b

Please sign in to comment.