Coriolis

The module polaris.coriolis adds the Coriolis parameter to a horizontal mesh dataset. Each of its functions sets fCell, fEdge and fVertex on the dataset it is given, with a long_name, a standard_name of coriolis_parameter and units of radians s^-1, and returns the updated dataset.

Nothing in the module is specific to a component: it reads the coordinates that any MPAS mesh has (xCell, yCell, lonCell, latCell and their edge and vertex counterparts) and writes mesh fields. It is therefore available to the ocean, sea ice and any future component.

From config options

Most init steps use polaris.coriolis.add_coriolis_to_dataset(), which chooses the kind of Coriolis from the [coriolis] config section:

import xarray as xr

from polaris.coriolis import add_coriolis_to_dataset
from polaris.step import Step


class Init(Step):
    def run(self):
        ds_mesh = xr.open_dataset('culled_mesh.nc')
        ds_mesh = add_coriolis_to_dataset(self.config, ds_mesh)

The type option selects one of five kinds, and each kind reads only the parameters that belong to it:

type

parameters read

zero

none

constant

constant_f

beta_plane

beta_plane_f0, beta_plane_beta

spherical

none

rotated_sphere

rotated_sphere_alpha

polaris/default.cfg declares all five options but gives none of them a value. A task that needs Coriolis has to say which kind it wants, and with which parameters, in its own config file:

[coriolis]

# type of Coriolis: zero, constant, beta_plane, spherical, or rotated_sphere
type = constant

# the constant Coriolis parameter
constant_f = 1.0e-4

A task that forgets gets a ValueError naming the option it left unset, rather than a mesh that silently has no rotation. A task that wants no rotation says type = zero; that is a statement about the task rather than a default it fell into. The options it does not use may stay blank, since they are never read.

An option can also be set at run time, when its value depends on something the config file cannot express. For example, polaris.tasks.ocean.barotropic_gyre.init.Init computes f0 from the domain size before adding the fields:

config.set('coriolis', 'beta_plane_f0', str(f0))
ds_mesh = add_coriolis_to_dataset(config, ds_mesh)

Directly

A step that should not be configurable calls the helper for the kind it needs and skips the config section altogether. This suits steps whose output is a released data product, where “not configurable” is a stronger guarantee than “configured well by default”:

The two spherical helpers take an optional omega, defaulting to the Earth’s angular_velocity from polaris.constants.get_constant().