
Versatile Ocean Simulation in Pure Python¶
Veros, the versatile ocean simulator, aims to be the swiss army knife of ocean modeling. It is a full-fledged GCM that supports anything between highly idealized configurations and realistic set-ups, targeting students and seasoned researchers alike. Thanks to its seamless interplay with Bohrium, Veros runs efficiently on your laptop, gaming PC (with experimental GPU support through OpenCL & CUDA), and small cluster. Veros has a clear focus on simplicity, usability, and adaptability - because the Baroque is over.
If you want to learn more about the background and capabilities of Veros, you should check out A short introduction to Veros. If you are already convinced, you can jump right into action, and learn how to get started instead!
A short introduction to Veros¶
The vision¶
Veros is an adaptation of pyOM2 (v2.1.0), developed by Carsten Eden (Institut für Meereskunde, Hamburg University). In contrast to pyOM2, however, this implementation does not rely on a Fortran backend for computations - everything runs in pure Python, down to the last parameterization. We believe that using this approach it is possible to create an open source ocean model that is:
Easy to access: Python modules are simple to install, and projects like Anaconda are doing a great job in creating platform-independent environments.
Easy to use: Anyone with some experience can use their favorite Python tools to set up, control, and post-process Veros.
Easy to verify: Python code tends to be concise and easy to read, even for people with little practical programming experience. This enables a wide range of people to spot errors in our code, solidifying it in the process.
Easy to modify: Due to the popularity of Python, its dynamic code structure, and OOP-capabilities, Veros can be extended and modified with minimal effort.
However, using Python over a compiled language like Fortran usually comes at a high computational cost. We try to overcome this gap for large models by providing an interface to Bohrium, a framework that acts as a high-performance replacement for NumPy. Bohrium takes care of all parallelism in the background for us, so we can concentrate on writing a nice, readable ocean model.
In case you are curious about how Veros is currently stacking up against pyOM2 in terms of performance, you should check out our benchmarks.
Features¶
Note
This section provides a quick overview of the capabilities and limitations of Veros. For a comprehensive description of the physics and numerics behind Veros, please refer to the documentation of pyOM2. You can also obtain a copy of the PDF documentation here
.
The model domain¶
The numerical solution is calculated using finite differences on an Arakawa C-grid, which is staggered in every dimension. Tracers (like temperature and salinity) are calculated at different positions than zonal, meridional, and vertical fluxes (like the velocities u, v, and w). The following figure shows the relative positions of the so-called T, U, V, and ζ grid points (W not shown):
The structure of the Arakawa C-grid.¶
Veros supports both Cartesian and pseudo-spherical (i.e., including additional metric terms) coordinate systems. Islands or holes in the domain are fully supported by the streamfunction solver. Zonal boundaries can either be cyclic or regraded as walls (with free-slip boundary conditions).
Available parameterizations¶
At its core, Veros currently offers the following solvers, numerical schemes, parameterizations, and closures:
- Surface pressure:
a high-performance streamfunction solver via an iterative Poisson solver
- Equation of state:
the full 48-term TEOS equation of state
various linear and nonlinear model equations from [Vallis2006]
- Friction:
harmonic or biharmonic lateral friction
linear or quadratic bottom friction
interior Rayleigh friction
explicit or fully implicit harmonic vertical friction
- Advection:
a classical second-order central difference scheme
a second-order scheme with a superbee flux-limiter
- Diffusion:
harmonic or biharmonic lateral diffusion
explicit or implicit harmonic vertical diffusion
- Isoneutral mixing:
lateral mixing of tracers along neutral surfaces following [Griffies1998] (optional)
- Internal wave breaking:
IDEMIX as in [OlbersEden2013] (optional)
- EKE model (eddy kinetic energy):
meso-scale eddy mixing closure after [Gent1995], either with constant coefficients or calculated using the prognostic EKE closure by [EdenGreatbatch2008] (optional)
- TKE model (turbulent kinetic energy):
prognostic TKE model for vertical mixing as introduced in [Gaspar1990] (optional)
Diagnostics¶
Diagnostics are responsible for handling all model output, runtime checks of the solution, and restart file handling. They are implemented in a modular fashion, so additional diagnostics can be implemented easily. Already implemented diagnostics handle snapshot output, time-averaging of variables, monitoring of energy fluxes, and calculation of the overturning streamfunction.
For more information, see Diagnostics.
Pre-configured model setups¶
Veros supports a wide range of model configurations. Several setups are already implemented that highlight some of the capabilities of Veros, and that serve as a basis for users to set up their own configuration: Setup gallery.
Current limitations¶
Veros is still in early development. There are several open issues that we would like to fix later on:
- Physics:
Veros does not yet implement any of the more recent pyOM2.2 features such as the ROSSMIX parameterization, IDEMIX v3.0, open boundary conditions, or cyclic meridional boundaries. It neither implements all of pyOM2.1’s features - missing are e.g. the non-hydrostatic solver, IDEMIX v2.0, and the surface pressure solver.
Since the grid is required to be rectilinear, there is currently no natural way to handle the singularity at the North Pole. The northern and southern boundaries of the domain are thus always “walls”.
There is currently no ice sheet model in Veros. Some realistic setups employ a simple ice mask that cut off atmospheric forcing for water that gets too cold instead.
- Technical issues:
For the time being, Veros’ dynamical core is still more or less a direct port of PyOM2. This means that numerics and physics are still tightly coupled, which makes for a far from optimal user experience. In a future version of Veros, we would like to introduce additional abstraction to make the core routines a lot more readable than they are now.
References¶
- EdenGreatbatch2008
Eden, Carsten, and Richard J. Greatbatch. “Towards a mesoscale eddy closure.” Ocean Modelling 20.3 (2008): 223-239.
- OlbersEden2013
Olbers, Dirk, and Carsten Eden. “A global model for the diapycnal diffusivity induced by internal gravity waves.” Journal of Physical Oceanography 43.8 (2013): 1759-1779.
- Gent1995
Gent, Peter R., et al. “Parameterizing eddy-induced tracer transports in ocean circulation models.” Journal of Physical Oceanography 25.4 (1995): 463-474.
- Griffies1998
Griffies, Stephen M. “The Gent–McWilliams skew flux.” Journal of Physical Oceanography 28.5 (1998): 831-841.
- Vallis2006
Vallis, Geoffrey K. “Atmospheric and oceanic fluid dynamics: fundamentals and large-scale circulation.” Cambridge University Press, 2006.
- Gaspar1990
Gaspar, Philippe, Yves Grégoris, and Jean‐Michel Lefevre. “A simple eddy kinetic energy model for simulations of the oceanic vertical mixing: Tests at station Papa and Long‐Term Upper Ocean Study site.” Journal of Geophysical Research: Oceans 95.C9 (1990): 16179-16193.
Getting started¶
Installation¶
Using pip (multi-platform)¶
Note
You should only install Veros via pip if you want to get going as quickly as possible, and do not plan to access or modify the Veros source code. The prefered way to install Veros is through Anaconda (see below).
If you already have Python installed, the quickest way to get a working Veros installation is to run:
$ pip install veros --user
and optionally:
$ pip install bohrium --user
to use Veros with Bohrium (Linux and OSX only).
Using Anaconda (multi-platform, recommended)¶
Download and install Anaconda. Make sure to grab the 64-bit version of the Python interpreter.
Clone the Veros repository:
$ git clone https://github.com/dionhaefner/veros.git
Create a new conda environment for Veros, and install all relevant dependencies, by running
$ conda env create -f environment-unix.yml
on Linux and OSX, or
$ conda env create -f environment-windows.yml
on Windows.
To use Veros, just activate your new conda environment! This can be done through either conda activate veros, source activate veros, or activate veros, depending on your platform and Anaconda installation.
On bare metal (Ubuntu / Debian)¶
Install some dependencies:
$ sudo apt-get install git python3-dev python3-pip libhdf5-dev
Clone our repository:
$ git clone https://github.com/dionhaefner/veros.git
Install Veros (preferably in a virtual environment) via:
$ pip3 install -e ./veros --user
Optionally, install Bohrium via:
$ pip3 install bohrium --user
Setting up a model¶
To run Veros, you need to set up a model - i.e., specify which settings and model domain you want to use. This is done by subclassing the Veros setup base class
in a setup script that is written in Python. You should have a look at the pre-implemented model setups in the repository’s setup
folder, or use the veros copy-setup command to copy one into your current folder. A good place to start is the ACC model
:
$ veros copy-setup acc
By working through the existing models, you should quickly be able to figure out how to write your own simulation. Just keep in mind this general advice:
You can (and should) use any (external) Python tools you want in your model setup. Before implementing a certain functionality, you should check whether it is already provided by a common library. Especially the SciPy module family provides countless implementations of common scientific functions (and SciPy is installed along with Veros).
If you decorate your methods with
@veros_method
, the variablenp
inside that function will point to the currently used backend (i.e., NumPy or Bohrium). Thus, if you want your setup to be able to dynamically switch between backends, you should write your methods like this:from veros import Veros, veros_method class MyVerosSetup(Veros): ... @veros_method def my_function(self): arr = np.array([1,2,3,4]) # "np" uses either NumPy or Bohrium
If you are curious about the general procedure in which a model is set up and ran, you should read the source code of
veros.VerosSetup
(especially thesetup()
andrun()
methods). This is also the best way to find out about the order in which methods and routines are called.Out of all functions that need to be implemented by your subclass of
veros.VerosSetup
, the only one that is called in every time step isset_forcing()
(at the beginning of each iteration). This implies that, to achieve optimal performance, you should consider moving calculations that are constant in time to other functions.
If you want to learn more about setting up advanced configurations, you should check out our tutorial that walks you through the creation of a realistic configuration with an idealized Atlantic.
Running Veros¶
After adapting your setup script, you are ready to run your first simulation. It is advisable to include something like:
@veros.tools.cli
def run(*args, **kwargs):
simulation = MyVerosSetup()
simulation.setup()
simulation.run()
if __name__ == "__main__":
run()
in your setup file, so you can run it as a script:
$ python my_setup.py
However, you are not required to do so, and you are welcome to write include your simulation class into other Python files and call it dynamically or interactively (e.g. in an IPython session).
All Veros setups decorated with veros.tools.cli()
accept additional options via the command line when called as a script or as arguments to their __init__()
function when called from another Python module. You can check the available commands through
$ python my_setup.py --help
Reading Veros output¶
All output is handled by the available diagnostics. The most basic diagnostic, snapshot, writes some model variables to netCDF files in regular intervals (and puts them into your current working directory).
NetCDF is a binary format that is widely adopted in the geophysical modeling community. There are various packages for reading, visualizing and processing netCDF files (such as ncview and ferret), and bindings for many programming languages (such as C, Fortran, MATLAB, and Python).
In fact, after installing Veros, you will already have installed the netCDF bindings for Python, so reading data from an output file and plotting it is as easy as:
import matplotlib.pyplot as plt
import h5netcdf
with h5netcdf.File("veros.snapshot.nc", "r") as datafile:
# read variable "u" and save it to a NumPy array
u = datafile.variables["u"][...]
# plot surface velocity at the last time step included in the file
plt.imshow(u[-1, -1, ...])
plt.show()
For further reference refer to the netcdf4-python documentation.
Using Bohrium¶
Warning
While Bohrium yields significant speed-ups for large to very large setups, the overhead introduced by Bohrium often leads to (sometimes considerably) slower execution for problems below a certain threshold size (see also Which backend should I choose to run my model (NumPy / Bohrium)?). You are thus advised to test carefully whether Bohrium is beneficial in your particular use case.
For large simulations, it is often beneficial to use the Bohrium backend for computations. When using Bohrium, all number crunching will make full use of your available architecture, i.e., computations are executed in parallel on all of your CPU cores, or even GPU when using BH_STACK=opencl
or BH_STACK=cuda
. You may switch between NumPy and Bohrium with a simple command line switch:
$ python my_setup.py -b bohrium
or, when running inside another Python module: (must be done before initializing you setup):
from veros import runtime_settings as rs
rs.backend = "bohrium"
Re-starting from a previous run¶
Restart data (in HDF5 format) is written at the end of each simulation or after a regular time interval if the setting restart_frequency is set to a finite value. To use this restart file as initial conditions for another simulation, you will have to point restart_input_filename of the new simulation to the corresponding restart file. This can (as all settings) also be given via command line:
$ python my_setup.py -s restart_input_filename /path/to/restart_file.h5
Running Veros on multiple processes via MPI¶
Note
This assumes that you are familiar with running applications through MPI, and is most useful on large architectures like a compute cluster. For smaller architectures, it is usually easier to stick to Bohrium.
Running Veros through MPI requires some addititonal dependencies:
A recent MPI implementation, such as OpenMPI or MPICH
mpi4py
that is linked to the correct MPI libraryA parallel-enabled version of the HDF5 library
h5py
built against this parallel version of HDF5For optimal performance, PETSc and
petsc4py
, linked to the rest of the stack
After you have installed everything, you can start Veros on multiple processes like so::
$ mpirun -n 4 python my_setup.py -n 2 2
In this case, Veros would run on 4 processes, each process computing one-quarter of the domain. The arguments of the -n flag specify the number of chunks in x and y-direction, respectively.
You can combine MPI and Bohrium like so::
$ OMP_NUM_THREADS=2 mpirun -n 2 python my_setup.py -n 2 1 -b bohrium
This starts 2 independent processes, each being parallelized by Bohrium using 2 threads (hybrid run).
See also
For more information, see Running Veros on a cluster.
Enhancing Veros¶
Veros was written with extensibility in mind. If you already know some Python and have worked with NumPy, you are pretty much ready to write your own extension. The model code is located in the veros
subfolder, while all of the numerical routines are located in veros/core
.
We believe that the best way to learn how Veros works is to read its source code. Starting from the Veros base class
, you should be able to work your way through the flow of the program, and figure out where to add your modifications. If you installed Veros through pip -e or setup.py develop, all changes you make will immediately be reflected when running the code.
In case you want to add additional output capabilities or compute additional quantities without changing the main solution of the simulation, you should consider adding a custom diagnostic.
A convenient way to implement your modifications is to create your own fork of Veros on GitHub, and submit a pull request if you think your modifications could be useful for the Veros community.
See also
More information is available in our developer guide.
Creating an advanced model setup¶
Note
This guide is still work in progress.
This is a step-by-step guide that illustrates how even complicated setups can be created with relative ease (thanks to the tools provided by the scientific Python community). As an example, we will re-create the wave propagation setup, which is a global ocean model with an idealized Atlantic.

The resulting stream function after about 1 year of integration.¶
The vision¶
The purpose of this model is to examine wave propagation along the eastern boundary of the North Atlantic. Since it is difficult to track propagating waves along ragged geometry or through uneven forcing fields, we will idealize the representation of the North Atlantic; and as the presence of the Pacific in the model is crucial to achieve a realistic ocean circulation, we want to use a global model.
This leaves us with the following requirements for the final wave propagation model:
A global model with a resolution of around 2 degrees and meridional stretching.
Convert the eastern boundary of the Atlantic to a straight line, so analytically derived wave properties hold.
A refined grid resolution at the eastern boundary of the Atlantic.
Zonally averaged forcings in the Atlantic.
A somehow interpolated initial state for cells that have been converted from land to ocean in the North Atlantic.
Options for shelf and continental slope.
A multiplier setting for the Southern Ocean wind stress.
Model skeleton¶
Instead of starting from scratch, we can use the global one degree model as a template, which looks like this:
#!/usr/bin/env python
import os
import h5netcdf
from veros import VerosSetup, tools, veros_method, time
from veros.variables import Variable, allocate
BASE_PATH = os.path.dirname(os.path.realpath(__file__))
DATA_FILES = tools.get_assets('global_1deg', os.path.join(BASE_PATH, 'assets.yml'))
class GlobalOneDegreeSetup(VerosSetup):
"""Global 1 degree model with 115 vertical levels.
`Adapted from pyOM2 <https://wiki.zmaw.de/ifm/TO/pyOM2/1x1%20global%20model>`_.
"""
@veros_method
def set_parameter(self, vs):
"""
set main parameters
"""
vs.nx = 360
vs.ny = 160
vs.nz = 115
vs.dt_mom = 1800.0
vs.dt_tracer = 1800.0
vs.runlen = 0.
vs.coord_degree = True
vs.enable_cyclic_x = True
vs.congr_epsilon = 1e-10
vs.congr_max_iterations = 10000
vs.enable_hor_friction = True
vs.A_h = 5e4
vs.enable_hor_friction_cos_scaling = True
vs.hor_friction_cosPower = 1
vs.enable_tempsalt_sources = True
vs.enable_implicit_vert_friction = True
vs.eq_of_state_type = 5
# isoneutral
vs.enable_neutral_diffusion = True
vs.K_iso_0 = 1000.0
vs.K_iso_steep = 50.0
vs.iso_dslope = 0.005
vs.iso_slopec = 0.005
vs.enable_skew_diffusion = True
# tke
vs.enable_tke = True
vs.c_k = 0.1
vs.c_eps = 0.7
vs.alpha_tke = 30.0
vs.mxl_min = 1e-8
vs.tke_mxl_choice = 2
vs.kappaM_min = 2e-4
vs.kappaH_min = 2e-5
vs.enable_kappaH_profile = True
vs.enable_tke_superbee_advection = True
# eke
vs.enable_eke = True
vs.eke_k_max = 1e4
vs.eke_c_k = 0.4
vs.eke_c_eps = 0.5
vs.eke_cross = 2.
vs.eke_crhin = 1.0
vs.eke_lmin = 100.0
vs.enable_eke_superbee_advection = True
vs.enable_eke_isopycnal_diffusion = True
# idemix
vs.enable_idemix = False
vs.enable_eke_diss_surfbot = True
vs.eke_diss_surfbot_frac = 0.2
vs.enable_idemix_superbee_advection = True
vs.enable_idemix_hor_diffusion = True
# custom variables
vs.nmonths = 12
vs.variables.update(
t_star=Variable('t_star', ('xt', 'yt', 'nmonths'), '', '', time_dependent=False),
s_star=Variable('s_star', ('xt', 'yt', 'nmonths'), '', '', time_dependent=False),
qnec=Variable('qnec', ('xt', 'yt', 'nmonths'), '', '', time_dependent=False),
qnet=Variable('qnet', ('xt', 'yt', 'nmonths'), '', '', time_dependent=False),
qsol=Variable('qsol', ('xt', 'yt', 'nmonths'), '', '', time_dependent=False),
divpen_shortwave=Variable('divpen_shortwave', ('zt',), '', '', time_dependent=False),
taux=Variable('taux', ('xt', 'yt', 'nmonths'), '', '', time_dependent=False),
tauy=Variable('tauy', ('xt', 'yt', 'nmonths'), '', '', time_dependent=False),
)
@veros_method
def _read_forcing(self, vs, var):
with h5netcdf.File(DATA_FILES['forcing'], 'r') as infile:
var = infile.variables[var]
return np.array(var, dtype=str(var.dtype)).T
@veros_method
def set_grid(self, vs):
dz_data = self._read_forcing(vs, 'dz')
vs.dzt[...] = dz_data[::-1]
vs.dxt[...] = 1.0
vs.dyt[...] = 1.0
vs.y_origin = -79.
vs.x_origin = 91.
@veros_method
def set_coriolis(self, vs):
vs.coriolis_t[...] = 2 * vs.omega * np.sin(vs.yt[np.newaxis, :] / 180. * vs.pi)
@veros_method(dist_safe=False, local_variables=['kbot'])
def set_topography(self, vs):
bathymetry_data = self._read_forcing(vs, 'bathymetry')
salt_data = self._read_forcing(vs, 'salinity')[:, :, ::-1]
mask_salt = salt_data == 0.
vs.kbot[2:-2, 2:-2] = 1 + np.sum(mask_salt.astype(np.int), axis=2)
mask_bathy = bathymetry_data == 0
vs.kbot[2:-2, 2:-2][mask_bathy] = 0
vs.kbot[vs.kbot >= vs.nz] = 0
# close some channels
i, j = np.indices((vs.nx, vs.ny))
mask_channel = (i >= 207) & (i < 214) & (j < 5) # i = 208,214; j = 1,5
vs.kbot[2:-2, 2:-2][mask_channel] = 0
# Aleutian islands
mask_channel = (i == 104) & (j == 134) # i = 105; j = 135
vs.kbot[2:-2, 2:-2][mask_channel] = 0
# Engl channel
mask_channel = (i >= 269) & (i < 271) & (j == 130) # i = 270,271; j = 131
vs.kbot[2:-2, 2:-2][mask_channel] = 0
@veros_method(dist_safe=False, local_variables=[
't_star', 's_star', 'qnec', 'qnet', 'qsol', 'divpen_shortwave', 'taux', 'tauy',
'temp', 'salt', 'forc_iw_bottom', 'forc_iw_surface', 'kbot', 'maskT', 'maskW',
'zw', 'dzt'
])
def set_initial_conditions(self, vs):
rpart_shortwave = 0.58
efold1_shortwave = 0.35
efold2_shortwave = 23.0
# initial conditions
temp_data = self._read_forcing(vs, 'temperature')
vs.temp[2:-2, 2:-2, :, 0] = temp_data[..., ::-1] * vs.maskT[2:-2, 2:-2, :]
vs.temp[2:-2, 2:-2, :, 1] = temp_data[..., ::-1] * vs.maskT[2:-2, 2:-2, :]
salt_data = self._read_forcing(vs, 'salinity')
vs.salt[2:-2, 2:-2, :, 0] = salt_data[..., ::-1] * vs.maskT[2:-2, 2:-2, :]
vs.salt[2:-2, 2:-2, :, 1] = salt_data[..., ::-1] * vs.maskT[2:-2, 2:-2, :]
# wind stress on MIT grid
vs.taux[2:-2, 2:-2, :] = self._read_forcing(vs, 'tau_x')
vs.tauy[2:-2, 2:-2, :] = self._read_forcing(vs, 'tau_y')
qnec_data = self._read_forcing(vs, 'dqdt')
vs.qnec[2:-2, 2:-2, :] = qnec_data * vs.maskT[2:-2, 2:-2, -1, np.newaxis]
qsol_data = self._read_forcing(vs, 'swf')
vs.qsol[2:-2, 2:-2, :] = -qsol_data * vs.maskT[2:-2, 2:-2, -1, np.newaxis]
# SST and SSS
sst_data = self._read_forcing(vs, 'sst')
vs.t_star[2:-2, 2:-2, :] = sst_data * vs.maskT[2:-2, 2:-2, -1, np.newaxis]
sss_data = self._read_forcing(vs, 'sss')
vs.s_star[2:-2, 2:-2, :] = sss_data * vs.maskT[2:-2, 2:-2, -1, np.newaxis]
if vs.enable_idemix:
tidal_energy_data = self._read_forcing(vs, 'tidal_energy')
mask = np.maximum(0, vs.kbot[2:-2, 2:-2] - 1)[:, :, np.newaxis] == np.arange(vs.nz)[np.newaxis, np.newaxis, :]
tidal_energy_data[:, :] *= vs.maskW[2:-2, 2:-2, :][mask].reshape(vs.nx, vs.ny) / vs.rho_0
vs.forc_iw_bottom[2:-2, 2:-2] = tidal_energy_data
wind_energy_data = self._read_forcing(vs, 'wind_energy')
wind_energy_data[:, :] *= vs.maskW[2:-2, 2:-2, -1] / vs.rho_0 * 0.2
vs.forc_iw_surface[2:-2, 2:-2] = wind_energy_data
"""
Initialize penetration profile for solar radiation and store divergence in divpen
note that pen is set to 0.0 at the surface instead of 1.0 to compensate for the
shortwave part of the total surface flux
"""
swarg1 = vs.zw / efold1_shortwave
swarg2 = vs.zw / efold2_shortwave
pen = rpart_shortwave * np.exp(swarg1) + (1.0 - rpart_shortwave) * np.exp(swarg2)
pen[-1] = 0.
vs.divpen_shortwave = allocate(vs, ('zt',))
vs.divpen_shortwave[1:] = (pen[1:] - pen[:-1]) / vs.dzt[1:]
vs.divpen_shortwave[0] = pen[0] / vs.dzt[0]
@veros_method
def set_forcing(self, vs):
t_rest = 30. * 86400.
cp_0 = 3991.86795711963 # J/kg /K
year_in_seconds = time.convert_time(1., 'years', 'seconds')
(n1, f1), (n2, f2) = tools.get_periodic_interval(vs.time, year_in_seconds,
year_in_seconds / 12., 12)
# linearly interpolate wind stress and shift from MITgcm U/V grid to this grid
vs.surface_taux[:-1, :] = f1 * vs.taux[1:, :, n1] + f2 * vs.taux[1:, :, n2]
vs.surface_tauy[:, :-1] = f1 * vs.tauy[:, 1:, n1] + f2 * vs.tauy[:, 1:, n2]
if vs.enable_tke:
vs.forc_tke_surface[1:-1, 1:-1] = np.sqrt((0.5 * (vs.surface_taux[1:-1, 1:-1] \
+ vs.surface_taux[:-2, 1:-1]) / vs.rho_0) ** 2
+ (0.5 * (vs.surface_tauy[1:-1, 1:-1] \
+ vs.surface_tauy[1:-1, :-2]) / vs.rho_0) ** 2) ** (3. / 2.)
# W/m^2 K kg/J m^3/kg = K m/s
t_star_cur = f1 * vs.t_star[..., n1] + f2 * vs.t_star[..., n2]
vs.qqnec = f1 * vs.qnec[..., n1] + f2 * vs.qnec[..., n2]
vs.qqnet = f1 * vs.qnet[..., n1] + f2 * vs.qnet[..., n2]
vs.forc_temp_surface[...] = (vs.qqnet + vs.qqnec * (t_star_cur - vs.temp[..., -1, vs.tau])) \
* vs.maskT[..., -1] / cp_0 / vs.rho_0
s_star_cur = f1 * vs.s_star[..., n1] + f2 * vs.s_star[..., n2]
vs.forc_salt_surface[...] = 1. / t_rest * \
(s_star_cur - vs.salt[..., -1, vs.tau]) * vs.maskT[..., -1] * vs.dzt[-1]
# apply simple ice mask
mask1 = vs.temp[:, :, -1, vs.tau] * vs.maskT[:, :, -1] <= -1.8
mask2 = vs.forc_temp_surface <= 0
ice = ~(mask1 & mask2)
vs.forc_temp_surface *= ice
vs.forc_salt_surface *= ice
# solar radiation
if vs.enable_tempsalt_sources:
vs.temp_source[..., :] = (f1 * vs.qsol[..., n1, None] + f2 * vs.qsol[..., n2, None]) \
* vs.divpen_shortwave[None, None, :] * ice[..., None] \
* vs.maskT[..., :] / cp_0 / vs.rho_0
@veros_method
def set_diagnostics(self, vs):
average_vars = ['surface_taux', 'surface_tauy', 'forc_temp_surface', 'forc_salt_surface',
'psi', 'temp', 'salt', 'u', 'v', 'w', 'Nsqr', 'Hd', 'rho',
'K_diss_v', 'P_diss_v', 'P_diss_nonlin', 'P_diss_iso', 'kappaH']
if vs.enable_skew_diffusion:
average_vars += ['B1_gm', 'B2_gm']
if vs.enable_TEM_friction:
average_vars += ['kappa_gm', 'K_diss_gm']
if vs.enable_tke:
average_vars += ['tke', 'Prandtlnumber', 'mxl', 'tke_diss',
'forc_tke_surface', 'tke_surf_corr']
if vs.enable_idemix:
average_vars += ['E_iw', 'forc_iw_surface', 'forc_iw_bottom', 'iw_diss',
'c0', 'v0']
if vs.enable_eke:
average_vars += ['eke', 'K_gm', 'L_rossby', 'L_rhines']
vs.diagnostics['averages'].output_variables = average_vars
vs.diagnostics['cfl_monitor'].output_frequency = 86400.0
vs.diagnostics['snapshot'].output_frequency = 365 * 86400 / 24.
vs.diagnostics['overturning'].output_frequency = 365 * 86400
vs.diagnostics['overturning'].sampling_frequency = 365 * 86400 / 24.
vs.diagnostics['energy'].output_frequency = 365 * 86400
vs.diagnostics['energy'].sampling_frequency = 365 * 86400 / 24.
vs.diagnostics['averages'].output_frequency = 365 * 86400
vs.diagnostics['averages'].sampling_frequency = 365 * 86400 / 24.
@veros_method
def after_timestep(self, vs):
pass
@tools.cli
def run(*args, **kwargs):
simulation = GlobalOneDegreeSetup(*args, **kwargs)
simulation.setup()
simulation.run()
if __name__ == '__main__':
run()
The biggest changes in the new wave propagation setup will be located in the
set_grid()
set_topography()
and set_initial_conditions()
methods to accommodate for the new geometry and the interpolation of initial
conditions to the modified grid, so we can concentrate on implementing those
first.
Step 1: Setup grid¶
Warning
When using a non-uniform grid,
Step 2: Create idealized topography¶
Usually, to create an idealized topography, one would simply hand-craft some input and forcing files that reflect the desired changes. However, since we want our setup to have flexible resolution, we will have to write an algorithm that creates these input files for any given number of grid cells. One convenient way to achieve this is by creating some high-resolution masks representing the target topography by hand, and then interpolate these masks to the desired resolution.
Create a mask image¶
Before we can start, we need to download a high-resolution topography dataset. There are many freely available topographical data sets on the internet; one of them is ETOPO5 (with a resolution of 5 arc-minutes), which we will be using throughout this tutorial. To create a mask image from the topography file, you can use the command line tool veros create-mask, e.g. like
$ veros create-mask ETOPO5_Ice_g_gmt4.nc
This creates a one-to-one representation of the topography file as a PNG image. However, in the case of the 5 arc-minute topography, the resulting image includes a lot of small islands and complicated coastlines that might cause problems when being interpolated to a numerical grid with a much lower resolution. To address this, the create-mask script accepts a scale argument. When given, a Gaussian filter with standard deviation scale (in grid cells) is applied to the resulting image, smoothing out small features. The command
$ veros create-mask ETOPO5_Ice_g_gmt4 --scale 3 3
results in the following mask:

Smoothed topography mask¶
which looks good enough to serve as a basis for horizontal resolutions of around one degree.
Modify the mask¶
We can now proceed to mold this realistic version of the global topography into the desired idealized shape. You can use any image editor you have available; one possibility is the free software GIMP. Inside the editor, we can use the pencil tools to create a modified version of the topography mask:

Idealized topography mask¶
In this modified version, I have
replaced the eastern boundary of the North Atlantic by a meridional line;
removed all lakes and inland seas;
thickened Central America (to prevent North and South America to become disconnected due to interpolation artifacts); and
removed the Arctic Ocean and Hudson Bay.
Now that our topography mask is finished, we can go ahead and implement it in the Veros setup!
Import to Veros¶
To read the mask in PNG format, we are going to use the Python Imaging Library (PIL).
Step 3: Interpolate forcings & initial conditions¶

Mask to identify grid cells in the North Atlantic¶
Step 4: Set up diagnostics & final touches¶
Making changes in Veros¶
Code conventions¶
When contributing to Veros, please adhere to the following general guidelines:
Your first guide should be the surrounding Veros code. Look around, and be consistent with your modifications.
Unless you have a very good reason not to do so, please stick to the PEP8 style guide throughout your code. One exception we make in Veros is in regard to the maximum line length - since numerical operations can take up quite a lot of horizontal space, you may use longer lines if it increases readability.
Please follow the PEP8 naming conventions, and use meaningful, telling names for your variables, functions, and classes. The variable name
stretching_factor
is infinitely more meaningful thank
. This is especially important for settings and generic helper functions.“Private” helper functions that are not meant to be called from outside the current source file should be prefixed with an underscore (
_
).Use double quotes (
"
) for all strings longer than a single character.Document your functions using Google-style docstrings. This is especially important if you are implementing a user-facing API (such as a diagnostic, a setup, or tools that are meant to be called from setups).
Distributed memory support¶
By default, all core routines should support distributed execution via MPI.
In this case, every processor only operates on a chunk of the total data.
By using veros.variables.allocate()
, you can make sure that allocated data always has the right shape.
Since none of the processes have access to the global data, you need to take special care during reductions (e.g. sum
) and accumulations (e.g. cumsum
) along horizontal dimensions.
Use functions from veros.distributed
(e.g. veros.distributed.global_max()
) where appropriate.
The dist_safe keyword¶
If you are not comfortable writing code that is safe for distributed execution, you can use the dist_safe
keyword to veros.decorators.veros_method()
::
@veros_method(dist_safe=False, local_variables=["temp"])
def my_function(vs):
# this function is now guaranteed to be executed on the main process
# since temp is declared as a local variable, we have access to all of the data
vs.temp[2:-2, 2:-2] = np.max(vs.temp)
# this would throw an error, since salt is not in local_variables
# vs.salt[...] = 0
# after execution, the updated contents of vs.temp are scattered to all processes,
# and distributed execution continues
When encountering a veros_method
that is marked as not safe for distributed execution (dist_safe=False
), Veros gathers all relevant data from the worker processes,
copies it to the main process, and executes the function there.
This ensures that you can write your code exactly as in the non-distributed case (but it comes with a performance penalty, of course).
Running tests and benchmarks¶
If you want to make sure that your changes did not break anything, you can run our test suite that compares the results of each subroutine to pyOM2. To do that, you will need to compile the Python interface of pyOM2 on your machine, and then point the testing suite to the library location, e.g. through:
$ pytest -v . --pyom2-lib /path/to/pyOM2/py_src/pyOM_code.so
from the main folder of the Veros repository.
If you deliberately introduced breaking changes, you can disable them during testing by prefixing them with:
if not vs.pyom_compatibility_mode:
# your changes
Automated benchmarks are provided in a similar fashion. The benchmarks run some dummy problems with varying problem sizes and all available computational backends: numpy
, bohrium-openmp
, bohrium-opencl
, bohrium-cuda
, fortran
(pyOM2), and fortran-mpi
(parallel pyOM2). For options and further information run:
$ python run_benchmarks.py --help
from the test
folder. Timings are written in YAML format.
Performance tweaks¶
If your changes to Veros turn out to have a negative effect on the runtime of the model, there several ways to investigate and solve performance problems:
Run your model with the
-v debug
option to get additional debugging output (such as timings for each time step, and a timing summary after the run has finished).Run your model with the
-p
option to profile Veros with pyinstrument. You may have to run pip install pyinstrument before being able to do so. After completion of the run, a fileprofile.html
will be written that can be opened with a web browser and contains timings for the entire call stack.You should try and avoid explicit loops over arrays at all cost (even more so when using Bohrium). You should always try to work on the whole array at once.
When using Bohrium, it is sometimes beneficial to copy an array to NumPy before passing it to an external module or performing an operation that cannot be vectorized efficiently. Just don’t forget to copy it back to Bohrium after you are finished, e.g. like so:
from veros import runtime_settings as rs if rs.backend == "bohrium": u_np = vs.u.copy2numpy() else: u_np = vs.u vs.u[...] = np.asarray(external_function(u_np))
If you are still having trouble, don’t hesitate to ask for help (e.g. on GitHub).
Running Veros on a cluster¶
This tutorial walks you through some of the most common challenges that are specific to large, shared architectures like clusters and supercomputers. In case you are still having trouble setting up or running Veros on a large architecture after reading it, you should first contact the administrator of your cluster. Otherwise, you should of course feel free to open an issue.
Installation¶
Probably the easiest way to install Veros on a cluster is to, once again, use Anaconda. Since it is mostly platform independent and does not require elevated permissions, Anaconda is the perfect way to try out Veros without too much hassle.
If you are an administrator and want to make Veros accessible to multiple users on your cluster, we recommend that you do not install Veros system-wide, since it severely limits the possibilities of the users: First of all, they won’t be able to install additional Python modules they might want to use for post-processing or development. And second of all, the source code (and playing with it) is supposed to be a critical part of the Veros experience. Instead, you could e.g. use virtualenv to create a lightweight Python environment for every user that they can freely manage.
Usage¶
If you want to run Veros on a shared computing architecture, there are several issues that require special handling:
Preventing timeouts: In cloud computing, it is common that scheduling constraints limit the maximum execution time of a given process. Processes that exceed this time are killed. To prevent that long-running processes have to be restarted manually after each timeout, one usually makes use of a resubmit mechanism: The long-running process is split into chunks that each finish before a timeout is triggered, with subsequent runs starting from the restart files that the previous process has written.
Allocation of resources: Most applications use MPI to distribute work across processors; however, this is not supported by Bohrium. We therefore need to make sure that just one single process on a single node is started for our simulation (Bohrium will then divide the workload among different threads using OpenMP).
To solve these issues, the scheduling manager needs to be told exactly how it should run our model, which is usually being done by writing a batch script that prepares the environment and states which resources to request. The exact set-up of such a script will vary depending on the scheduling manager running on your cluster, and how exactly you chose to install Veros and Bohrium. One possible way to write such a batch script for the scheduling manager SLURM is presented here:
#!/bin/bash -l
#
#SBATCH -p mycluster
#SBATCH -A myaccount
#SBATCH --job-name=veros_mysetup
#SBATCH --nodes=2
#SBATCH --ntasks=16
#SBATCH --cpus-per-task=4
#SBATCH --exclusive
#SBATCH --mail-type=ALL
#SBATCH --mail-user=your@email.xyz
# load module dependencies
module load bohrium
# only needed if not found automatically
export BH_CONFIG=/path/to/bohrium/config.ini
# if needed, you can modify the internal Bohrium compiler flags
export BH_OPENMP_COMPILER_FLG="-x c -fPIC -shared -std=gnu99 -O3 -Werror -fopenmp"
# set number of threads to cpus-per-task
export OMP_NUM_THREADS=4
# adapt srun command to your available scheduler / MPI implementation
veros resubmit -i my_run -n 8 -l 7776000 \
-c "srun --mpi=pmi2 -- python my_setup.py -b bohrium -v debug -n 4 4" \
--callback "sbatch veros_batch.sh"
which is saved as veros_batch.sh
in the model setup folder and called using sbatch
.
This script makes use of the veros resubmit command and its --callback
option to create a script that automatically re-runs itself in a new process after each successful run (see also Command line tools). Upon execution, a job is created on one node, using 16 processors in one process, that runs the Veros setup located in my_setup.py
a total of eight times for 90 days (7776000 seconds) each, with identifier my_run
. Note that the --callback "sbatch veros_batch.sh"
part of the command is needed to actually create a new job after every run, to prevent the script from being killed after a timeout.
Setup gallery¶
This page gives an overview of the available model setups. To copy the setup file and additional input files (if applicable) to the current working directory, you can make use of the veros copy-setup command.
Example:
$ veros copy-setup acc
Idealized configurations¶
ACC channel model¶
-
class
veros.setup.acc.
ACCSetup
(state=None, override=None)[source]¶ Bases:
veros.veros.VerosSetup
A model using spherical coordinates with a partially closed domain representing the Atlantic and ACC.
Wind forcing over the channel part and buoyancy relaxation drive a large-scale meridional overturning circulation.
- This setup demonstrates:
setting up an idealized geometry
updating surface forcings
basic usage of diagnostics
ACC sector model¶
-
class
veros.setup.acc_sector.
ACCSectorSetup
(state=None, override=None)[source]¶ Bases:
veros.veros.VerosSetup
A model using spherical coordinates with a partially closed domain representing the narrow sector of Atlantic and ACC.
The bathymetry of the model is idealized to a flat-bottom (with depth of 4000 m) over the majority of the domain, except a half depth appended within the confines of the circumpolar channel at the inflow and outflow regions. The horizontal grid has resolution of \(2 \times 2\) degrees, and the vertical one has 40 levels.
Wind forcing over the sector part and buoyancy relaxation drive a large-scale meridional overturning circulation.
- This setup demonstrates:
setting up an idealized geometry after (Munday et al., 2013).
modifing surface forcings over selected regions of the domain
sensitivity of circumpolar transport and meridional overturning to changes in Southern Ocean wind stress and buoyancy anomalies
basic usage of diagnostics
Realistic configurations¶
Global flexible resolution setup¶
Wave propagation study¶
Global four-degree model¶
-
class
veros.setup.global_4deg.
GlobalFourDegreeSetup
(state=None, override=None)[source]¶ Bases:
veros.veros.VerosSetup
Global 4 degree model with 15 vertical levels.
- This setup demonstrates:
setting up a realistic model
reading input data from external files
implementing surface forcings
applying a simple ice mask
Global one-degree model¶
North Atlantic regional model¶
-
class
veros.setup.north_atlantic.
NorthAtlanticSetup
(state=None, override=None)[source]¶ Bases:
veros.veros.VerosSetup
A regional model of the North Atlantic, inspired by Smith et al., 2000.
Forcing and initial conditions are taken from the FLAME PyOM2 setup. Bathymetry data from ETOPO1 (resolution of 1 arcmin).
Boundary forcings are implemented via sponge layers in the Greenland Sea, by the Strait of Gibraltar, and in the South Atlantic. This setup runs with arbitrary resolution; upon changing the number of grid cells, all forcing files will be interpolated to the new grid. Default resolution corresponds roughly to \(0.5 \times 0.25\) degrees.
Configurations with BioGeoChemistry¶
Available model settings¶
The following list of available settings is automatically created from the file settings.py
in the Veros main folder.
They are available as attributes of all instances of the Veros state class
, e.g.:
>>> simulation = MyVerosSetup()
>>> vs = simulation.state
>>> print(vs.eq_of_state_type)
1
-
identifier = UNNAMED
Identifier of the current simulation
-
nx = 0
Grid points in zonal (x) direction
-
ny = 0
Grid points in meridional (y,j) direction
-
nz = 0
Grid points in vertical (z,k) direction
-
dt_mom = 0.0
Time step in seconds for momentum
-
dt_tracer = 0.0
Time step for tracers, can be larger than dt_mom
-
dt_bio = 0
Time step for npzd, must be smaller than dt_mom
-
runlen = 0.0
Length of simulation in seconds
-
AB_eps = 0.1
Deviation from Adam-Bashforth weighting
-
coord_degree = False
either spherical (True) or cartesian (False) coordinates
-
enable_cyclic_x = False
enable cyclic boundary conditions
-
eq_of_state_type = 1
equation of state: 1: linear, 3: nonlinear with comp., 5: TEOS
-
enable_implicit_vert_friction = False
enable implicit vertical friction
-
enable_explicit_vert_friction = False
enable explicit vertical friction
-
enable_hor_friction = False
enable horizontal friction
-
enable_hor_diffusion = False
enable horizontal diffusion
-
enable_biharmonic_friction = False
enable biharmonic horizontal friction
-
enable_biharmonic_mixing = False
enable biharmonic horizontal mixing
-
enable_hor_friction_cos_scaling = False
scaling of hor. viscosity with cos(latitude)**cosPower
-
enable_ray_friction = False
enable Rayleigh damping
-
enable_bottom_friction = False
enable bottom friction
-
enable_bottom_friction_var = False
enable bottom friction with lateral variations
-
enable_quadratic_bottom_friction = False
enable quadratic bottom friction
-
enable_tempsalt_sources = False
enable restoring zones, etc
-
enable_momentum_sources = False
enable restoring zones, etc
-
enable_superbee_advection = False
enable advection scheme with implicit mixing
-
enable_conserve_energy = True
exchange energy consistently
-
enable_store_bottom_friction_tke = False
transfer dissipated energy by bottom/rayleig fric. to TKE, else transfer to internal waves
-
enable_store_cabbeling_heat = False
transfer non-linear mixing terms to potential enthalpy, else transfer to TKE and EKE
-
enable_noslip_lateral = False
enable lateral no-slip boundary conditions in harmonic- and biharmonic friction.
-
congr_epsilon = 1e-12
convergence criteria for Poisson solver
-
congr_max_iterations = 1000
maximum number of Poisson solver iterations
-
A_h = 0.0
lateral viscosity in m^2/s
-
K_h = 0.0
lateral diffusivity in m^2/s
-
r_ray = 0.0
Rayleigh damping coefficient in 1/s
-
r_bot = 0.0
bottom friction coefficient in 1/s
-
r_quad_bot = 0.0
qudratic bottom friction coefficient
-
hor_friction_cosPower = 3
-
A_hbi = 0.0
lateral biharmonic viscosity in m^4/s
-
K_hbi = 0.0
lateral biharmonic diffusivity in m^4/s
-
kappaH_0 = 0.0
-
kappaM_0 = 0.0
fixed values for vertical viscosity/diffusivity which are set for no TKE model
-
enable_neutral_diffusion = False
enable isopycnal mixing
-
enable_skew_diffusion = False
enable skew diffusion approach for eddy-driven velocities
-
enable_TEM_friction = False
TEM approach for eddy-driven velocities
-
K_iso_0 = 0.0
constant for isopycnal diffusivity in m^2/s
-
K_iso_steep = 0.0
lateral diffusivity for steep slopes in m^2/s
-
K_gm_0 = 0.0
fixed value for K_gm which is set for no EKE model
-
iso_dslope = 0.0008
parameters controlling max allowed isopycnal slopes
-
iso_slopec = 0.001
parameters controlling max allowed isopycnal slopes
-
enable_idemix = False
-
tau_v = 172800.0
time scale for vertical symmetrisation
-
tau_h = 1296000.0
time scale for horizontal symmetrisation
-
gamma = 1.57
-
jstar = 5.0
spectral bandwidth in modes
-
mu0 = 0.3333333333333333
dissipation parameter
-
enable_idemix_hor_diffusion = False
-
enable_eke_diss_bottom = False
-
enable_eke_diss_surfbot = False
-
eke_diss_surfbot_frac = 1.0
fraction which goes into bottom
-
enable_idemix_superbee_advection = False
-
enable_idemix_upwind_advection = False
-
enable_tke = False
-
c_k = 0.1
-
c_eps = 0.7
-
alpha_tke = 1.0
-
mxl_min = 1e-12
-
kappaM_min = 0.0
-
kappaM_max = 100.0
-
tke_mxl_choice = 1
-
enable_tke_superbee_advection = False
-
enable_tke_upwind_advection = False
-
enable_tke_hor_diffusion = False
-
K_h_tke = 2000.0
lateral diffusivity for tke
-
enable_eke = False
-
eke_lmin = 100.0
minimal length scale in m
-
eke_c_k = 1.0
-
eke_cross = 1.0
Parameter for EKE model
-
eke_crhin = 1.0
Parameter for EKE model
-
eke_c_eps = 1.0
Parameter for EKE model
-
eke_k_max = 10000.0
maximum of K_gm
-
alpha_eke = 1.0
factor vertical friction
-
enable_eke_superbee_advection = False
-
enable_eke_upwind_advection = False
-
enable_eke_isopycnal_diffusion = False
use K_gm also for isopycnal diffusivity
-
enable_eke_leewave_dissipation = False
-
c_lee0 = 1.0
-
eke_Ri0 = 200.0
-
eke_Ri1 = 50.0
-
eke_int_diss0 = 5.787037037037037e-07
-
kappa_EKE0 = 0.1
-
eke_r_bot = 0.0
bottom friction coefficient
-
eke_hrms_k0_min = 0.0
min value for bottom roughness parameter
-
kappaH_min = 0.0
minimum value for vertical diffusivity
-
enable_kappaH_profile = False
Compute vertical profile of diffusivity after Bryan and Lewis (1979) in TKE routine
-
enable_Prandtl_tke = True
Compute Prandtl number from stratification levels in TKE routine
-
Prandtl_tke0 = 10.0
Constant Prandtl number when stratification is neglected for kappaH computation in TKE routine
-
use_io_threads = False
Start extra threads for disk writes
-
io_timeout = 20
Timeout in seconds while waiting for IO locks to be released
-
enable_netcdf_zlib_compression = True
Use netCDF4’s native zlib interface, which leads to smaller output files (but carries some computational overhead).
-
enable_hdf5_gzip_compression = True
Use h5py’s native gzip interface, which leads to smaller restart files (but carries some computational overhead).
-
restart_input_filename =
File name of restart input. If not given, no restart data will be read.
-
restart_output_filename = {identifier}_{itt:0>4d}.restart.h5
File name of restart output. May contain Python format syntax that is substituted with Veros attributes.
-
restart_frequency = 0
Frequency (in seconds) to write restart data
-
force_overwrite = False
Overwrite existing output files
-
pyom_compatibility_mode = False
Force compatibility to pyOM2 (even reproducing bugs and other quirks). For testing purposes only.
-
diskless_mode = False
Suppress all output to disk. Mainly used for testing purposes.
-
default_float_type = float64
Default type to use for floating point arrays (e.g.
float32
orfloat64
).
-
enable_npzd = False
-
recycled = {}
Amount of recycled material [mmol/m^3] for NPZD tracers
-
mortality = {}
Amount of dead plankton [mmol/m^3] by species
-
net_primary_production = {}
Primary production for each producing plankton species
-
plankton_growth_functions = {}
Collection of functions calculating growth for plankton by species
-
limiting_functions = {}
Collection of functions calculating limits to growth for plankton by species
-
npzd_tracers = {}
Dictionary whose values point to veros variables for npzd tracers
-
npzd_rules = []
List of active rules in primary loop of BGC
-
npzd_pre_rules = []
List of rules to executed in the pre loop of BGC
-
npzd_post_rules = []
Rules to be executed after primary bio loop
-
npzd_available_rules = {}
Every rule created is stored here, can be individual rules or collections of rules
-
npzd_selected_rule_names = []
name of selected rules
-
npzd_export = {}
Exported material from npzd tracers by sinking
-
npzd_import = {}
Imported material from npzd tracers from layer above. Takes same value as npzd_export scaled by level differences. Sea surface is 0
-
zprefs = {}
Preference for zooplankton to graze on named tracers
-
npzd_transported_tracers = []
List of NPZD tracers which are transported
-
npzd_advection_derivatives = {}
Stores derivates of advection term for tracers
-
temporary_tracers = {}
Temporary copy of npzd_tracers for biogeochemistry loop
-
light_attenuation_phytoplankton = 0.047
Light attenuation of phytoplankton
-
light_attenuation_water = 0.04
Light attenuation of water [1/m]
-
light_attenuation_ice = 5.0
Light attenuation of ice [1/m]
-
remineralization_rate_detritus = 0
Remineralization rate of detritus [1/sec]
-
bbio = 0
the b in b ** (c*T)
-
cbio = 0
the c in b ** (c*T)
-
maximum_growth_rate_phyto = 0.0
Maximum growth rate parameter for phytoplankton in [1/sec]
-
maximum_grazing_rate = 0
Maximum grazing rate at 0 deg C [1/sec]
-
fast_recycling_rate_phytoplankton = 0
Fast-recycling mortality rate of phytoplankton [1/sec]
-
saturation_constant_N = 0.7
Half saturation constant for N uptate [mmol N / m^3]
-
saturation_constant_Z_grazing = 0.15
Half saturation constant for Z grazing [mmol/m^3]
-
specific_mortality_phytoplankton = 0
Specific mortality rate of phytoplankton
-
quadric_mortality_zooplankton = 0
Quadric mortality rate of zooplankton [1/ (mmol N ^2 s)]
-
assimilation_efficiency = 0
Effiency with which ingested prey is converted growth in zooplankton, range: [0,1]
-
zooplankton_growth_efficiency = 0
Zooplankton growth efficiency, range: [0,1]
-
wd0 = 0.0
Sinking speed of detritus at surface [m/s]
-
mwz = 1000
Depth below which sinking speed of detritus remains constant [m]
-
mw = 2.3148148148148148e-07
Increase in sinking speed with depth [1/sec]
-
zprefP = 1
Zooplankton preference for grazing on Phytoplankton
-
zprefZ = 1
Zooplankton preference for grazing on other zooplankton
-
zprefDet = 1
Zooplankton preference for grazing on detritus
-
redfield_ratio_PN = 0.0625
Refield ratio for P/N
-
redfield_ratio_CP = 113.6
Refield ratio for C/P
-
redfield_ratio_ON = 10.6
Redfield ratio for O/N
-
redfield_ratio_CN = 7.1
Redfield ratio for C/N
-
trcmin = 1e-13
Minimum npzd tracer value
-
u1_min = 1e-06
Minimum u1 value for calculating avg J
-
zooplankton_max_growth_temp = 20.0
Temperature (C) for which zooplankton growth rate no longer grows with temperature
-
capr = 0.022
Carbonate to carbon production ratio
Model variables¶
The variable meta-data (i.e., all instances of veros.variables.Variable
)
are available in a dictionary as the attribute Veros.variables
. The actual
data arrays are added directly as attributes to Veros
. The following code
snippet (as commonly used in the Diagnostics) illustrates this behavior:
var_meta = {key: val for key, val in vs.variables.items() if val.time_dependent and val.output}
var_data = {key: getattr(veros, key) for key in var_meta.keys()}
In this case, var_meta
is a dictionary containing all metadata for variables that
are time dependent and should be added to the output, while var_data
is a dictionary
with the same keys containing the corresponding data arrays.
Variable class¶
Available variables¶
There are two kinds of variables in Veros. Main variables are always present in a
simulation, while conditional variables are only available if their respective
condition is True
at the time of variable allocation.
- Attributes:
- : Time-dependent: Included in snapshot output by default: Written to restart files by default
Main variables¶
-
Veros.
dxt
¶ - Units
m
- Dimensions
xt
- Type
float
- Attributes
Zonal (x) spacing of T-grid point
-
Veros.
dxu
¶ - Units
m
- Dimensions
xu
- Type
float
- Attributes
Zonal (x) spacing of U-grid point
-
Veros.
dyt
¶ - Units
m
- Dimensions
yt
- Type
float
- Attributes
Meridional (y) spacing of T-grid point
-
Veros.
dyu
¶ - Units
m
- Dimensions
yu
- Type
float
- Attributes
Meridional (y) spacing of U-grid point
-
Veros.
zt
¶ - Units
m
- Dimensions
zt
- Type
float
- Attributes
Vertical coordinate
-
Veros.
zw
¶ - Units
m
- Dimensions
zw
- Type
float
- Attributes
Vertical coordinate
-
Veros.
dzt
¶ - Units
m
- Dimensions
zt
- Type
float
- Attributes
Vertical spacing
-
Veros.
dzw
¶ - Units
m
- Dimensions
zw
- Type
float
- Attributes
Vertical spacing
-
Veros.
cost
¶ - Units
1
- Dimensions
yt
- Type
float
- Attributes
Metric factor for spherical coordinates
-
Veros.
cosu
¶ - Units
1
- Dimensions
yu
- Type
float
- Attributes
Metric factor for spherical coordinates
-
Veros.
tantr
¶ - Units
1
- Dimensions
yt
- Type
float
- Attributes
Metric factor for spherical coordinates
-
Veros.
coriolis_t
¶ - Units
1/s
- Dimensions
xt, yt
- Type
float
- Attributes
Coriolis frequency at T grid point
-
Veros.
coriolis_h
¶ - Units
1/s
- Dimensions
xt, yt
- Type
float
- Attributes
Horizontal Coriolis frequency at T grid point
-
Veros.
kbot
¶ - Units
- Dimensions
xt, yt
- Type
int
- Attributes
Index of the deepest grid cell (counting from 1, 0 means all land)
-
Veros.
ht
¶ - Units
m
- Dimensions
xt, yt
- Type
float
- Attributes
Total depth of the water column
-
Veros.
hu
¶ - Units
m
- Dimensions
xu, yt
- Type
float
- Attributes
Total depth of the water column
-
Veros.
hv
¶ - Units
m
- Dimensions
xt, yu
- Type
float
- Attributes
Total depth of the water column
-
Veros.
hur
¶ - Units
m
- Dimensions
xu, yt
- Type
float
- Attributes
Total depth of the water column (masked)
-
Veros.
hvr
¶ - Units
m
- Dimensions
xt, yu
- Type
float
- Attributes
Total depth of the water column (masked)
-
Veros.
beta
¶ - Units
1/(ms)
- Dimensions
xt, yt
- Type
float
- Attributes
Change of Coriolis frequency with latitude
-
Veros.
area_t
¶ - Units
m^2
- Dimensions
xt, yt
- Type
float
- Attributes
Area of T-box
-
Veros.
area_u
¶ - Units
m^2
- Dimensions
xu, yt
- Type
float
- Attributes
Area of U-box
-
Veros.
area_v
¶ - Units
m^2
- Dimensions
xt, yu
- Type
float
- Attributes
Area of V-box
-
Veros.
maskT
¶ - Units
- Dimensions
xt, yt, zt
- Type
int8
- Attributes
Mask in physical space for tracer points
-
Veros.
maskU
¶ - Units
- Dimensions
xu, yt, zt
- Type
int8
- Attributes
Mask in physical space for U points
-
Veros.
maskV
¶ - Units
- Dimensions
xt, yu, zt
- Type
int8
- Attributes
Mask in physical space for V points
-
Veros.
maskW
¶ - Units
- Dimensions
xt, yt, zw
- Type
int8
- Attributes
Mask in physical space for W points
-
Veros.
maskZ
¶ - Units
- Dimensions
xu, yu, zt
- Type
int8
- Attributes
Mask in physical space for Zeta points
-
Veros.
rho
¶ - Units
kg/m^3
- Dimensions
xt, yt, zt, timesteps
- Type
float
- Attributes
In-situ density anomaly, relative to the surface mean value of 1024 kg/m^3
-
Veros.
prho
¶ - Units
kg/m^3
- Dimensions
xt, yt, zt
- Type
float
- Attributes
Potential density anomaly, relative to the surface mean value of 1024 kg/m^3 (equal to in-situ density anomaly for equation of state 1 to 4)
-
Veros.
int_drhodT
¶ - Units
?
- Dimensions
xt, yt, zt, timesteps
- Type
float
- Attributes
Partial derivative of dynamic enthalpy by temperature
-
Veros.
int_drhodS
¶ - Units
?
- Dimensions
xt, yt, zt, timesteps
- Type
float
- Attributes
Partial derivative of dynamic enthalpy by salinity
-
Veros.
Nsqr
¶ - Units
1/s^2
- Dimensions
xt, yt, zw, timesteps
- Type
float
- Attributes
Square of stability frequency
-
Veros.
Hd
¶ - Units
m^2/s^2
- Dimensions
xt, yt, zt, timesteps
- Type
float
- Attributes
Dynamic enthalpy
-
Veros.
dHd
¶ - Units
m^2/s^3
- Dimensions
xt, yt, zt, timesteps
- Type
float
- Attributes
Change of dynamic enthalpy due to advection
-
Veros.
temp
¶ - Units
deg C
- Dimensions
xt, yt, zt, timesteps
- Type
float
- Attributes
Conservative temperature
-
Veros.
dtemp
¶ - Units
deg C/s
- Dimensions
xt, yt, zt, timesteps
- Type
float
- Attributes
Conservative temperature tendency
-
Veros.
salt
¶ - Units
g/kg
- Dimensions
xt, yt, zt, timesteps
- Type
float
- Attributes
Salinity
-
Veros.
dsalt
¶ - Units
g/(kg s)
- Dimensions
xt, yt, zt, timesteps
- Type
float
- Attributes
Salinity tendency
-
Veros.
dtemp_vmix
¶ - Units
deg C/s
- Dimensions
xt, yt, zt
- Type
float
- Attributes
Change of temperature due to vertical mixing
-
Veros.
dtemp_hmix
¶ - Units
deg C/s
- Dimensions
xt, yt, zt
- Type
float
- Attributes
Change of temperature due to horizontal mixing
-
Veros.
dsalt_vmix
¶ - Units
deg C/s
- Dimensions
xt, yt, zt
- Type
float
- Attributes
Change of salinity due to vertical mixing
-
Veros.
dsalt_hmix
¶ - Units
deg C/s
- Dimensions
xt, yt, zt
- Type
float
- Attributes
Change of salinity due to horizontal mixing
-
Veros.
dtemp_iso
¶ - Units
deg C/s
- Dimensions
xt, yt, zt
- Type
float
- Attributes
Change of temperature due to isopycnal mixing plus skew mixing
-
Veros.
dsalt_iso
¶ - Units
deg C/s
- Dimensions
xt, yt, zt
- Type
float
- Attributes
Change of salinity due to isopycnal mixing plus skew mixing
-
Veros.
forc_temp_surface
¶ - Units
m K/s
- Dimensions
xt, yt
- Type
float
- Attributes
Surface temperature flux
-
Veros.
forc_salt_surface
¶ - Units
m g/s kg
- Dimensions
xt, yt
- Type
float
- Attributes
Surface salinity flux
-
Veros.
flux_east
¶ - Units
?
- Dimensions
xu, yt, zt
- Type
float
- Attributes
Multi-purpose flux
-
Veros.
flux_north
¶ - Units
?
- Dimensions
xt, yu, zt
- Type
float
- Attributes
Multi-purpose flux
-
Veros.
flux_top
¶ - Units
?
- Dimensions
xt, yt, zw
- Type
float
- Attributes
Multi-purpose flux
-
Veros.
u
¶ - Units
m/s
- Dimensions
xu, yt, zt, timesteps
- Type
float
- Attributes
Zonal velocity
-
Veros.
v
¶ - Units
m/s
- Dimensions
xt, yu, zt, timesteps
- Type
float
- Attributes
Meridional velocity
-
Veros.
w
¶ - Units
m/s
- Dimensions
xt, yt, zw, timesteps
- Type
float
- Attributes
Vertical velocity
-
Veros.
du
¶ - Units
m/s
- Dimensions
xu, yt, zt, timesteps
- Type
float
- Attributes
Zonal velocity tendency
-
Veros.
dv
¶ - Units
m/s
- Dimensions
xt, yu, zt, timesteps
- Type
float
- Attributes
Meridional velocity tendency
-
Veros.
du_cor
¶ - Units
m/s^2
- Dimensions
xu, yt, zt
- Type
float
- Attributes
Change of u due to Coriolis force
-
Veros.
dv_cor
¶ - Units
m/s^2
- Dimensions
xt, yu, zt
- Type
float
- Attributes
Change of v due to Coriolis force
-
Veros.
du_mix
¶ - Units
m/s^2
- Dimensions
xu, yt, zt
- Type
float
- Attributes
Change of u due to implicit vertical mixing
-
Veros.
dv_mix
¶ - Units
m/s^2
- Dimensions
xt, yu, zt
- Type
float
- Attributes
Change of v due to implicit vertical mixing
-
Veros.
du_adv
¶ - Units
m/s^2
- Dimensions
xu, yt, zt
- Type
float
- Attributes
Change of u due to advection
-
Veros.
dv_adv
¶ - Units
m/s^2
- Dimensions
xt, yu, zt
- Type
float
- Attributes
Change of v due to advection
-
Veros.
p_hydro
¶ - Units
m^2/s^2
- Dimensions
xt, yt, zt
- Type
float
- Attributes
Hydrostatic pressure
-
Veros.
kappaM
¶ - Units
m^2/s
- Dimensions
xt, yt, zt
- Type
float
- Attributes
Vertical viscosity
-
Veros.
kappaH
¶ - Units
m^2/s
- Dimensions
xt, yt, zw
- Type
float
- Attributes
Vertical diffusivity
-
Veros.
surface_taux
¶ - Units
N/s^2
- Dimensions
xu, yt
- Type
float
- Attributes
Zonal surface wind stress
-
Veros.
surface_tauy
¶ - Units
N/s^2
- Dimensions
xt, yu
- Type
float
- Attributes
Meridional surface wind stress
-
Veros.
forc_rho_surface
¶ - Units
?
- Dimensions
xt, yt
- Type
float
- Attributes
Surface potential density flux
-
Veros.
psi
¶ - Units
m^3/s
- Dimensions
xu, yu, timesteps
- Type
float
- Attributes
Barotropic streamfunction
-
Veros.
dpsi
¶ - Units
m^3/s^2
- Dimensions
xu, yu, timesteps
- Type
float
- Attributes
Streamfunction tendency
-
Veros.
land_map
¶ - Units
- Dimensions
xt, yt
- Type
float
- Attributes
Land map
-
Veros.
isle
¶ - Units
- Dimensions
isle
- Type
float
- Attributes
Island number
-
Veros.
psin
¶ - Units
m^3/s
- Dimensions
xu, yu, isle
- Type
float
- Attributes
Boundary streamfunction
-
Veros.
dpsin
¶ - Units
?
- Dimensions
isle, timesteps
- Type
float
- Attributes
Boundary streamfunction factor
-
Veros.
line_psin
¶ - Units
?
- Dimensions
isle, isle
- Type
float
- Attributes
Boundary line integrals
-
Veros.
boundary_mask
¶ - Units
- Dimensions
xt, yt, isle
- Type
float
- Attributes
Boundary mask
-
Veros.
line_dir_south_mask
¶ - Units
- Dimensions
xt, yt, isle
- Type
float
- Attributes
Line integral mask
-
Veros.
line_dir_north_mask
¶ - Units
- Dimensions
xt, yt, isle
- Type
float
- Attributes
Line integral mask
-
Veros.
line_dir_east_mask
¶ - Units
- Dimensions
xt, yt, isle
- Type
float
- Attributes
Line integral mask
-
Veros.
line_dir_west_mask
¶ - Units
- Dimensions
xt, yt, isle
- Type
float
- Attributes
Line integral mask
-
Veros.
K_gm
¶ - Units
m^2/s
- Dimensions
xt, yt, zw
- Type
float
- Attributes
GM diffusivity, either constant or from EKE model
-
Veros.
K_iso
¶ - Units
m^2/s
- Dimensions
xt, yt, zw
- Type
float
- Attributes
Along-isopycnal diffusivity
-
Veros.
K_diss_v
¶ - Units
m^2/s^3
- Dimensions
xt, yt, zw
- Type
float
- Attributes
Kinetic energy dissipation by vertical, rayleigh and bottom friction
-
Veros.
K_diss_bot
¶ - Units
m^2/s^3
- Dimensions
xt, yt, zw
- Type
float
- Attributes
Mean energy dissipation by bottom and rayleigh friction
-
Veros.
K_diss_h
¶ - Units
m^2/s^3
- Dimensions
xt, yt, zw
- Type
float
- Attributes
Kinetic energy dissipation by horizontal friction
-
Veros.
K_diss_gm
¶ - Units
m^2/s^3
- Dimensions
xt, yt, zw
- Type
float
- Attributes
Mean energy dissipation by GM (TRM formalism only)
-
Veros.
P_diss_v
¶ - Units
m^2/s^3
- Dimensions
xt, yt, zw
- Type
float
- Attributes
Potential energy dissipation by vertical diffusion
-
Veros.
P_diss_nonlin
¶ - Units
m^2/s^3
- Dimensions
xt, yt, zw
- Type
float
- Attributes
Potential energy dissipation by nonlinear equation of state
-
Veros.
P_diss_iso
¶ - Units
m^2/s^3
- Dimensions
xt, yt, zw
- Type
float
- Attributes
Potential energy dissipation by isopycnal mixing
-
Veros.
P_diss_skew
¶ - Units
m^2/s^3
- Dimensions
xt, yt, zw
- Type
float
- Attributes
Potential energy dissipation by GM (w/o TRM)
-
Veros.
P_diss_hmix
¶ - Units
m^2/s^3
- Dimensions
xt, yt, zw
- Type
float
- Attributes
Potential energy dissipation by horizontal mixing
-
Veros.
P_diss_adv
¶ - Units
m^2/s^3
- Dimensions
xt, yt, zw
- Type
float
- Attributes
Potential energy dissipation by advection
-
Veros.
P_diss_comp
¶ - Units
m^2/s^3
- Dimensions
xt, yt, zw
- Type
float
- Attributes
Potential energy dissipation by compression
-
Veros.
P_diss_sources
¶ - Units
m^2/s^3
- Dimensions
xt, yt, zw
- Type
float
- Attributes
Potential energy dissipation by external sources (e.g. restoring zones)
-
Veros.
u_wgrid
¶ - Units
m/s
- Dimensions
xt, yt, zw
- Type
float
- Attributes
Zonal velocity interpolated to W grid points
-
Veros.
v_wgrid
¶ - Units
m/s
- Dimensions
xt, yt, zw
- Type
float
- Attributes
Meridional velocity interpolated to W grid points
-
Veros.
w_wgrid
¶ - Units
m/s
- Dimensions
xt, yt, zw
- Type
float
- Attributes
Vertical velocity interpolated to W grid points
Conditional variables¶
coord_degree¶
-
Veros.
xt
¶ - Units
degrees_east
- Dimensions
xt
- Type
float
- Attributes
Zonal (x) coordinate of T-grid point
-
Veros.
xu
¶ - Units
degrees_east
- Dimensions
xu
- Type
float
- Attributes
Zonal (x) coordinate of U-grid point
-
Veros.
yt
¶ - Units
degrees_north
- Dimensions
yt
- Type
float
- Attributes
Meridional (y) coordinate of T-grid point
-
Veros.
yu
¶ - Units
degrees_north
- Dimensions
yu
- Type
float
- Attributes
Meridional (y) coordinate of U-grid point
not coord_degree¶
-
Veros.
xt
- Units
km
- Dimensions
xt
- Type
float
- Attributes
Zonal (x) coordinate of T-grid point
-
Veros.
xu
- Units
km
- Dimensions
xu
- Type
float
- Attributes
Zonal (x) coordinate of U-grid point
-
Veros.
yt
- Units
km
- Dimensions
yt
- Type
float
- Attributes
Meridional (y) coordinate of T-grid point
-
Veros.
yu
- Units
km
- Dimensions
yu
- Type
float
- Attributes
Meridional (y) coordinate of U-grid point
enable_tempsalt_sources¶
-
Veros.
temp_source
¶ - Units
K/s
- Dimensions
xt, yt, zt
- Type
float
- Attributes
Non-conservative source of temperature
-
Veros.
salt_source
¶ - Units
g/(kg s)
- Dimensions
xt, yt, zt
- Type
float
- Attributes
Non-conservative source of salt
enable_momentum_sources¶
-
Veros.
u_source
¶ - Units
m/s^2 (?)
- Dimensions
xu, yt, zt
- Type
float
- Attributes
Non-conservative source of zonal velocity
-
Veros.
v_source
¶ - Units
m/s^2 (?)
- Dimensions
xt, yu, zt
- Type
float
- Attributes
Non-conservative source of meridional velocity
enable_neutral_diffusion¶
-
Veros.
K_11
¶ - Units
?
- Dimensions
xt, yt, zt
- Type
float
- Attributes
Isopycnal mixing tensor component
-
Veros.
K_13
¶ - Units
?
- Dimensions
xt, yt, zt
- Type
float
- Attributes
Isopycnal mixing tensor component
-
Veros.
K_22
¶ - Units
?
- Dimensions
xt, yt, zt
- Type
float
- Attributes
Isopycnal mixing tensor component
-
Veros.
K_23
¶ - Units
?
- Dimensions
xt, yt, zt
- Type
float
- Attributes
Isopycnal mixing tensor component
-
Veros.
K_31
¶ - Units
?
- Dimensions
xt, yt, zt
- Type
float
- Attributes
Isopycnal mixing tensor component
-
Veros.
K_32
¶ - Units
?
- Dimensions
xt, yt, zt
- Type
float
- Attributes
Isopycnal mixing tensor component
-
Veros.
K_33
¶ - Units
?
- Dimensions
xt, yt, zt
- Type
float
- Attributes
Isopycnal mixing tensor component
-
Veros.
Ai_ez
¶ - Units
?
- Dimensions
xt, yt, zt, tensor1, tensor2
- Type
float
- Attributes
?
-
Veros.
Ai_nz
¶ - Units
?
- Dimensions
xt, yt, zt, tensor1, tensor2
- Type
float
- Attributes
?
-
Veros.
Ai_bx
¶ - Units
?
- Dimensions
xt, yt, zt, tensor1, tensor2
- Type
float
- Attributes
?
-
Veros.
Ai_by
¶ - Units
?
- Dimensions
xt, yt, zt, tensor1, tensor2
- Type
float
- Attributes
?
enable_skew_diffusion¶
-
Veros.
B1_gm
¶ - Units
m^2/s
- Dimensions
xt, yu, zt
- Type
float
- Attributes
Zonal component of GM streamfunction
-
Veros.
B2_gm
¶ - Units
m^2/s
- Dimensions
xu, yt, zt
- Type
float
- Attributes
Meridional component of GM streamfunction
enable_bottom_friction_var¶
-
Veros.
r_bot_var_u
¶ - Units
?
- Dimensions
xu, yt
- Type
float
- Attributes
Zonal bottom friction coefficient
-
Veros.
r_bot_var_v
¶ - Units
?
- Dimensions
xt, yu
- Type
float
- Attributes
Meridional bottom friction coefficient
enable_TEM_friction¶
-
Veros.
kappa_gm
¶ - Units
m^2/s
- Dimensions
xt, yt, zw
- Type
float
- Attributes
Vertical diffusivity
enable_tke¶
-
Veros.
tke
¶ - Units
m^2/s^2
- Dimensions
xt, yt, zw, timesteps
- Type
float
- Attributes
Turbulent kinetic energy
-
Veros.
sqrttke
¶ - Units
m/s
- Dimensions
xt, yt, zw
- Type
float
- Attributes
Square-root of TKE
-
Veros.
dtke
¶ - Units
m^2/s^3
- Dimensions
xt, yt, zw, timesteps
- Type
float
- Attributes
Turbulent kinetic energy tendency
-
Veros.
Prandtlnumber
¶ - Units
- Dimensions
xt, yt, zw
- Type
float
- Attributes
Prandtl number
-
Veros.
mxl
¶ - Units
m
- Dimensions
xt, yt, zw
- Type
float
- Attributes
Mixing length
-
Veros.
forc_tke_surface
¶ - Units
m^3/s^3
- Dimensions
xt, yt
- Type
float
- Attributes
TKE surface flux
-
Veros.
tke_diss
¶ - Units
m^2/s^3
- Dimensions
xt, yt, zw
- Type
float
- Attributes
TKE dissipation
-
Veros.
tke_surf_corr
¶ - Units
m^3/s^3
- Dimensions
xt, yt
- Type
float
- Attributes
Correction of TKE surface flux
enable_eke¶
-
Veros.
eke
¶ - Units
m^2/s^2
- Dimensions
xt, yt, zw, timesteps
- Type
float
- Attributes
meso-scale energy
-
Veros.
deke
¶ - Units
m^2/s^3
- Dimensions
xt, yt, zw, timesteps
- Type
float
- Attributes
meso-scale energy tendency
-
Veros.
sqrteke
¶ - Units
m/s
- Dimensions
xt, yt, zw
- Type
float
- Attributes
square-root of eke
-
Veros.
L_rossby
¶ - Units
m
- Dimensions
xt, yt
- Type
float
- Attributes
Rossby radius
-
Veros.
L_rhines
¶ - Units
m
- Dimensions
xt, yt, zw
- Type
float
- Attributes
Rhines scale
-
Veros.
eke_len
¶ - Units
m
- Dimensions
xt, yt, zt
- Type
float
- Attributes
Eddy length scale
-
Veros.
eke_diss_iw
¶ - Units
m^2/s^3
- Dimensions
xt, yt, zw
- Type
float
- Attributes
Dissipation of EKE to internal waves
-
Veros.
eke_diss_tke
¶ - Units
m^2/s^3
- Dimensions
xt, yt, zw
- Type
float
- Attributes
Dissipation of EKE to TKE
-
Veros.
eke_bot_flux
¶ - Units
m^3/s^3
- Dimensions
xt, yt
- Type
float
- Attributes
Flux by bottom friction
enable_eke_leewave_dissipation¶
-
Veros.
eke_topo_hrms
¶ - Units
?
- Dimensions
xt, yt
- Type
float
- Attributes
?
-
Veros.
eke_topo_lam
¶ - Units
?
- Dimensions
xt, yt
- Type
float
- Attributes
?
-
Veros.
hrms_k0
¶ - Units
?
- Dimensions
xt, yt
- Type
float
- Attributes
?
-
Veros.
c_lee
¶ - Units
1/s
- Dimensions
xt, yt
- Type
float
- Attributes
Lee wave dissipation coefficient
-
Veros.
eke_lee_flux
¶ - Units
m^3/s^3
- Dimensions
xt, yt
- Type
float
- Attributes
Lee wave flux
-
Veros.
c_Ri_diss
¶ - Units
1/s
- Dimensions
xt, yt, zw
- Type
float
- Attributes
Interior dissipation coefficient
enable_idemix¶
-
Veros.
E_iw
¶ - Units
m^2/s^2
- Dimensions
xt, yt, zw, timesteps
- Type
float
- Attributes
Internal wave energy
-
Veros.
dE_iw
¶ - Units
m^2/s^2
- Dimensions
xt, yt, zw, timesteps
- Type
float
- Attributes
Internal wave energy tendency
-
Veros.
c0
¶ - Units
m/s
- Dimensions
xt, yt, zw
- Type
float
- Attributes
Vertical internal wave group velocity
-
Veros.
v0
¶ - Units
m/s
- Dimensions
xt, yt, zw
- Type
float
- Attributes
Horizontal internal wave group velocity
-
Veros.
alpha_c
¶ - Units
?
- Dimensions
xt, yt, zw
- Type
float
- Attributes
?
-
Veros.
iw_diss
¶ - Units
m^2/s^3
- Dimensions
xt, yt, zw
- Type
float
- Attributes
Internal wave dissipation
-
Veros.
forc_iw_surface
¶ - Units
m^3/s^3
- Dimensions
xt, yt
- Type
float
- Attributes
Internal wave surface forcing
-
Veros.
forc_iw_bottom
¶ - Units
m^3/s^3
- Dimensions
xt, yt
- Type
float
- Attributes
Internal wave bottom forcing
enable_npzd¶
-
Veros.
bottom_mask
¶ - Units
- Dimensions
xt, yt, zt
- Type
int8
- Attributes
Bottom mask
-
Veros.
phytoplankton
¶ - Units
mmol/m^3?
- Dimensions
xt, yt, zt, timesteps
- Type
float
- Attributes
Concentration of phytoplankton in grid box
-
Veros.
zooplankton
¶ - Units
mmol/m^3?
- Dimensions
xt, yt, zt, timesteps
- Type
float
- Attributes
Concentration of zooplankton in grid box
-
Veros.
detritus
¶ - Units
mmol/m^3?
- Dimensions
xt, yt, zt, timesteps
- Type
float
- Attributes
Concentration of detritus in grid box
-
Veros.
po4
¶ - Units
mmol/m^3?
- Dimensions
xt, yt, zt, timesteps
- Type
float
- Attributes
Concentration of phosphate in grid box
-
Veros.
swr
¶ - Units
W/m^3?
- Dimensions
xt, yt
- Type
float
- Attributes
Incomming solar radiation at sea level
-
Veros.
rctheta
¶ - Units
1
- Dimensions
yt
- Type
float
- Attributes
Effective vertical coordinate for incoming solar radiation
-
Veros.
dayfrac
¶ - Units
1
- Dimensions
yt
- Type
float
- Attributes
Fraction of day with sunlight
-
Veros.
excretion_total
¶ - Units
mmol/m^3 / s
- Dimensions
xt, yt, zt
- Type
float
- Attributes
Zooplankton grazing causes excretion. This stores the total excreted amount for all consumed tracers
enable_carbon¶
-
Veros.
dic
¶ - Units
mmol/m^3
- Dimensions
xt, yt, zt, timesteps
- Type
float
- Attributes
Concentration of inorganic carbon ions and molecule
-
Veros.
alkalinity
¶ - Units
mmol/m^3
- Dimensions
xt, yt, zt, timesteps
- Type
float
- Attributes
Combined bases and acids
-
Veros.
atmospheric_co2
¶ - Units
ppmv
- Dimensions
xt, yt
- Type
float
- Attributes
Atmospheric co2 concentration
-
Veros.
cflux
¶ - Units
mmol/m^3/s
- Dimensions
xt, yt
- Type
float
- Attributes
Flux of CO2 over the ocean-atmosphere bounday
-
Veros.
wind_speed
¶ - Units
m/s
- Dimensions
xt, yt
- Type
float
- Attributes
Just used for debugging. Please ignore
-
Veros.
hSWS
¶ - Units
1
- Dimensions
xt, yt
- Type
float
- Attributes
[H] in Sea water sample
-
Veros.
pCO2
¶ - Units
?ppmv/atm?
- Dimensions
xt, yt
- Type
float
- Attributes
Partial CO2 pressure
-
Veros.
dpCO2
¶ - Units
?ppmv/atm?
- Dimensions
xt, yt
- Type
float
- Attributes
Difference in ocean CO2 pressure and atmospheric
-
Veros.
co2star
¶ - Units
?ppmv?
- Dimensions
xt, yt
- Type
float
- Attributes
Adjusted CO2 in ocean
-
Veros.
dco2star
¶ - Units
?ppmv?
- Dimensions
xt, yt
- Type
float
- Attributes
Adjusted CO2 difference
-
Veros.
rcak
¶ - Units
1
- Dimensions
xt, yt, zt
- Type
float
- Attributes
Calcite is redistributed after production by dissolution varying by depth
Diagnostics¶
Diagnostics are separate objects (instances of subclasses of VerosDiagnostic
)
responsible for handling I/O, restart mechanics, and monitoring of the numerical
solution. All available diagnostics are instantiated and added to a dictionary
attribute VerosState.diagnostics
(with a key determined by their name attribute).
Options for diagnostics may be set during the VerosSetup.set_diagnostics()
method:
class MyModelSetup(VerosSetup):
...
def set_diagnostics(self, vs):
vs.diagnostics['averages'].output_variables = ['psi','u','v']
vs.diagnostics['averages'].sampling_frequency = 3600.
vs.diagnostics['snapshot'].output_variables += ['du']
Base class¶
This class implements some common logic for all diagnostics. This makes it easy to write your own diagnostics: Just derive from this class, and implement the virtual functions.
-
class
veros.diagnostics.diagnostic.
VerosDiagnostic
(vs)[source]¶ Bases:
object
Base class for diagnostics. Provides an interface and wrappers for common I/O.
Any diagnostic needs to implement the five interface methods and set some attributes.
-
name
= None¶ Name that identifies the current diagnostic
-
initialize
(vs)¶ Called at the end of setup. Use this to process user settings and handle setup.
-
diagnose
(vs)¶ Called with frequency
sampling_frequency
.
-
output
(vs)¶ Called with frequency
output_frequency
.
-
write_restart
(vs)¶ Responsible for writing restart files.
-
read_restart
(vs)¶ Responsible for reading restart files.
-
Available diagnostics¶
Currently, the following diagnostics are implemented and added to
VerosState.diagnostics
:
Snapshot¶
-
class
veros.diagnostics.snapshot.
Snapshot
(vs)[source]¶ Bases:
veros.diagnostics.diagnostic.VerosDiagnostic
Writes snapshots of the current solution. Also reads and writes the main restart data required for restarting a Veros simulation.
-
output_path
= '{identifier}.snapshot.nc'¶ File to write to. May contain format strings that are replaced with Veros attributes.
-
name
= 'snapshot'¶
-
output_frequency
= None¶ Frequency (in seconds) in which output is written.
-
output_variables
= None¶ Variables to be written to output. Defaults to all Veros variables that have the attribute
output
.
-
restart_variables
= None¶ Variables to be written to restart. Defaults to all Veros variables that have the attribute
write_to_restart
.
-
Averages¶
-
class
veros.diagnostics.averages.
Averages
(vs)[source]¶ Bases:
veros.diagnostics.diagnostic.VerosDiagnostic
Time average output diagnostic.
All registered variables are summed up when
diagnose()
is called, and averaged and output upon callingoutput()
.-
name
= 'averages'¶
-
output_path
= '{identifier}.averages.nc'¶ File to write to. May contain format strings that are replaced with Veros attributes.
-
output_variables
= None¶ Iterable containing all variables to be averaged. Changes have no effect after
initialize
has been called.
-
output_frequency
= None¶ Frequency (in seconds) in which output is written.
-
sampling_frequency
= None¶ Frequency (in seconds) in which variables are accumulated.
-
CFL monitor¶
-
class
veros.diagnostics.cfl_monitor.
CFLMonitor
(vs)[source]¶ Bases:
veros.diagnostics.diagnostic.VerosDiagnostic
Diagnostic monitoring the maximum CFL number of the solution to detect instabilities.
Writes output to stdout (no binary output).
-
name
= 'cfl_monitor'¶
-
Tracer monitor¶
-
class
veros.diagnostics.tracer_monitor.
TracerMonitor
(vs)[source]¶ Bases:
veros.diagnostics.diagnostic.VerosDiagnostic
Diagnostic monitoring global tracer contents / fluxes.
Writes output to stdout (no binary output).
-
name
= 'tracer_monitor'¶
-
output_frequency
= None¶ Frequency (in seconds) in which output is written.
-
Energy¶
-
class
veros.diagnostics.energy.
Energy
(vs)[source]¶ Bases:
veros.diagnostics.diagnostic.VerosDiagnostic
Diagnose globally averaged energy cycle. Also averages energy in time.
-
name
= 'energy'¶
-
output_path
= '{identifier}.energy.nc'¶ File to write to. May contain format strings that are replaced with Veros attributes.
-
output_frequency
= None¶ Frequency (in seconds) in which output is written.
-
sampling_frequency
= None¶ Frequency (in seconds) in which variables are accumulated.
-
Overturning¶
-
class
veros.diagnostics.overturning.
Overturning
(vs)[source]¶ Bases:
veros.diagnostics.diagnostic.VerosDiagnostic
Isopycnal overturning diagnostic. Computes and writes vertical streamfunctions (zonally averaged).
-
name
= 'overturning'¶
-
output_path
= '{identifier}.overturning.nc'¶ File to write to. May contain format strings that are replaced with Veros attributes.
-
output_frequency
= None¶ Frequency (in seconds) in which output is written.
-
sampling_frequency
= None¶ Frequency (in seconds) in which variables are accumulated.
-
p_ref
= 2000.0¶ Reference pressure for isopycnals
-
Biogeochemistry¶
This module monitors total phosphate and produces interaction graphs for the biogeochemistry module
-
class
veros.diagnostics.npzd.
NPZDMonitor
(setup)[source]¶ Bases:
veros.diagnostics.diagnostic.VerosDiagnostic
Diagnostic monitoring nutrients and plankton concentrations
-
name
= 'npzd'¶
-
output_frequency
= None¶ Frequency (in seconds) in which output is written
-
save_graph
= False¶ Whether or not to save a graph of the selected dynamics
-
Biogeochemistry¶
The biogeochemistry module for Veros is designed for allowing construction of user defined ecosystems.
Base systems are made available for a basic Nutrients-Plankton-Zooplankton-Detritus, NPZD, system,
which can optionally be extended by a basic carbon cycle. Enabling the biogeochemistry module and
activating the basic NPZD system can be done by setting enable_npzd = True
.
Ecosystems created with the biogeochemistry module are extensible and any components of them are in principle replaceable. This is handled by three principles: Representation of model tracers by classes, representation of interactions between tracers as rules, and separation of component creation from activation.
Tracer classes¶
All model tracers in the biogeochemistry module are created as instances of classes inheriting from a
base class NPZD_tracer
. This class itself inherits from numpy.ndarray, which allows using it
like any other Veros variable. The concentration (or appropriate unit) of the tracer within each cell
in Veros’ grid is stored in the corresponding cell in the tracer grid. The base class defines attributes
for operations which may apply to any tracer.
Instances of this class must be created with a numpy array backing the tracer values. Preferably this
array was created in variables.py. Additionally a name must be supplied. This name will uniquely
identify the tracer during simulation. Optional arguments may be supplied:
transport
By default this value is True. When transport
is true, the tracer is transported
according to the selected transportation scheme. Setting a value for for sinking_speed
will cause
the tracer to be included in calculations of sinking tracers. And setting light_attenuation
will
block downward shortwave radiation proportionally to the concentration of the tracer.
This class may itself be used for tracers, which should not express any further features such
as the nutrients phosphate.
NPZD_tracer(vs.po4, 'po4')
Tracers which should express actionable features such as grazing, primary production must implement
certain methods. Methods to implement are mortality
for mortality, recycle
for recycling,
potential_growth
for primary production. In addition to this methods should be supplied a list
of functions representing limiting in growth by nutrients. grazing
for grazing. This method
should return dictionaries for grazing, digestion, excretion, and sloppy feeding. Where the keys
are names of the tracers, which have been grazed upon.
It is possible to add additional actionable methods by editing npzd.py.
Predefined tracers¶
A number of classes for tracers have been predefined. These classes can be instantiated with different parameters to defined tracers with varying properties. For example creating tracers for coccolithophores and phytoplankton can be done like
coccolithophores = Phytoplankton(np.zeros((3,vs.nx, vs.ny, vs.nz)), 'coccolithophores',
light_attenuation=1,
growth_parameter=0.9,
recycling_rate=0.8,
mortality_rate=0.7)
phytoplankton = Phytoplankton(vs.phytoplankton, 'phytoplankton',
light_attenuation=vs.light_attenuation_phytoplankton,
growth_parameter=vs.maximum_growth_rate_phyto,
recycling_rate=vs.fast_recycling_rate_phytoplankton,
mortality_rate=vs.specific_mortality_phytoplankton)
Base tracer¶
-
class
veros.core.npzd_tracers.
NPZD_tracer
[source]¶ Bases:
numpy.ndarray
Class for npzd tracers to store additional information about themselves.
Note
Inhenrits from numpy.ndarray to make it work seamless with array operations
- Parameters
input_array (
numpy.ndarray
) – Numpy array backing dataname (
str
) – Identifier for the tracer, which must be unique within a given configurationsinking_speed (
numpy.ndarray
, optional) – Numpy array for how fast the tracer sinks in each celltransport (
bool
= True, optional) – Whether or not to include the tracer in physical transportlight_attenuation (
numpy.ndarray
, optional) – Factor for how much light is blocked
-
name
¶ Identifier for the tracer, which must be unique within a given configuration
-
description
¶ Description of the tracer represented by the class
-
transport
¶ Whether or not to include the tracer in physical transport
-
sinking_speed
¶ If set: how fast the tracer sinks in each cell
- Type
numpy.ndarray
, optional
-
light_attenuation
¶ If set: Factor for how much light is blocked
- Type
numpy.ndarray
, optional
Recyclable tracer¶
-
class
veros.core.npzd_tracers.
Recyclable_tracer
[source]¶ Bases:
veros.core.npzd_tracers.NPZD_tracer
A recyclable tracer
This would be tracer, which may be a tracer like detritus, which can be recycled
- Parameters
input_array (
numpy.ndarray
) – Numpy array backing dataname (
str
) – Identifier for the tracer, which must be unique within a given configurationrecycling_rate – A factor scaling the recycling by the population size
**kwargs – All named parameters accepted by super class
-
recycling_rate
¶ A factor scaling the recycling by the population size
-
+ All attributes held by super class
Plankton¶
-
class
veros.core.npzd_tracers.
Plankton
[source]¶ Bases:
veros.core.npzd_tracers.Recyclable_tracer
Class for plankton object, which is both recyclable and displays mortality
This class is intended as a base for phytoplankton and zooplankton and not as a standalone class
Note
Typically, it would desirable to also set light attenuation
- Parameters
input_array (
numpy.ndarray
) – Numpy array backing dataname (
str
) – Identifier for the tracer, which must be unique within a given configurationmortality_rate – Rate at which the tracer is dying in mortality method
**kwargs – All named parameters accepted by super class
-
mortality_rate
¶ Rate at which the tracer is dying in mortality method
-
+ All attributes held by super class
Phytoplankton¶
-
class
veros.core.npzd_tracers.
Phytoplankton
[source]¶ Bases:
veros.core.npzd_tracers.Plankton
Phytoplankton also has primary production
- Parameters
input_array (
numpy.ndarray
) – Numpy array backing dataname (
str
) – Identifier for the tracer, which must be unique within a given configurationgrowth_parameter – Scaling factor for maximum potential growth
**kwargs – All named parameters accepted by super class
-
growth_parameter
¶ Scaling factor for maximum potential growth
-
+ All attributes held by super class
Zooplankton¶
-
class
veros.core.npzd_tracers.
Zooplankton
[source]¶ Bases:
veros.core.npzd_tracers.Plankton
Zooplankton displays quadratic mortality rate but otherwise is similar to ordinary phytoplankton
- Parameters
input_array (
numpy.ndarray
) – Numpy array backing dataname (
str
) – Identifier for the tracer, which must be unique within a given configurationmax_grazing – Scaling factor for maximum grazing rate
grazing_saturation_constant – Saturation in Michaelis-Menten
grazing_preferences – Dictionary of preferences for grazing on other tracers
assimilation_efficiency – Fraction of grazed material ingested
growth_efficiency – Fraction of ingested material resulting in growth
maximum_growth_temperature (= 20) – Temperature in Celsius where increasing temperature no longer increases grazing
**kwargs – All named parameters accepted by super class
-
max_grazing
¶ Scaling factor for maximum grazing rate
-
grazing_saturation_constant
¶ Saturation in Michaelis-Menten
-
grazing_preferences
¶ Dictionary of preferences for grazing on other tracers
-
assimilation_efficiency
¶ Fraction of grazed material ingested
-
growth_efficiency
¶ Fraction of ingested material resulting in growth
-
maximum_growth_temperature
¶ Temperature in Celsius where increasing temperature no longer increases grazing
-
+ All attributes held by super class
Extending tracers¶
The biogeochemistry tracers make use of the object oriented nature of Python to allow easy extensibility.
Tracers which exhibit nearly identical behavior can be created via extension. For example the
Zooplankton
class overrides the mortality function defined by the Plankton
class
class Zooplankton(Plankton):
# ...
@veros_method(inline=True)
def mortality(self, vs):
"""
Zooplankton mortality is modelled with a quadratic mortality rate
"""
return self.mortality_rate * self ** 2
By using this approach you only have to focus on the differences between tracers.
Rules¶
Creating your tracers as objects does not in itself add any time evolution to the system. You must also specify the interaction between the tracers. This is done by creating rules. A rule specifies the flow from one tracer to another. An ecosystem can be defined as a collection of rules each specifying part of the flow between tracers.
Rules consist of a function describing the interaction, the name of the source tracer and the name of the sink tracer. The function itself may be used in several rules. The rule function has access to any variable stored in the Veros object. This includes results of the methods described in the previous section. An example rule could look like
@veros_method(inline=True)
def recycling_to_po4(vs, source, sink):
return {source: -vs.recycled[source], sink: vs.redfield_ratio_PN * vs.recycled[source]}
The function returns a dictionary. The keys of the dictionary must be names of the tracers, which are affected by the rule. The values are numpy arrays corresponding to the change in the tracer. The return dictionary is not strictly required to contain two keys. If a rule only represents part of an interaction, just one key can be included. Any number of entries in the dictionary will be processed, but a rule is intended to represent a flow between two tracers. The rule should then be registered with the names of the source and sink to make it available for use in Veros.
register_npzd_rule(vs, 'recycle_phytoplankton_to_po4', (recycling_to_po4, 'phytoplankton', 'po4'))
The rule is registered with the Veros object as the first argument followed by a unique name for the rule and a tuple consisting of the rule function, the name of the source, and the name of the sink. Those two names will be passed as arguments to the function. The rule name is used for selecting the rule for activation. The tuple may also be replaced by a list containing names of other rules. This collection of rules may later be activated using just the name the list was registered with.
Optional arguments¶
Rules can also be registered with optional arguments.
The label
argument specifies a displayed
name which is shown in the graph generated by the biogeochemistry diagnostics.
boundary
may take 3 values. ‘SURFACE’, ‘BOTTOM’ or None (default). If ‘SURFACE’ the rule only applies
to the top layer of the grid. ‘BOTTOM’ means the rule only applies to the cells immediately above the
bottom. None means the rule applies to the entire grid.
group
specifies in which of three execution locations the rule will be applied. The ‘PRIMARY’
group is the default group. Rules in this group will be evaluated several times in a loop. The number
of times specified by the ratio between vs.dt_tracer
and vs.dt_bio
. The result of the
rule will be time stepped and added to the tracer concentrations. The ‘PRE’ group is evaluated once
per tracer time step before the ‘PRIMARY’ loop. The results of these rules are not time stepped before
adding to the result to the relevant tracers. The ‘POST’ group is evaluated once before the ‘PRIMARY’
rules. Time stepping is left out of ‘PRE’ and ‘POST’ rules in order to allow them to clean up or
reuse results from other rules.
Difference between rules and tracer classes¶
The difference between rules and classes and their methods is, that the tracer objects themselves do not modify tracer concentrations. Only the rules should influence the time evolution of the tracers. The results of the methods may be used in rules.
Activation¶
In order to use the created classes and rules. They must be activated. Tracers are activated by register_npzd_data. Rules are activated by adding their names to npzd_selected_rules for example.
detritus = Recyclable_tracer(vs.detritus, 'detritus',
sinking_speed=dtr_speed,
recycling_rate=vs.remineralization_rate_detritus)
register_npzd_data(vs, detritus)
This adds a tracer with the name ‘detritus’ to the model which sinks and a recycling method.
Rules which have been registered with register_npzd_rule are activated by selecting them with select_npzd_rule. select_npzd_rule accepts rule names. If the name represents a collection of rules, each rule in the collection is activated.
# activate the npzd_basic_phytoplankton_grazing rule
select_npzd_rule(vs, 'npzd_basic_phytoplankton_grazing')
# a list of rules, which have been registered with a single name
# may be activated collectively from that name
register_npzd_rule(vs, 'group_npzd_basic', [
'npzd_basic_phytoplankton_grazing',
'npzd_basic_phytoplankton_mortality',
'npzd_basic_phytoplankton_fast_recycling',
'npzd_basic_phytoplankton_primary_production',
'npzd_basic_zooplankton_grazing',
'npzd_basic_zooplankton_mortality',
'npzd_basic_zooplankton_sloppy_feeding',
'npzd_basic_detritus_remineralization',
'npzd_basic_detritus_grazing',
'npzd_basic_detritus_bottom_remineralization'
])
select_npzd_rule(vs, 'group_npzd_basic') # This activates all the rules in the collection
The example setup file for biogeochemistry demonstrates how a configuration file can be used to activate rules.
Command line tools¶
After installing Veros, you can call these scripts from the command line from any location on your system.
veros¶
This is a wrapper script that provides easy access to all Veros command line tools.
Usage: veros [OPTIONS] COMMAND [ARGS]...
Veros command-line tools
Options:
--version Show the version and exit.
--help Show this message and exit.
Commands:
copy-setup Copy a standard setup to another directory
create-mask Creates a mask image from a given netCDF file
resubmit Re-run a Veros setup several times
veros-create-mask¶
Usage: veros create-mask [OPTIONS] INFILE
Creates a mask image from a given netCDF file
Options:
-v, --variable TEXT Variable holding topography data (default: z)
-o, --outfile TEXT Output filename (default: topography.png)
-s, --scale INTEGER... Standard deviation in grid cells for Gaussian
smoother (default: disable smoother)
--help Show this message and exit.
veros-copy-setup¶
Usage: veros copy-setup [OPTIONS] SETUP
Copy a standard setup to another directory
Options:
--to PATH Target directory (default: copy to current working directory)
--help Show this message and exit.
veros-resubmit¶
Usage: veros resubmit [OPTIONS]
Performs several runs of Veros back to back, using the previous run as
restart input.
Intended to be used with scheduling systems (e.g. SLURM or PBS).
Options:
-i, --identifier TEXT Base identifier of the simulation [required]
-n, --num-runs INTEGER Total number of runs to execute [required]
-l, --length-per-run FLOAT Length (in seconds) of each run [required]
-c, --veros-cmd COMMAND The command that is used to call veros (quoted)
[required]
--callback CMD Command to call after each run has finished
(quoted, default: call self)
--help Show this message and exit.
Python API¶
Veros setup class¶
-
class
veros.
VerosSetup
(state=None, override=None)[source]¶ Bases:
object
Main class for Veros, used for building a model and running it.
Note
This class is meant to be subclassed. Subclasses need to implement the methods
set_parameter()
,set_topography()
,set_grid()
,set_coriolis()
,set_initial_conditions()
,set_forcing()
, andset_diagnostics()
.- Parameters
backend (
bool
, optional) – Backend to use for array operations. Possible values arenumpy
andbohrium
. Defaults toNone
, which tries to read the backend from the command line (set via a flag-b
/--backend
), and usesnumpy
if no command line argument is given.loglevel (one of {debug, info, warning, error, critical}, optional) – Verbosity of the model. Tries to read value from command line if not given (
-v
/--loglevel
). Defaults toinfo
.
Example
>>> import matplotlib.pyplot as plt >>> from veros import VerosSetup >>> >>> class MyModel(VerosSetup): >>> ... >>> >>> simulation = MyModel(backend='bohrium') >>> simulation.run() >>> plt.imshow(simulation.state.psi[..., 0]) >>> plt.show()
-
set_parameter
(vs)[source]¶ To be implemented by subclass.
First function to be called during setup. Use this to modify the model settings.
Example
>>> def set_parameter(self, vs): >>> vs.nx, vs.ny, vs.nz = (360, 120, 50) >>> vs.coord_degree = True >>> vs.enable_cyclic = True
-
set_initial_conditions
(vs)[source]¶ To be implemented by subclass.
May be used to set initial conditions.
Example
>>> @veros_method >>> def set_initial_conditions(self, vs): >>> vs.u[:, :, :, vs.tau] = np.random.rand(vs.u.shape[:-1])
-
set_grid
(vs)[source]¶ To be implemented by subclass.
Has to set the grid spacings
dxt
,dyt
, anddzt
, along with the coordinates of the grid origin,x_origin
andy_origin
.Example
>>> @veros_method >>> def set_grid(self, vs): >>> vs.x_origin, vs.y_origin = 0, 0 >>> vs.dxt[...] = [0.1, 0.05, 0.025, 0.025, 0.05, 0.1] >>> vs.dyt[...] = 1. >>> vs.dzt[...] = [10, 10, 20, 50, 100, 200]
-
set_coriolis
(vs)[source]¶ To be implemented by subclass.
Has to set the Coriolis parameter
coriolis_t
at T grid cells.Example
>>> @veros_method >>> def set_coriolis(self, vs): >>> vs.coriolis_t[:, :] = 2 * vs.omega * np.sin(vs.yt[np.newaxis, :] / 180. * vs.pi)
-
set_topography
(vs)[source]¶ To be implemented by subclass.
Must specify the model topography by setting
kbot
.Example
>>> @veros_method >>> def set_topography(self, vs): >>> vs.kbot[:, :] = 10 >>> # add a rectangular island somewhere inside the domain >>> vs.kbot[10:20, 10:20] = 0
-
set_forcing
(vs)[source]¶ To be implemented by subclass.
Called before every time step to update the external forcing, e.g. through
forc_temp_surface
,forc_salt_surface
,surface_taux
,surface_tauy
,forc_tke_surface
,temp_source
, orsalt_source
. Use this method to implement time-dependent forcing.Example
>>> @veros_method >>> def set_forcing(self, vs): >>> current_month = (vs.time / (31 * 24 * 60 * 60)) % 12 >>> vs.surface_taux[:, :] = vs._windstress_data[:, :, current_month]
-
set_diagnostics
(vs)[source]¶ To be implemented by subclass.
Called before setting up the diagnostics. Use this method e.g. to mark additional variables for output.
Example
>>> @veros_method >>> def set_diagnostics(self, vs): >>> vs.diagnostics['snapshot'].output_vars += ['drho', 'dsalt', 'dtemp']
-
after_timestep
(vs)[source]¶ Called at the end of each time step. Can be used to define custom, setup-specific events.
-
run
(show_progress_bar=None)[source]¶ Main routine of the simulation.
Note
Make sure to call
setup()
prior to this function.- Parameters
show_progress_bar (
bool
, optional) – Whether to show fancy progress bar via tqdm. By default, only show if stdout is a terminal and Veros is running on a single process.
Veros state class¶
veros_method decorator¶
-
veros.
veros_method
(function=None, **kwargs)[source]¶ Decorator that injects the current backend as variable
np
into the wrapped function.Note
This decorator should be applied to all functions that make use of the computational backend (even when subclassing
veros.Veros
). The first argument to the decorated function must be a Veros instance.Example
>>> from veros import Veros, veros_method >>> >>> class MyModel(Veros): >>> @veros_method >>> def set_topography(self): >>> self.kbot[...] = np.random.randint(0, self.nz, size=self.kbot.shape)
Runtime settings & state¶
Tools & utilities¶
Assets¶
-
veros.tools.assets.
get_assets
(asset_id, asset_file)[source]¶ Handles automatic download and verification of external assets (such as forcing files).
By default, assets are stored in
$HOME/.veros/assets
(can be overwritten by settingVEROS_ASSET_DIR
environment variable to the desired location).- Parameters
asset_id (str) – Identifier of the collection of assets. Should be unique for each setup.
asset_file (str) – YAML file containing URLs and (optionally) MD5 hashsums of each asset.
- Returns
A
dict
mapping identifier of each asset to file name on disk.
Example
>>> get_assets('mysetup', 'assets.yml') { "forcing": "/home/user/.veros/assets/mysetup/mysetup_forcing.h5", "initial_conditions": "/home/user/.veros/assets/mysetup/initial.h5" }
In this case,
assets.yml
contains:forcing: url: https://mywebsite.com/veros_assets/mysetup_forcing.h5 md5: ef3be0a58782771c8ee5a6d0206b87f6 initial_conditions: url: https://mywebsite.com/veros_assets/initial.h5 md5: d1b4e0e199d7a5883cf7c88d3d6bcb28
CLI¶
-
veros.tools.cli.
cli
(run)[source]¶ Decorator that wraps the decorated function with the Veros setup command line interface.
Example
>>> @veros.tools.cli.cli() >>> def run_setup(override): ... sim = MyVerosSetup(override=override) ... sim.run() ... >>> if __name__ == '__main__': ... run_setup()
This script then automatically supports settings to be specified from the command line:
$ python my_setup.py --help Usage: my_setup.py [OPTIONS] Options: -b, --backend [numpy|bohrium] Backend to use for computations (default: numpy) -v, --loglevel [trace|debug|info|warning|error|critical] Log level used for output (default: info) -s, --override SETTING VALUE Override default setting, may be specified multiple times -p, --profile-mode Write a performance profile for debugging (default: false) -n, --num-proc INTEGER... Number of processes in x and y dimension (requires execution via mpirun) --help Show this message and exit.
Setup tools¶
-
veros.tools.setup.
interpolate
(coords, var, interp_coords, missing_value=None, fill=True, kind='linear')[source]¶ Interpolate globally defined data to a different (regular) grid.
- Parameters
coords – Tuple of coordinate arrays for each dimension.
var (
ndarray
of dim (nx1, …, nxd)) – Variable data to interpolate.interp_coords – Tuple of coordinate arrays to interpolate to.
missing_value (optional) – Value denoting cells of missing data in
var
. Is replaced by NaN before interpolating. Defaults to None, which means no replacement is taking place.fill (bool, optional) – Whether NaN values should be replaced by the nearest finite value after interpolating. Defaults to
True
.kind (str, optional) – Order of interpolation. Supported are nearest and linear (default).
- Returns
ndarray
containing the interpolated values on the grid spanned byinterp_coords
.
-
veros.tools.setup.
fill_holes
(data)[source]¶ A simple inpainting function that replaces NaN values in data with the nearest finite value.
-
veros.tools.setup.
get_periodic_interval
(current_time, cycle_length, rec_spacing, n_rec)[source]¶ Used for linear interpolation between periodic time intervals.
One common application is the interpolation of external forcings that are defined at discrete times (e.g. one value per month of a standard year) to the current time step.
- Parameters
current_time (float) – Time to interpolate to.
cycle_length (float) – Total length of one periodic cycle.
rec_spacing (float) – Time spacing between each data record.
n_rec (int) – Total number of records available.
- Returns
Indices and weights for the interpolated record array.
- Return type
tuple
containing (n1, f1), (n2, f2)
Example
The following interpolates a record array
data
containing 12 monthly values to the current time step:>>> year_in_seconds = 60. * 60. * 24. * 365. >>> current_time = 60. * 60. * 24. * 45. # mid-february >>> print(data.shape) (360, 180, 12) >>> (n1, f1), (n2, f2) = get_periodic_interval(current_time, year_in_seconds, year_in_seconds / 12, 12) >>> data_at_current_time = f1 * data[..., n1] + f2 * data[..., n2]
-
veros.tools.setup.
make_cyclic
(longitude, array=None, wrap=360.0)[source]¶ Create a cyclic version of a longitude array and (optionally) another array.
- Parameters
longitude (ndarray) – Longitude array of shape (nlon, …).
array (ndarray) – Another array that is to be made cyclic of shape (nlon, …).
wrap (float) – Wrapping value, defaults to 360 (degrees).
- Returns
Tuple containing (cyclic_longitudes, cyclic_array) if array is given, otherwise just the ndarray cyclic_longitudes of shape (2 * nlon, …).
-
veros.tools.setup.
get_coastline_distance
(coords, coast_mask, spherical=False, radius=None, num_candidates=None, n_jobs=-1)[source]¶ Calculate the (approximate) distance of each water cell from the nearest coastline.
- Parameters
coords (tuple of ndarrays) – Tuple containing x and y (longitude and latitude) coordinate arrays of shape (nx, ny).
coast_mask (ndarray) – Boolean mask indicating whether a cell is a land cell (must be same shape as coordinate arrays).
spherical (bool) – Use spherical instead of Cartesian coordinates. When this is True, cyclical boundary conditions are used, and the resulting distances are only approximate. Cells are pre-sorted by Euclidean lon-lat distance, and great circle distances are calculated for the first num_candidates elements. Defaults to False.
radius (float) – Radius of spherical coordinate system. Must be given when spherical is True.
num_candidates (int) – Number of candidates to calculate great circle distances for for each water cell. The higher this value, the more accurate the returned distances become when spherical is True. Defaults to the square root of the number of coastal cells.
n_jobs (int) – Number of parallel jobs to determine nearest neighbors (defaults to -1, which uses all available threads).
- Returns
ndarray
of shape (nx, ny) indicating the distance to the nearest land cell (0 if cell is land).
Example
The following returns coastal distances of all T cells for a spherical Veros setup.
>>> coords = np.meshgrid(self.xt[2:-2], self.yt[2:-2], indexing='ij') >>> dist = tools.get_coastline_distance(coords, self.kbot > 0, spherical=True, radius=self.radius)
-
veros.tools.setup.
get_uniform_grid_steps
(total_length, stepsize)[source]¶ Get uniform grid step sizes in an interval.
- Parameters
total_length (float) – total length of the resulting grid
stepsize (float) – grid step size
- Returns
ndarray
of grid steps
Example
>>> uniform_steps = uniform_grid_setup(6., 0.25) >>> uniform_steps [ 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25 ]
-
veros.tools.setup.
get_stretched_grid_steps
(n_cells, total_length, minimum_stepsize, stretching_factor=2.5, two_sided_grid=False, refine_towards='upper')[source]¶ Computes stretched grid steps for regional and global domains with either one or two-sided stretching using a hyperbolic tangent stretching function.
- Parameters
n_cells (int) – Number of grid points.
total_length (float) – Length of the grid interval to be covered (sum of the resulting grid steps).
minimum_stepsize (float) – Grid step size on the lower end of the interval.
stretching_factor (float, optional) – Coefficient of the tanh stretching function. The higher this value, the more abrupt the step sizes change.
two_sided_grid (bool, optional) – If set to True, the resulting grid will be symmetrical around the center. Defaults to False.
refine_towards ('upper' or 'lower', optional) – The side of the interval that is to be refined. Defaults to ‘upper’.
- Returns
ndarray
of shape (n_cells) containing grid steps.
Examples
>>> dyt = get_stretched_grid_steps(14, 180, 5) >>> dyt [ 5.10517337 5.22522948 5.47813251 5.99673813 7.00386752 8.76808565 11.36450896 14.34977676 16.94620006 18.71041819 19.71754758 20.2361532 20.48905624 20.60911234] >>> dyt.sum() 180.0
>>> dyt = get_stretched_grid_steps(14, 180, 5, stretching_factor=4.) >>> dyt [ 5.00526979 5.01802837 5.06155549 5.20877528 5.69251688 7.14225176 10.51307232 15.20121339 18.57203395 20.02176884 20.50551044 20.65273022 20.69625734 20.70901593] >>> dyt.sum() 180.0
-
veros.tools.setup.
get_vinokur_grid_steps
(n_cells, total_length, lower_stepsize, upper_stepsize=None, two_sided_grid=False, refine_towards='upper')[source]¶ Computes stretched grid steps for regional and global domains with either one or two-sided stretching using Vinokur stretching.
This stretching function minimizes discretization errors on finite difference grids.
- Parameters
n_cells (int) – Number of grid points.
total_length (float) – Length of the grid interval to be covered (sum of the resulting grid steps).
lower_stepsize (float) – Grid step size on the lower end of the interval.
upper_stepsize (float or
None
, optional) – Grid step size on the upper end of the interval. If not given, the one-sided version of the algorithm is used (that enforces zero curvature on the upper end).two_sided_grid (bool, optional) – If set to True, the resulting grid will be symmetrical around the center. Defaults to False.
refine_towards ('upper' or 'lower', optional) – The side of the interval that is to be refined. Defaults to ‘upper’.
- Returns
ndarray
of shape (n_cells) containing grid steps.
- Reference:
Vinokur, Marcel, On One-Dimensional Stretching Functions for Finite-Difference Calculations, Journal of Computational Physics. 50, 215, 1983.
Examples
>>> dyt = get_vinokur_grid_steps(14, 180, 5, two_sided_grid=True) >>> dyt [ 18.2451554 17.23915939 15.43744632 13.17358802 10.78720589 8.53852027 6.57892471 6.57892471 8.53852027 10.78720589 13.17358802 15.43744632 17.23915939 18.2451554 ] >>> dyt.sum() 180.
>>> dyt = get_vinokur_grid_steps(14, 180, 5, upper_stepsize=10) >>> dyt [ 5.9818365 7.3645667 8.92544833 10.61326984 12.33841985 13.97292695 15.36197306 16.3485688 16.80714121 16.67536919 15.97141714 14.78881918 13.27136448 11.57887877 ] >>> dyt.sum() 180.
Numerical operators¶
Distributed communication primitives¶
Frequently asked questions¶
Which backend should I choose to run my model (NumPy / Bohrium)?¶
Because in its current state Bohrium carries some computational overhead, this mostly depends on your problem size and the architecture you want to use. As a rule of thumb, switching from NumPy to Bohrium is beneficial if your set-up contains at least 1,000,000 elements (total number of elements in a 3-dimensional array, i.e., \(n_x n_y n_z\)). You can also use our benchmarks for general orientation.
Benchmarks¶
Note
The following benchmarks are for general orientation only. Benchmark results are highly platform dependent; your mileage may vary.
Veros compared to PyOM2¶
The following figurew present some benchmarks that compare the performance of Veros and pyOM 2.1 depending on the problem size:
Veros runtime estimates on the DC3 cluster¶
The following figure presents estimates of Veros runtime required for 1 year prediction on CPU and GPU nodes of the DC3 cluster. The estimates were done for ACC, Wave propagation and Global cases with different spatial and temporal resolution.
For more details on the cases configuration see the setup gallery.
Runtime estimates on a cluster node with 32 CPU cores (Bh CPU) and on a cluster node with 24 CPU cores and an NVidia Tesla P100 GPU (Bh GPU).¶
Publications¶
Papers¶
Häfner, D., Jacobsen, R. L., Eden, C., Kristensen, M. R. B., Jochum, M., Nuterman, R., and Vinter, B.: Veros v0.1 – a fast and versatile ocean simulator in pure Python, Geosci. Model Dev., 11, 3299-3312, https://doi.org/10.5194/gmd-11-3299-2018, 2018.
Talks¶
Veros — A High-Performance Ocean Simulator Written in Pure Python. A talk held at the 98th Annual Meeting of the American Meteorological Society (AMS). Abstract and slides available.
A Fast Versatile Ocean Simulator (Veros) in Pure Python. A talk held at the European Geosciences Union General Assembly 2018, Vienna, Austria. Abstract
Contact¶
If you want to report a bug in Veros, have a technical inquiry, or want to ask for a missing feature, please use our issue tracker on GitHub.
In case you have general questions about Veros, please contact the maintainer of the Veros repository.