Transports Through Straits

Computing the depth-integrated volume transport through some major straits.

Theory

Formally, mass transports are given by

\[T_x = \rho u\]
\[T_y = \rho v\]

Mass transports are diagnostics that are calculated online by the model:

variable

long name

units

dimensions

tx_trans

T-cell i-mass transport

kg s⁻¹

(time, st_ocean, xu_ocean, yt_ocean)

ty_trans

T-cell j-mass transport

kg s⁻¹

(time, st_ocean, xt_ocean, yu_ocean)

Variable tx_trans contains the instantaneous zonal transport multiplied with \(y\)-\(z\) face of the volume of each cell:

tx_trans\(=T_{x}(x, y, z, t)\,\Delta y\,\Delta z\).

Similarly, ty_trans contains

ty_trans\(=T_{y}(x, y, z, t)\,\Delta x\,\Delta z\).

Thus, tx_trans and ty_trans variables come in units of

\[\underbrace{\mathrm{kg}\,\mathrm{m}^{-3}}_{\rm density} \times \underbrace{\mathrm{m}\,\mathrm{s}^{-1}}_{\rm velocity}\times\underbrace{\mathrm{m}^2}_{\rm area} = \mathrm{kg}\,\mathrm{s}^{-1}.\]

To get the volume transport (\(\mathrm{m}^3\,\mathrm{s}^{-1}\)) we have to divide by density \(\rho\).

Calculation

[1]:
%config InlineBackend.figure_format='retina'

import cosima_cookbook as cc
import cf_xarray as cfxr
import cf_xarray.units
import pint_xarray
from pint import application_registry as ureg
import matplotlib.pyplot as plt
from dask.distributed import Client
import logging

Load a dask client.

[2]:
client = Client()
client
[2]:

Client

Client-5c88e5d8-d1d6-11ee-9085-000007a7fe80

Connection method: Cluster object Cluster type: distributed.LocalCluster
Dashboard: /proxy/8787/status

Cluster Info

Use default database for this calculation

[3]:
session = cc.database.create_session()

Select an experiment.

[4]:
experiment = '025deg_jra55_iaf_omip2_cycle6'

This dictionary defines a few key choke points that you might be interested in. For the purposes of demonstration we are just using Drake Passage in this example.

[5]:
straits = {'Drake Passage': [ -69.9,  -69.9, -71.6, -51.0],
           'Lombok':        [-244.6, -243.9,  -8.6,  -8.6],
           'Ombai' :        [-235.0, -235.0,  -9.2,  -8.1],
           'Timor' :        [-235.9, -235.9, -11.9,  -9.9],
           'Denmark' :      [ -42.0,  -22.0,  65.8,  65.8],
           'Bering' :       [-172.0, -167.0,  65.8,  65.8],
           }

Here we define a function so that you can specify a given strait, and rely on the function to extract the transport through that strait.

The calc_transport will load 18 years of data by default but you can change that by providing different start_time and end_time keyword arguments, which are then passed onto cc.querying.getvar.

[6]:
ρ0 = 1036 * ureg.kilogram / ureg.meter**3 # reference density

def calc_transport(experiment, strait, start_time='2000-1-1', end_time='2018-1-1'):
    """
    Calculate barotropic transport across a given
    line of latitude or longitude.

    Designed for flow through straits.
    """

    xmin, xmax, ymin, ymax = straits[strait]

    if ymax >= 65:
        logging.warning('North of 65N the tripolar grid geometry brings complications and .sum(\'longitude\') is wrong!')

    print('Calculating {}: {} transport'.format(experiment, strait))

    if xmin == xmax:
        tx_trans = cc.querying.getvar(experiment, 'tx_trans', session, start_time=start_time, end_time=end_time, chunks={'time': 3})
        tx_trans = tx_trans.pint.quantify()

        transport = (tx_trans / ρ0).sel(time=slice(start_time, end_time))\
                                   .cf.sel(longitude=xmin, method='nearest')\
                                   .cf.sel(latitude=slice(ymin, ymax))\
                                   .cf.sum({'vertical', 'latitude'})
        transport.attrs['long_name'] = 'zonal transport'
    elif ymin == ymax:
        ty_trans = cc.querying.getvar(experiment, 'ty_trans', session, start_time=start_time, end_time=end_time, chunks={'time': 3})
        ty_trans = ty_trans.pint.quantify()

        transport = (ty_trans / ρ0).sel(time=slice(start_time, end_time))\
                                   .cf.sel(longitude=slice(xmin, xmax))\
                                   .cf.sel(latitude=ymin, method='nearest')\
                                   .cf.sum({'vertical', 'longitude'})
        transport.attrs['long_name'] = 'meridional transport'
    else:
        raise ValueError('Transports are computed only along lines of either constant latitude or constant longitude')

    transport = transport.pint.to('sverdrup')
    transport = transport.compute()

    return transport

Now, for a given experiment, calculate the total (barotropic) transport through Drake Passage:

[7]:
%%time

strait = 'Drake Passage'
transport = calc_transport(experiment, strait)
transport.plot()
plt.title(strait+' Transport');
Calculating 025deg_jra55_iaf_omip2_cycle6: Drake Passage transport
/g/data/hh5/public/apps/miniconda3/envs/analysis3-24.01/lib/python3.10/site-packages/xarray/core/dataset.py:271: UserWarning: The specified chunks separate the stored chunks along dimension "time" starting at index 3. This could degrade performance. Instead, consider rechunking after loading.
  warnings.warn(
/g/data/hh5/public/apps/miniconda3/envs/analysis3-24.01/lib/python3.10/site-packages/xarray/core/dataset.py:271: UserWarning: The specified chunks separate the stored chunks along dimension "time" starting at index 3. This could degrade performance. Instead, consider rechunking after loading.
  warnings.warn(
/g/data/hh5/public/apps/miniconda3/envs/analysis3-24.01/lib/python3.10/site-packages/xarray/core/dataset.py:271: UserWarning: The specified chunks separate the stored chunks along dimension "time" starting at index 3. This could degrade performance. Instead, consider rechunking after loading.
  warnings.warn(
/g/data/hh5/public/apps/miniconda3/envs/analysis3-24.01/lib/python3.10/site-packages/xarray/core/dataset.py:271: UserWarning: The specified chunks separate the stored chunks along dimension "time" starting at index 3. This could degrade performance. Instead, consider rechunking after loading.
  warnings.warn(
/g/data/hh5/public/apps/miniconda3/envs/analysis3-24.01/lib/python3.10/site-packages/xarray/core/dataset.py:271: UserWarning: The specified chunks separate the stored chunks along dimension "time" starting at index 3. This could degrade performance. Instead, consider rechunking after loading.
  warnings.warn(
/g/data/hh5/public/apps/miniconda3/envs/analysis3-24.01/lib/python3.10/site-packages/xarray/core/dataset.py:271: UserWarning: The specified chunks separate the stored chunks along dimension "time" starting at index 3. This could degrade performance. Instead, consider rechunking after loading.
  warnings.warn(
/g/data/hh5/public/apps/miniconda3/envs/analysis3-24.01/lib/python3.10/site-packages/xarray/core/dataset.py:271: UserWarning: The specified chunks separate the stored chunks along dimension "time" starting at index 3. This could degrade performance. Instead, consider rechunking after loading.
  warnings.warn(
CPU times: user 5.52 s, sys: 559 ms, total: 6.07 s
Wall time: 22.8 s
../_images/DocumentedExamples_Transport_Through_Straits_15_3.png

Or let’s just plot all of the straits!

Care must be taken north of 65N when performing zonal averages. Some warnings will be given to remind you that zonal averages north of 65N are not completely correct!

[8]:
fig, axes = plt.subplots(nrows=6, sharex=True, figsize=(8, 16))

for j, strait in enumerate(straits):
    transport = calc_transport(experiment, strait)

    transport.plot(ax=axes[j])
    axes[j].set_xlabel('')
    axes[j].set_title(strait+' Transport');
Calculating 025deg_jra55_iaf_omip2_cycle6: Drake Passage transport
Calculating 025deg_jra55_iaf_omip2_cycle6: Lombok transport
Calculating 025deg_jra55_iaf_omip2_cycle6: Ombai transport
Calculating 025deg_jra55_iaf_omip2_cycle6: Timor transport
WARNING:root:North of 65N the tripolar grid geometry brings complications and .sum('longitude') is wrong!
Calculating 025deg_jra55_iaf_omip2_cycle6: Denmark transport
WARNING:root:North of 65N the tripolar grid geometry brings complications and .sum('longitude') is wrong!
Calculating 025deg_jra55_iaf_omip2_cycle6: Bering transport
../_images/DocumentedExamples_Transport_Through_Straits_17_5.png