Deep submesoscales in 1/100°?#

Are there submesoscale features in the deep eq ocean? Do we resolve them with coarser vertical spacing?

May be some fronty things close to the equator, but our vertical resolution gets coarse (≈40m at 500m depth), so we may not be resolving things properly

Setup#

%config InlineBackend.figure_format = "retina"
%matplotlib inline
%load_ext autoreload
%autoreload 2

import dask
import distributed
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
import seawater as sw

import cf_xarray

import dcpy
import facetgrid
import xarray as xr

# import xmitgcm

# import pump

mpl.rcParams["savefig.dpi"] = 300
mpl.rcParams["savefig.bbox"] = "tight"
mpl.rcParams["figure.dpi"] = 140

xr.set_options(keep_attrs=True)
<xarray.core.options.set_options at 0x7f43eb4a8550>
cluster = distributed.LocalCluster(
    n_workers=24,
    processes=True,
    threads_per_worker=1,
    local_directory="/home/dcherian/.dask_worker/",
    dashboard_address=":9999",
    memory_limit="10GB",
)
cluster
client = distributed.Client(cluster)

Read data#

dirname = "/home/dcherian/pump/TPOS_MITgcm_HR/"
ds = xr.open_mfdataset(
    f"{dirname}/cmpr_*.nc",
    parallel=True,
    data_vars="minimal",
    coords="minimal",
    compat="override",
    chunks={"longitude": 1500, "latitude": 240},
)

Ro#

f = dcpy.oceans.coriolis(ds.latitude)
vor = ds.v.differentiate("longitude") / 110e3 - ds.u.differentiate("latitude") / 105e3
Ro = vor / f
Ro.attrs["long_name"] = "$Ro = ζ/f$"
Ro
<xarray.DataArray (time: 141, depth: 185, latitude: 2400, longitude: 7500)>
dask.array<truediv, shape=(141, 185, 2400, 7500), dtype=float32, chunksize=(1, 185, 240, 1500), chunktype=numpy.ndarray>
Coordinates:
  * latitude   (latitude) float32 -12.0 -11.99 -11.98 ... 11.98 11.99 12.0
  * longitude  (longitude) float32 -170.0 -170.0 -170.0 ... -95.02 -95.01 -95.0
  * depth      (depth) float32 -1.25 -3.75 -6.25 ... -5.658e+03 -5.758e+03
  * time       (time) datetime64[ns] 1995-11-07T08:00:00 ... 1995-11-30T16:00:00
Attributes:
    long_name:  $Ro = ζ/f$

Scott’s \(Ro\)

\begin{equation} Ro = \frac{|ζ|}{|ζ| + |f|} \end{equation}

sRo = np.abs(vor) / (np.abs(vor) + np.abs(f))
sRo.attrs["long_name"] = "$Ro = |ζ| / (|ζ| + |f|)$"

\(u\) lat-depth sections#

kwargs = dict(
    robust=True,
    vmin=0,
    vmax=0.8,
    cmap=mpl.cm.Spectral_r,
    cbar_kwargs={"orientation": "horizontal"},
)
ds.u.sel(longitude=[-110, -125, -140, -155], method="nearest").sel(
    latitude=slice(-5, 5), depth=slice(-2000)
).isel(time=50).plot(
    y="depth",
    x="latitude",
    row="longitude",
    robust=True,
    cbar_kwargs={"orientation": "horizontal"},
)
<xarray.plot.facetgrid.FacetGrid at 0x7f4552b2b7f0>
_images/66b0fcafa4f9afddfeadc4915a4844ef6c7c2cc67c125623e761e53d634c1937.png

Scott \(Ro\) maps#

Looks more “fronty” at depth

subset = sRo.sel(latitude=slice(-10, 10), longitude=slice(-155, -110))
subset.isel(time=50).sel(depth=0, method="nearest").plot(**kwargs)
<matplotlib.collections.QuadMesh at 0x7f461efdd580>
_images/626fbab032b09f0767d4ec4671003670bab3ae3d1fddec4a12fb10954ef2fdaa.png
sRo.isel(time=50).sel(depth=-100, method="nearest").plot(**kwargs)
<matplotlib.collections.QuadMesh at 0x7f47b6c28f70>
_images/9b3712f27307b5f69f80454b6146fd76c824abfc9510fc1b17831ba1dd60fde5.png
subset.isel(time=50).sel(depth=-200, method="nearest").plot(**kwargs)
<matplotlib.collections.QuadMesh at 0x7f4284573d60>
_images/58730714548770c8669c31010184e5b683b7c563dddc2187eb015bdd5a21f94c.png
for depth in [-300, -500, -700, -1000]:
    plt.figure()
    subset.isel(time=50).sel(depth=depth, method="nearest").plot(ylim=(-5, 5), **kwargs)
_images/9b176114a855d748a1c7094573d7645dcc2e806718625fe35641489fd38d3e67.png _images/da938190cc0a2ea6dc0528c2c4333471096e0a00edc42d6f184f7b7a9b3e0060.png _images/5f86e54df3ba940727662d5e827c4b4df809db2ff99778444f9314c8c96a7933.png _images/e3e9a776007f61a040d1e6a8977e6114dfe7f5b2b6c6587cff068a0797dba1ba.png

Ro maps at depth#

for depth in [-300, -500, -700, -1000]:
    plt.figure()
    Ro.reindex_like(subset).isel(time=50).sel(depth=depth, method="nearest").plot(
        ylim=(-5, 5),
        cmap=mpl.cm.RdBu_r,
        vmin=-1,
        vmax=1,
    )
/home/dcherian/miniconda3/envs/dcpy/lib/python3.8/site-packages/xarray/core/indexing.py:1375: PerformanceWarning: Slicing is producing a large chunk. To accept the large
chunk and silence this warning, set the option
    >>> with dask.config.set(**{'array.slicing.split_large_chunks': False}):
    ...     array[indexer]

To avoid creating the large chunks, set the option
    >>> with dask.config.set(**{'array.slicing.split_large_chunks': True}):
    ...     array[indexer]
  value = value[(slice(None),) * axis + (subkey,)]
/home/dcherian/miniconda3/envs/dcpy/lib/python3.8/site-packages/xarray/core/indexing.py:1375: PerformanceWarning: Slicing is producing a large chunk. To accept the large
chunk and silence this warning, set the option
    >>> with dask.config.set(**{'array.slicing.split_large_chunks': False}):
    ...     array[indexer]

To avoid creating the large chunks, set the option
    >>> with dask.config.set(**{'array.slicing.split_large_chunks': True}):
    ...     array[indexer]
  value = value[(slice(None),) * axis + (subkey,)]
/home/dcherian/miniconda3/envs/dcpy/lib/python3.8/site-packages/xarray/core/indexing.py:1375: PerformanceWarning: Slicing is producing a large chunk. To accept the large
chunk and silence this warning, set the option
    >>> with dask.config.set(**{'array.slicing.split_large_chunks': False}):
    ...     array[indexer]

To avoid creating the large chunks, set the option
    >>> with dask.config.set(**{'array.slicing.split_large_chunks': True}):
    ...     array[indexer]
  value = value[(slice(None),) * axis + (subkey,)]
/home/dcherian/miniconda3/envs/dcpy/lib/python3.8/site-packages/xarray/core/indexing.py:1375: PerformanceWarning: Slicing is producing a large chunk. To accept the large
chunk and silence this warning, set the option
    >>> with dask.config.set(**{'array.slicing.split_large_chunks': False}):
    ...     array[indexer]

To avoid creating the large chunks, set the option
    >>> with dask.config.set(**{'array.slicing.split_large_chunks': True}):
    ...     array[indexer]
  value = value[(slice(None),) * axis + (subkey,)]
_images/8e0c24712bbfe3347cec72281d9e36a0d70f921a10665d4a930a2d23c4e44cf4.png _images/4201527b0e21a2ffd295f56e20c6d75588a678ced4a341c4bda1026a776b33de.png _images/dd520e6458ed399d5f90cba6766178c29dff44eba6877407477301c95dac7893.png _images/283122c247c3f1907400006e7db994f7a8877ff13f59a6c7e3b2aa571d6bbf9b.png

Ro Lat-depth plots#

There may be some interesting things in 1°S-1°N, but our vertical resolution is coarse below 250m

for longitude in [-155, -140, -125, -110]:
    plt.figure()
    Ro.isel(time=50).sel(longitude=longitude, method="nearest").plot(
        ylim=(-500, 0), vmin=-1, vmax=1, cmap=mpl.cm.RdBu_r, y="depth"
    )
_images/7785bec286a31107e0e0cab00043b94980b17bdbb176b4fbe4117f5ec762614a.png _images/654fb427d34123fae40c13ea61cbbc5f3b2334834161eb24d3a4b8dc99146dba.png _images/89f3497148835e9f601eed4a1736c5ed6436ee6632701184525da0438e04e17d.png _images/64394a558dc6d24db28339369dccdce780a836553c737bc006547e98712aeb83.png
for longitude in [-155, -140, -125, -110]:
    plt.figure()
    sRo.isel(time=50).sel(longitude=longitude, method="nearest").plot(
        ylim=(-500, 0), vmin=0, vmax=0.8, cmap=mpl.cm.RdBu_r, y="depth"
    )
_images/41370734079396739b1136fbdf6cb4fd75ff8687a48434071df28b080acb0684.png _images/9758c2d6938c0d45186fd71ba9268615253da381310171d491c90a87d6143d57.png _images/960c74395fe626767e1134652641ef3fedb14cb0c8d61486ca55e79205828dd9.png _images/e7a348adb2ce73fda84d1918f95b9a84f4db61c7b50a8fff424761b8d5c2f5ba.png