Skip to content

Commit 08d929a

Browse files
authored
Merge pull request #284 from andrewdnolan/merry_go_round
The merry-go-round test group is used for testing the vertical advection scheme only using tracers. This PR ports the `Default` test case from the `merry_go_round` test group from `compass`. This PR also adds convergence tests in space and both space and time.
2 parents 36eca06 + bb60c5b commit 08d929a

File tree

20 files changed

+1508
-2
lines changed

20 files changed

+1508
-2
lines changed

docs/developers_guide/ocean/api.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,35 @@
260260
viz.Viz.run
261261
```
262262

263+
### merry_go_round
264+
265+
```{eval-rst}
266+
.. currentmodule:: polaris.tasks.ocean.merry_go_round
267+
268+
.. autosummary::
269+
:toctree: generated/
270+
271+
add_merry_go_round_tasks
272+
273+
default.Default
274+
default.viz.Viz
275+
default.viz.Viz.setup
276+
default.viz.Viz.run
277+
278+
forward.Forward
279+
forward.Forward.compute_cell_count
280+
281+
init.Init
282+
init.Init.setup
283+
init.Init.run
284+
285+
analysis.Analysis
286+
287+
viz.Viz
288+
viz.Viz.setup
289+
viz.Viz.run
290+
```
291+
263292
### overflow
264293

265294
```{eval-rst}

docs/developers_guide/ocean/tasks/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ ice_shelf_2d
1616
inertial_gravity_wave
1717
internal_wave
1818
manufactured_solution
19+
merry_go_round
1920
nondivergent_2d
2021
overflow
2122
rotation_2d
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
(dev-ocean-merry-go-round)=
2+
3+
# merry-go-round
4+
5+
The merry-go-round task group is currently comprised of one `default` task for
6+
quick testing and two convergence tests testing the convergence in space
7+
and both space and time.
8+
9+
## framework
10+
11+
The shared config options for `merry_go_round` tests are described in
12+
{ref}`ocean-merry-go-round` in the User's Guide.
13+
14+
Additionally, the tests share a `forward.yaml` file with a few common model
15+
config options related to time management, time integration, and which
16+
tendencies terms are active, as well as defining `mesh`, `input`, `restart`,
17+
and `output` streams.
18+
19+
### init
20+
21+
The class {py:class}`polaris.tasks.ocean.merry_go_round.init.Init`
22+
defines a step for setting up the initial state for each test case.
23+
24+
First, a mesh appropriate for the resolution is generated using
25+
{py:func}`mpas_tools.planar_hex.make_planar_hex_mesh()`. Then, the mesh is
26+
culled to remove periodicity in the y direction. The uniform bottom depth and
27+
requested number of vertical layer (default of 50) are used to define a
28+
vertical coordinate. Next, the ocean state is generated following the
29+
initial condition description from {ref}`ocean-merry-go-round` in the User's
30+
Guide.
31+
32+
### forward
33+
34+
The class {py:class}`polaris.tasks.ocean.merry_go_round.forward.Forward`
35+
defines a step for running the ocean model from the initial condition produced
36+
in the `init` step. The time step is determined algorithmically based on
37+
config options (i.e. `dt_per_km`) and the type of refinement requested. The
38+
number of cells is approximated from config options in
39+
{py:meth}`polaris.tasks.ocean.merry_go_round.forward.Forward.compute_cell_count()`
40+
so that this can be used to constrain the number of MPI tasks that Polaris
41+
tasks have as their target and minimum (if the resources are not explicitly
42+
prescribed). For MPAS-Ocean, PIO namelist options are modified and a
43+
graph partition is generated as part of `runtime_setup()`. Next, the ocean
44+
model is run. The duration is set by `run_duration` in the config section
45+
corresponding to the task (`merry_go_round`). Finally, validation of
46+
`normalVelocity`, `tracer1`, `tracer2`, and `tracer3` in the `output.nc`
47+
file are performed against a baseline if one is provided when
48+
calling {ref}`dev-polaris-setup`.
49+
50+
(dev-ocean-merry-go-round)=
51+
52+
## default
53+
54+
The {py:class}`polaris.tasks.ocean.merry_go_round.default.Default`
55+
test runs the `init` step, the `forward` step, and a custom `viz` step.
56+
57+
### viz
58+
59+
The {py:class}`polaris.tasks.ocean.merry_go_round.default.viz.Viz` plots
60+
transects of the horizontal velocity, vertical velocity, simulated tracer
61+
concentration, and error in simulated tracer concentration at the end of the
62+
forward run. This more detailed plotting step is only available for the
63+
default test case.
64+
65+
(dev-ocean-merry-go-analysis)=
66+
67+
## convergence tasks
68+
69+
### analysis
70+
71+
The class {py:class}`polaris.tasks.ocean.merry_go_round.analysis.Analysis`
72+
descends from {py:class}`polaris.ocean.convergence.analysis.ConvergenceAnalysis`
73+
a step for computing the error from the final simulated field
74+
and the exact solution. It uses the config options to determine whether the
75+
convergence rate falls within acceptable bounds.
76+
77+
### viz
78+
79+
The class {py:class}`polaris.tasks.ocean.merry_go_round.viz.Viz`
80+
defines a step for visualization. It produces transects of the simulated,
81+
exact, and (simulated - exact) `tracer1` fields for each resolution.
44.9 KB
Loading
96 KB
Loading

docs/users_guide/ocean/tasks/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ ice_shelf_2d
1616
inertial_gravity_wave
1717
internal_wave
1818
manufactured_solution
19+
merry_go_round
1920
nondivergent_2d
2021
overflow
2122
rotation_2d
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
(ocean-merry-go-round)=
2+
3+
# merry-go-round
4+
5+
The `ocean/merry_go_round` test group induces a convective cell in a horizontal
6+
domain in order to verify tracer advection.
7+
8+
```{image} images/merry_go_round_section.png
9+
:align: center
10+
:width: 500 px
11+
```
12+
13+
## supported models
14+
15+
These tasks only support MPAS-Ocean.
16+
17+
(ocean-merry-go-round-default)=
18+
19+
## default
20+
21+
### description
22+
23+
For the initial conditions described below, tracer concentration contours match
24+
the streamlines of the convective cell, such that an accurate tracer advection
25+
scheme would result in no change in the tracer field in time.
26+
27+
The init step generates the mesh and initial condition for the requested
28+
resolution.
29+
30+
The forward step runs the model for the requested length of time. Tendencies
31+
for normal velocity and layer thickness are disabled, such that these fields
32+
remain fixed at their initial conditions throughout the simulation.
33+
34+
The visualization step produces a plot illustrating the horizontal velocity,
35+
vertical velocity, simulated `tracer1` concentration, the error in simulated
36+
tracer concentration at the end of the forward simulation.
37+
(See above for an example).
38+
39+
### mesh
40+
The mesh is planar and the resolution is specified by config option
41+
`merry_go_round_default:resolution`, which defaults to 5 m. The horizontal
42+
dimensions of the domain are set by config options `merry_go_round:lx` and
43+
`merry_go_round:ly`, defaulting to 500 m by 5 m. The domain is solid on the
44+
zonal boundaries and periodic on the meridional boundaries.
45+
46+
### vertical grid
47+
48+
The vertical coordinate is fixed throughout the simulation.
49+
50+
```cfg
51+
[vertical_grid]
52+
53+
# the type of vertical grid
54+
grid_type = uniform
55+
56+
# Number of vertical levels for base resolution
57+
vert_levels = 50
58+
59+
# Depth of the bottom of the ocean
60+
bottom_depth = 500.0
61+
62+
# The type of vertical coordinate (e.g. z-level, z-star)
63+
coord_type = z-level
64+
65+
# Whether to use "partial" or "full", or "None" to not alter the topography
66+
partial_cell_type = None
67+
68+
# The minimum fraction of a layer for partial cells
69+
min_pc_fraction = 0.1
70+
```
71+
72+
### initial conditions
73+
74+
Salinity is constant throughout the domain as specified by
75+
`merry_go_round:salinity_background`, which defaults to 35 PSU. The initial
76+
temperature is high on the right side (`merry_go_round:temperature_right`) of
77+
and low on the left side (`merry_go_round:temperature_left`) of the domain,
78+
with defaults of 30 degC and 5 degC respectively. This field initiates
79+
a convective cell in the zonal and vertical dimensions. Debug tracer, `tracer1`
80+
, is initialized with a high value in the center of domain and gradually
81+
transitions to a lower value at the edges of the domain.
82+
83+
### forcing
84+
N/A
85+
86+
### time step and run duration
87+
88+
The time step is determined by the config option `merry_go_round:dt_per_km`
89+
according to the mesh resolution (i.e. `convergence:base_resolution`).
90+
The run duration is determined by the config option
91+
`merry_go_round:run_duration` as measured in hours.
92+
93+
### config options
94+
95+
The following config options are available for this case:
96+
97+
```cfg
98+
[merry_go_round]
99+
100+
# the size of the domain in km in the x direction
101+
lx = 0.5
102+
103+
# the size of the domain in km in the y direction
104+
ly = 0.005
105+
106+
# temperature on the right of the domain
107+
temperature_right = 30.
108+
109+
# temperature on the left of the domain
110+
temperature_left = 5.
111+
112+
# background salinity
113+
salinity_background = 35.
114+
115+
# background tracer2 concentration
116+
tracer2_background = 10.
117+
118+
# background tracer3 concentration
119+
tracer3_background = 20.
120+
121+
# Time step per resolution (s/km), since dt is proportional to resolution
122+
dt_per_km = 72000.0
123+
124+
# Convergence threshold below which the test fails
125+
conv_thresh = 1.2
126+
127+
# Run duration in hours
128+
run_duration = 6.
129+
130+
[merry_go_round_default]
131+
# the mesh resolution (km) at which the default test case is run and
132+
# the resolution to which refinement_factors are applied if refinement is
133+
# 'space' or 'both' on a planar mesh
134+
resolution = 0.005
135+
```
136+
137+
### cores
138+
139+
The number of cores is determined according to the config options
140+
``max_cells_per_core`` and ``goal_cells_per_core``.
141+
142+
(ocean-merry-go-round-convergence)=
143+
144+
## convergence tasks
145+
146+
There are two versions of the convergence test case: `convergence_space` and
147+
`convergence_both` corresponding to space and both space and time convergence
148+
tests. All settings are the same as the
149+
{ref}`ocean-merry-go-round-default` case, but now the resolution and/or time step
150+
are refined to asses the order of convergence for tracer advection. Tests
151+
involving spatial convergence have a horizontal resolution of
152+
`convergence:base_resolution` times `convergence:refinement_factors_space`.
153+
Tests invoking both spatial and temporal convergence refine the spatial
154+
resolution as described above and use a time step set by
155+
`merry_go_round:dt_per_km` times the refined spatial resolution
156+
(see {ref}`dev-ocean-convergence` for more details on how to change resolutions
157+
or time steps tested).
158+
159+
The init and forward steps are analogous to what is described above for
160+
{ref}`ocean-merry-go-round-default`.
161+
162+
The analysis step computes the `convergence:error_type` of your choosing,
163+
between the simulated `tracer1` field and the exact solution at the end
164+
of the simulation. Because tracer concentration contours match the streamlines
165+
of the convective cell the exact solution is equivalent to the initial
166+
condition. It also computes the convergence rate with resolution and/or
167+
time step, producing a plot like:
168+
169+
```{image} images/merry_go_round_convergence.png
170+
:align: center
171+
:width: 500 px
172+
```
173+
The visualization step plot the numerical solution, exact solution, and their
174+
difference for each resolution and/or time step simulated.

polaris/ocean/convergence/analysis.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ class ConvergenceAnalysis(OceanIOStep):
5656
refinement : str
5757
Refinement type. One of 'space', 'time' or 'both' indicating both
5858
space and time
59+
60+
mesh_filename : str
61+
The name of the mesh file to use for calculating mesh metrics
62+
(i.e. cell area) needed for computing the error
5963
"""
6064

6165
def __init__(
@@ -65,6 +69,7 @@ def __init__(
6569
dependencies,
6670
convergence_vars,
6771
refinement='both',
72+
mesh_filename='base_mesh.nc',
6873
):
6974
"""
7075
Create the step
@@ -114,11 +119,17 @@ def __init__(
114119
refinement : str, optional
115120
Refinement type. One of 'space', 'time' or 'both' indicating both
116121
space and time
122+
123+
mesh_filename : str
124+
The name of the mesh file to use for calculating mesh metrics
125+
(i.e. cell area) needed for computing the error
117126
"""
118127
super().__init__(component=component, name='analysis', subdir=subdir)
128+
119129
self.dependencies_dict = dependencies
120130
self.convergence_vars = convergence_vars
121131
self.refinement = refinement
132+
self.mesh_filename = mesh_filename
122133

123134
for var in convergence_vars:
124135
self.add_output_file(f'convergence_{var["name"]}.png')
@@ -137,12 +148,12 @@ def setup(self):
137148
option = 'refinement_factors_space'
138149
refinement_factors = config.getlist('convergence', option, dtype=float)
139150
for refinement_factor in refinement_factors:
140-
base_mesh = dependencies['mesh'][refinement_factor]
151+
mesh = dependencies['mesh'][refinement_factor]
141152
init = dependencies['init'][refinement_factor]
142153
forward = dependencies['forward'][refinement_factor]
143154
self.add_input_file(
144155
filename=f'mesh_r{refinement_factor:02g}.nc',
145-
work_dir_target=f'{base_mesh.path}/base_mesh.nc',
156+
work_dir_target=f'{mesh.path}/{self.mesh_filename}',
146157
)
147158
self.add_input_file(
148159
filename=f'init_r{refinement_factor:02g}.nc',

polaris/suites/ocean/convergence.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ ocean/planar/inertial_gravity_wave/convergence_both
22
ocean/planar/manufactured_solution/convergence_both/default
33
ocean/planar/manufactured_solution/convergence_both/del2
44
ocean/planar/manufactured_solution/convergence_both/del4
5+
ocean/planar/merry_go_round/convergence_both
56
ocean/spherical/icos/correlated_tracers_2d
67
cached: icos_base_mesh_60km icos_base_mesh_120km icos_base_mesh_240km icos_base_mesh_480km
78
ocean/spherical/qu/correlated_tracers_2d

polaris/suites/ocean/pr.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ ocean/planar/inertial_gravity_wave/convergence_both
77
ocean/planar/internal_wave/standard/default
88
ocean/planar/internal_wave/vlr/default
99
# ocean/planar/manufactured_solution/convergence_both
10+
# ocean/planar/merry_go_round/default
1011
ocean/planar/overflow/default
1112
ocean/single_column/cvmix
1213
ocean/single_column/ekman

0 commit comments

Comments
 (0)