Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
9de0317
Organize init steps by forcing, sharing as applicable
cbegeman Nov 20, 2025
9e8d99e
Reorg cfg options for shared init step
cbegeman Dec 15, 2025
b49b9fb
Add option to turn vadv off for single column tests
cbegeman Nov 20, 2025
2d4f519
Namelist changes in accordance with omega pr#310
cbegeman Dec 15, 2025
681105b
Include restoring parameters in cfg and turn restoring on for individ…
cbegeman Dec 15, 2025
6d3b409
Update single_column docs
cbegeman Dec 17, 2025
27afbb4
Add no_vadv as a forward step
cbegeman Dec 17, 2025
24342f2
Add omega support
cbegeman Dec 17, 2025
0a28009
Add restart streams to forward.yaml's omega section
cbegeman Jan 4, 2026
d5f4566
Add a bunch of tendency configs to cvmix forward.yaml's omega section
cbegeman Jan 4, 2026
abcdf4e
Remove later: check out hyun's vmix tendency branch
cbegeman Jan 4, 2026
f08de5f
Add mapping for vmix tendency config
cbegeman Jan 8, 2026
23325ce
WIP add stable and unstable versions of cvmix
cbegeman Jan 8, 2026
fd4e014
Add name argument to cvmix and fixup comparison filepath
cbegeman Jan 8, 2026
d81281d
Add utility for daysSinceStartOfSim
cbegeman Jan 9, 2026
fb03b48
WIP Support omega in single column viz step
cbegeman Jan 9, 2026
9f17f49
Unstable stratification config
cbegeman Jan 9, 2026
494571b
Turn del4 off
cbegeman Jan 10, 2026
c26f7a4
Run with background diff, visc only
cbegeman Jan 10, 2026
a906b35
Reorganize and rename cvmix tests
cbegeman Jan 11, 2026
4a7083c
Fixup no vertical advection config options
cbegeman Jan 12, 2026
3fef286
WIP fixup yaml
cbegeman Jan 11, 2026
9e132de
Default duration of 1 day
cbegeman Jan 12, 2026
5212ab5
WIP try different unstable stratification profiles
cbegeman Jan 12, 2026
420043e
Use PP scheme for shear mixing
cbegeman Jan 12, 2026
5ae9582
Output zMid instead of computing it from layerThickness
cbegeman Jan 13, 2026
de0ce29
Provide ekman forward step path to analysis step
cbegeman Jan 13, 2026
686e68d
Provide consistent names for stream files
cbegeman Jan 13, 2026
a603d69
Use viz argument to designate all output files
cbegeman Jan 14, 2026
e086d25
WIP troubleshoot vmix config options
cbegeman Jan 14, 2026
5bf05ee
WIP troubleshoot vmix stable config options
cbegeman Jan 14, 2026
1782615
Use mid-lat settings for stable stratification
cbegeman Jan 16, 2026
953fc62
WIP change unstable stratification settings
cbegeman Jan 18, 2026
a72f422
Make comparison curves more differentiable
cbegeman Jan 18, 2026
95591b7
Update namelist options
cbegeman Jan 21, 2026
e0a99e3
Use no_vadv with constant diffusivity tests
cbegeman Jan 21, 2026
1ad256c
Make step with vadv optional
cbegeman Jan 21, 2026
9d04334
Always run viz step
cbegeman Jan 21, 2026
37ced8a
use zmid utility
cbegeman Jan 26, 2026
64a138a
Support fetching time from xtime variable
cbegeman Jan 30, 2026
4922ae3
Clean-up and generalize viz step
cbegeman Jan 30, 2026
9585bed
Add analysis step for wind-driven mixing
cbegeman Jan 30, 2026
7d587a2
fixup viz
cbegeman Jan 31, 2026
f7eebbb
fixup analysis
cbegeman Jan 31, 2026
417d5e6
Do not use Ri smoothing
cbegeman Jan 31, 2026
f375266
Match parameter values from Van Roekel et al 2018 for vmix_stable
cbegeman Jan 31, 2026
e853f41
fixup analysis to revert to old comparisons
cbegeman Jan 31, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 37 additions & 30 deletions docs/users_guide/ocean/tasks/single_column.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ the vertical dynamics of the ocean model only. The test cases are:

## suppported models

These tasks support only MPAS-Ocean.
These tasks support MPAS-Ocean and Omega.

## mesh

Expand Down Expand Up @@ -58,30 +58,8 @@ min_pc_fraction = 0.1

## initial conditions

The temperature and salinity profiles are defined using the following equations:

$$
\Phi(z) = \begin{cases}
\Phi_0 &\text{ if } z = z[0]\\
\Phi_0 + {d\Phi/dz}_{ML} z &
\text{ if } z > z_{MLD}\\
(\Phi_0 + {\Delta\Phi}_{ML}) + {d\Phi/dz}_{int} (z - z_{MLD}) &
\text{ if } z \le z_{MLD}
\end{cases}
$$

where $\Phi_0 = $`surface_X`, ${d\Phi/dz}_{ML} = $`X_gradient_mixed_layer`,
$z_{MLD} = -$`mixed_layer_depth_X`, ${\Delta\Phi}_{ML} = $
`X_difference_across_mixed_layer`, and ${d\Phi/dz}_{int} = $
`X_gradient_interior`. `X` in the config options above is either `temperature`
or `salinity`.

The initial velocity is vertically uniform and given by
`single_column:zonal_velocity` and `single_column:meridional_velocity`, which
are 0 by default (at rest).

The Coriolis parameter is spatially constant and set equal to
`coriolis_parameter`.
The initial conditions are either stably stratified or uniform. See each task
below.

### forcing

Expand Down Expand Up @@ -245,8 +223,35 @@ See {ref}`ocean-single-column`.

See {ref}`ocean-single-column`.

(ocean-single-column-stable)=

### initial conditions

The temperature and salinity profiles are defined using the following equations:

$$
\Phi(z) = \begin{cases}
\Phi_0 &\text{ if } z = z[0]\\
\Phi_0 + {d\Phi/dz}_{ML} z &
\text{ if } z > z_{MLD}\\
(\Phi_0 + {\Delta\Phi}_{ML}) + {d\Phi/dz}_{int} (z - z_{MLD}) &
\text{ if } z \le z_{MLD}
\end{cases}
$$

where $\Phi_0 = $`surface_X`, ${d\Phi/dz}_{ML} = $`X_gradient_mixed_layer`,
$z_{MLD} = -$`mixed_layer_depth_X`, ${\Delta\Phi}_{ML} = $
`X_difference_across_mixed_layer`, and ${d\Phi/dz}_{int} = $
`X_gradient_interior`. `X` in the config options above is either `temperature`
or `salinity`.

The initial velocity is vertically uniform and given by
`single_column:zonal_velocity` and `single_column:meridional_velocity`, which
are 0 by default (at rest).

The Coriolis parameter is spatially constant and set equal to
`coriolis_parameter`.

These config options overwrite those in {ref}`ocean-single-column`:

```cfg
Expand All @@ -263,7 +268,7 @@ mixed_layer_depth_temperature = 25.0
salinity_difference_across_mixed_layer = 1.0
```

The rest of the config options are given in {ref}`ocean-single-column`.
(ocean-single-column-wind-evap)=

### forcing

Expand Down Expand Up @@ -301,8 +306,7 @@ days.

### config options

See {ref}`ocean-single-column`. Currently, config options are only given in the
shared framework.
See {ref}`ocean-single-column-wind-evap` and {ref}`ocean-single-column-stable`.

### cores

Expand Down Expand Up @@ -345,7 +349,8 @@ The rest of the vertical grid features follow {ref}`ocean-single-column`.
### initial conditions

The temperature and salinity are constant and the flow is at rest.
See {ref}`ocean-single-column`.

(ocean-single-column-wind)=

### forcing

Expand Down Expand Up @@ -378,7 +383,8 @@ viscosity:
vertical_viscosity = 1.e-3
```

All other config options derive from {ref}`ocean-single-column`.
All other config options derive from {ref}`ocean-single-column` and
{ref}`ocean-single-column-wind`.

### cores

Expand Down Expand Up @@ -412,6 +418,7 @@ See {ref}`ocean-single-column`.
### initial conditions

`idealAgeTracers` is initialized as zero seconds throughout the water column.
See {ref}`ocean-single-column-stable`.

### forcing

Expand Down
29 changes: 29 additions & 0 deletions polaris/ocean/model/mpaso_to_omega.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ variables:
cellsOnVertex: CellsOnVertex
edgesOnVertex: EdgesOnVertex

# vertical
zMid: ZMid

# tracers
temperature: Temperature
salinity: Salinity
Expand Down Expand Up @@ -91,6 +94,11 @@ config:
options:
config_disable_vel_explicit_bottom_drag: BottomDragTendencyEnable

- section:
debug: Tendencies
options:
config_disable_vel_vmix: VelVertMixTendencyEnable

- section:
bottom_drag: Tendencies
options:
Expand All @@ -114,3 +122,24 @@ config:
config_eos_linear_alpha: DRhoDT
config_eos_linear_beta: DRhoDS
config_eos_linear_densityref: RhoT0S0

- section:
cvmix: [VertMix, Background]
options:
config_cvmix_background_diffusion: Diffusivity
config_cvmix_background_viscosity: Viscosity

- section:
cvmix: [VertMix, Convective]
options:
config_use_cvmix_convection: Enable
config_cvmix_convective_diffusion: Diffusivity
config_cvmix_convective_triggerBVF: TriggerBVF

- section:
cvmix: [VertMix, Shear]
options:
config_use_cvmix_shear: Enable
config_cvmix_shear_PP_nu_zero: NuZero
config_cvmix_shear_PP_alpha: Alpha
config_cvmix_shear_PP_exp: Exponent
34 changes: 34 additions & 0 deletions polaris/ocean/time.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
from datetime import datetime

import numpy as np
import pandas as pd


def get_days_since_start(ds):
"""
Ocean model output may or may not include 'daysSinceStartOfSim'. This
routine uses 'daysSinceStartOfSim' if available, otherwise it uses 'Time'
"""
if 'daysSinceStartOfSim' in ds.keys():
t_arr = ds.daysSinceStartOfSim.values.astype(float)
elif 'xtime' in ds.keys():
timestamps = []
for time_str in ds.xtime.values.astype(str):
try:
timestamp = datetime.strptime(time_str, '%Y-%m-%d_%H:%M:%S.%f')
except ValueError:
timestamp = datetime.strptime(time_str, '%Y-%m-%d_%H:%M:%S')
timestamps.append(timestamp)
# Calculate seconds since the first timestamp
seconds_since_start = [
(ts - timestamps[0]).total_seconds() for ts in timestamps
]
t_arr = np.array(seconds_since_start, dtype=float) / 86400.0
elif 'Time' in ds.keys():
t_vals = ds['Time'].values
t_pd = pd.to_datetime(t_vals)
t_arr = 1.0e9 * (t_pd - t_pd[0]) / np.timedelta64(1, 's')
t_arr = t_arr.astype(float) / 86400.0
else:
raise ValueError('Could not find a time variable in dataset')
return t_arr
1 change: 1 addition & 0 deletions polaris/suites/ocean/mpaso_pr.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ ocean/planar/internal_wave/vlr/default
# ocean/planar/merry_go_round/default
ocean/planar/overflow/default
ocean/single_column/cvmix
ocean/single_column/cvmix_no_vadv
ocean/single_column/ekman
ocean/single_column/ideal_age
ocean/single_column/inertial
Expand Down
157 changes: 152 additions & 5 deletions polaris/tasks/ocean/single_column/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
from polaris.tasks.ocean.single_column.cvmix import CVMix as CVMix
from polaris.config import PolarisConfigParser as PolarisConfigParser
from polaris.tasks.ocean.single_column.ekman import Ekman as Ekman
from polaris.tasks.ocean.single_column.ideal_age import IdealAge as IdealAge
from polaris.tasks.ocean.single_column.inertial import Inertial as Inertial
from polaris.tasks.ocean.single_column.init import Init
from polaris.tasks.ocean.single_column.vmix import VMix as VMix


def add_single_column_tasks(component):
Expand All @@ -11,7 +13,152 @@ def add_single_column_tasks(component):
component : polaris.tasks.ocean.Ocean
the ocean component that the tasks will be added to
"""
component.add_task(Ekman(component=component))
component.add_task(CVMix(component=component))
component.add_task(IdealAge(component=component))
component.add_task(Inertial(component=component))
group_name = 'single_column'

name = 'vmix_stable'
forcing = ['wind']
forcing_dir = '_'.join(forcing) if forcing else 'no_forcing'
filepath = f'{component.name}/{group_name}/{name}/{name}.cfg'
config = PolarisConfigParser(filepath=filepath)
config.add_from_package(
'polaris.tasks.ocean.single_column', f'{group_name}.cfg'
)
for forcing_name in forcing:
config.add_from_package(
'polaris.tasks.ocean.single_column', f'{forcing_name}.cfg'
)
config.add_from_package(
'polaris.tasks.ocean.single_column', 'stable_stratification.cfg'
)
init_step = component.get_or_create_shared_step(
step_cls=Init,
subdir=f'{group_name}/{forcing_dir}/init_stable',
config=config,
config_filename=f'{name}.cfg',
)
component.add_task(
VMix(
component=component,
config=config,
name=name,
init=init_step,
indir=group_name,
)
)

name = 'vmix_unstable'
forcing = []
forcing_dir = '_'.join(forcing) if forcing else 'no_forcing'
filepath = f'{component.name}/{group_name}/{name}/{name}.cfg'
config = PolarisConfigParser(filepath=filepath)
config.add_from_package(
'polaris.tasks.ocean.single_column', f'{group_name}.cfg'
)
for forcing_name in forcing:
config.add_from_package(
'polaris.tasks.ocean.single_column', f'{forcing_name}.cfg'
)
config.add_from_package(
'polaris.tasks.ocean.single_column', 'unstable_stratification.cfg'
)
init_step = component.get_or_create_shared_step(
step_cls=Init,
subdir=f'{group_name}/{forcing_dir}/init_unstable',
config=config,
config_filename=f'{name}.cfg',
)
component.add_task(
VMix(
component=component,
config=config,
name=name,
init=init_step,
indir=group_name,
)
)

forcing = ['wind']
name = 'ekman'
filepath = f'{component.name}/{group_name}/{name}/{name}.cfg'
config = PolarisConfigParser(filepath=filepath)
config.add_from_package(
'polaris.tasks.ocean.single_column', f'{group_name}.cfg'
)
for forcing_name in forcing:
config.add_from_package(
'polaris.tasks.ocean.single_column', f'{forcing_name}.cfg'
)
init_step = component.get_or_create_shared_step(
step_cls=Init,
subdir=f'{group_name}/{forcing_name}/init',
config=config,
config_filename=f'{name}.cfg',
)
component.add_task(
Ekman(
component=component,
config=config,
init=init_step,
indir=group_name,
)
)

name = 'ideal_age'
forcing = ['evap']
forcing_dir = '_'.join(forcing) if forcing else 'no_forcing'
filepath = f'{component.name}/{group_name}/{name}/{name}.cfg'
config = PolarisConfigParser(filepath=filepath)
config.add_from_package(
'polaris.tasks.ocean.single_column', f'{group_name}.cfg'
)
for forcing_name in forcing:
config.add_from_package(
'polaris.tasks.ocean.single_column', f'{forcing_name}.cfg'
)
config.add_from_package(
'polaris.tasks.ocean.single_column', 'stable_stratification.cfg'
)
init_step = component.get_or_create_shared_step(
step_cls=Init,
subdir=f'{group_name}/{forcing_dir}/init_stable',
config=config,
config_filename=f'{name}.cfg',
)
component.add_task(
IdealAge(
component=component,
init=init_step,
config=config,
indir=group_name,
)
)

name = 'inertial'
forcing = []
forcing_dir = '_'.join(forcing) if forcing else 'no_forcing'
filepath = f'{component.name}/{group_name}/{name}/{name}.cfg'
config = PolarisConfigParser(filepath=filepath)
config.add_from_package(
'polaris.tasks.ocean.single_column', f'{group_name}.cfg'
)
for forcing_name in forcing:
config.add_from_package(
'polaris.tasks.ocean.single_column', f'{forcing_name}.cfg'
)
config.add_from_package(
'polaris.tasks.ocean.single_column', 'stable_stratification.cfg'
)
init_step = component.get_or_create_shared_step(
step_cls=Init,
subdir=f'{group_name}/{forcing_dir}/init_stable',
config=config,
config_filename=f'{name}.cfg',
)
component.add_task(
Inertial(
component=component,
init=init_step,
config=config,
indir=group_name,
)
)
Loading
Loading