single_column

The single column tests in polaris.tasks.ocean.single_column exercise the vertical dynamics of the ocean model only. The test cases are:

  • Testing the vertical mixing library, CVMix, under surface forcing

  • Testing the Ideal Age tracer under surface forcing

  • Testing the Coriolis term by quantifying the inertial frequency

  • Testing the Ekman solution under wind forcing

Here, we describe the tests and their shared framework.

framework

The shared config options for the single_column tests are described in single column in the User’s Guide.

Additionally, the tests share a forward.yaml file with a few common model config options related to the initial state, coriolis forcing, run duration and surface forcing, as well as defining mesh, input, restart, and output, streams.

init

The class polaris.tasks.ocean.single_column.init.Init defines a step for setting up the initial state for each test case.

4×4 planar hex mesh is generated for this task using mpas_tools.planar_hex.make_planar_hex_mesh(). The number of cells in each dimension can be modified with config options single_column:nx, single_column:ny. By default, the mesh is 960 m in horizontal resolution and is not intended to resolve any lateral gradients. The horizontal resolution can be modified with config option single_column:resolution

A vertical grid is generated, with 100 layers of 4 m thickness each by default.

The initial temperature and salinity field are computed with variability in the vertical dimension only. The config options that determine these profiles are located in section single_column and include:

Option

Description

surface_temperature, surface_salinity

Initial surface values

temperature_gradient_mixed_layer, salinity_gradient_mixed_layer

Gradients within the mixed layer

temperature_difference_across_mixed_layer, salinity_difference_across_mixed_layer

Profile discontinuity across the mixed layer

temperature_gradient_interior, salinity_gradient_interior

Interior (below mixed layer) gradients

mixed_layer_depth_temperature, mixed_layer_depth_salinity

Mixed layer depths (typically ~40 m)

For cases with ideal age tracers, an initial profile for the ideal age tracer is also constructed and is equal to zero seconds throughout the column.

A forcing netCDF file is also created based on the config options given in the single_column_forcing section. A subset of those options are:

Option

Description

temperature_piston_velocity, salinity_piston_velocity

Surface restoring rates

temperature_surface_restoring_value, salinity_surface_restoring_value

Target surface values

temperature_interior_restoring_rate, salinity_interior_restoring_rate

Interior restoring rates

latent_heat_flux, sensible_heat_flux, shortwave_heat_flux

Surface heat flux components

evaporation_flux, rain_flux

Surface freshwater fluxes

wind_stress_zonal, wind_stress_meridional

Wind stress values

The forcing file holds only these forcing fields and the initial condition holds only the initial state, so both ocean models read their forcing from forcing.nc. The one exception is Omega’s TracersMonthlySurfClimoCell, the surface restoring climatology, which Omega registers as an auxiliary state variable rather than a member of its Forcing group and reads from the initial condition.

forward

The class polaris.tasks.ocean.single_column.forward.Forward defines a step for running MPAS-Ocean from the initial condition produced in the init step. The ocean model is run.

viz

The class polaris.tasks.ocean.single_column.viz.Viz produces figures comparing the initial and final profiles of temperature and salinity.

cvmix

The polaris.tasks.ocean.single_column.cvmix.CVMix test performs a 10-day run on 1 cores. Then, validation of temperature, salinity, layerThickness and normalVelocity are performed against a baseline if one is provided when calling polaris setup.

ekman

The polaris.tasks.ocean.single_column.cvmix.CVMix test performs a 5-day run on 1 cores. Then, validation of temperature, salinity, layerThickness and normalVelocity are performed against a baseline if one is provided when calling polaris setup.

ideal age

The polaris.tasks.ocean.single_column.cvmix.IdealAge test performs the same 10-day run on 1 cores as the polaris.tasks.ocean.single_column.cvmix.CVMix test, but with a single ideal age tracer included. An additional forward.yaml file is included in the ideal age tracer test case for enabeling on the ideal age tracers and ideal age surface forcing, as well as for defining idealAgeTracers streams. Validation of temperature, salinity, and idealAgeTracers are performed against a baseline if one is provided when calling polaris setup.

inertial

The polaris.tasks.ocean.single_column.inertial.Inertial test performs a 10-day run on 1 cores. Then, validation of temperature, salinity, layerThickness and normalVelocity are performed against a baseline if one is provided when calling polaris setup. Then, the analysis step is run, and the viz step is optionally run.

analysis

The polaris.tasks.ocean.single_column.inertial.analysis.Analysis compares the inertial frequency with its theoretical value and induces a failure if the frequency is more than a given fractional difference from theory, as determined by the config option single_column_inertial:period_tolerance_fraction.

thermo

The polaris.tasks.ocean.single_column.thermo.Thermo test performs a separate forward run of 3 time steps, with output written every time step, for each supported surface thermodynamic forcing variable (latent, sensible, shortwave and longwave heat fluxes; evaporation, snow, rain, river- and ice-runoff and sea-ice freshwater fluxes; and the sea-ice heat and salinity fluxes). Each init/forward pair applies a single nonzero forcing variable so that the individual forcing terms can be verified in isolation. Conservation is checked twice for each run: between the initial condition and the first time step in the output file, and between the last two time steps. Then the analysis step is run, and the viz step is optionally run.

conservation_summary

The polaris.tasks.ocean.single_column.thermo.conservation_summary.ConservationSummary step gathers the conservation results from each forward step’s property_check_results.json and writes conservation_summary.log, which lists each forward step name along with its mass, salt and energy relative error for each conservation interval.

analysis

The polaris.tasks.ocean.single_column.thermo.analysis.Analysis verifies conservation of mass, heat and salt for each forward run. For every run it compares the change in the column-integrated content against the surface forcing flux accumulated over the run. For a budget driven by a nonzero flux the error is measured relative to that accumulated flux; for a budget with no expected flux the residual is compared against the config option single_column_thermo:conservation_error_tolerance times the initial total column content. A failure is induced if any budget’s error exceeds that tolerance.

The budgets follow exactly what the model integrates. For Omega, the mass coordinate is the pseudo-thickness h (RhoSw * h is the mass per area), so the checks use the native PseudoThickness, Temperature and Salinity fields rather than the reconstructed geometric thickness. The column budgets per unit area are:

  • mass: RhoSw * sum_k(dh_k) vs the accumulated freshwater plus sea-ice salt flux (both enter Omega’s thickness equation),

  • heat: RhoSw * Cp0Sw * sum_k(d(h_k T_k)) vs the accumulated enthalpy flux,

  • salt: (RhoSw / 1000) * sum_k(d(h_k S_k)) vs the accumulated sea-ice salinity flux.

Because the freshwater mass fluxes (rain, river runoff, snow and ice runoff) also carry an SST-/freezing-point-dependent enthalpy heat flux, the heat budget is skipped for those runs. For MPAS-Ocean (Boussinesq), which has no pseudo-thickness, the geometric layerThickness is used instead.