Skip to content

Commit

Permalink
update to TEOS-10
Browse files Browse the repository at this point in the history
  • Loading branch information
fredc committed Feb 3, 2021
1 parent c43b32e commit f2c99d4
Show file tree
Hide file tree
Showing 12 changed files with 55 additions and 11 deletions.
1 change: 1 addition & 0 deletions etc/config.move.g.e20.G.TL319_t13.control.001
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ time_avg=monthly

[options]
array = MOVE
eos = teos10
td_geo = False
endpoint = False
georef_level = 4625.
Expand Down
1 change: 1 addition & 0 deletions etc/config.rapid.g.e20.G.TL319_t13.control.001
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ time_avg=monthly

[options]
array = RAPID
eos = teos10
td_geo = False
endpoint = False
#georef_level = 4625.
Expand Down
1 change: 1 addition & 0 deletions etc/config.samba.g.e20.G.TL319_t13.control.001
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ time_avg=monthly

[options]
array = SAMBA
eos = teos10
td_geo = False
endpoint = False
georef_level = 4700.
Expand Down
43 changes: 35 additions & 8 deletions metric/geostrophy.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,18 @@
import numpy as np
import copy

import gsw

from . import constants
from . import utils



def eos_insitu(t, s, p):
def eos80_insitu_dens(t, s, p):
"""
Returns in situ density of seawater as calculated by the NEMO
routine eos_insitu.f90. Computes the density referenced to
a specified depth/pressure from potential temperature and salinity
using the Jackett and McDougall (1994) equation of state.
Computes insitu density from potential temperature and salinity using the
1980 Equation of State of Seawater (EOS80; Jackett and McDougall 1994).
https://doi.org/10.1175/1520-0426(1995)012<0381:MAOHPT>2.0.CO;2
"""
# Convert to double precision
Expand Down Expand Up @@ -63,7 +64,27 @@ def eos_insitu(t, s, p):
return rho


def calc_dh(t_on_v, s_on_v, get_rho=True):
def teos10_insitu_dens(t, s, z, lat, lon):
"""
Computes the insitu density from potential temperature and salinity using the
Thermodynamic Equation of Seawater 2010 (TEOS-10; IOC, SCOR and IAPSO, 2010).
http://www.teos-10.org/pubs/TEOS-10_Manual.pdf
"""

depth = np.ones_like(t) * z[None,:,None]
lat = np.ones_like(t) * lat[None,None,:]
lon = np.ones_like(t) * lon[None,None,:]

p = gsw.p_from_z(-depth, lat)
SA = gsw.SA_from_SP(s, p, lon, lat)
CT = gsw.CT_from_pt(SA, t)
rho = gsw.rho(SA,CT,p)

return rho


def calc_dh(t_on_v, s_on_v, eos, get_rho=True):
"""
Return ZonalSections containing dynamic heights calculated from
from temperature and salinity interpolated onto velocity boundaries.
Expand All @@ -72,8 +93,14 @@ def calc_dh(t_on_v, s_on_v, get_rho=True):
# Calculate in situ density at bounds
rho = copy.deepcopy(t_on_v)
rho.data = None # Density not needed at v mid-points
rho.bounds_data = eos_insitu(t_on_v.bounds_data, s_on_v.bounds_data,
t_on_v.z_as_bounds_data)
if eos == 'eos80':
rho.bounds_data = eos80_insitu_dens(t_on_v.bounds_data, s_on_v.bounds_data,
t_on_v.z_as_bounds_data)
elif eos == 'teos10':
rho.bounds_data = teos10_insitu_dens(t_on_v.bounds_data, s_on_v.bounds_data,
t_on_v.z, t_on_v.ybounds, t_on_v.xbounds)
else:
raise RuntimeError('EOS based on either the 1980 equation of state (eos="eos80") or the international thermodynamic equation of seawater - 2010 (eos="teos10") are implemented')

# Calculate dynamic height relative to a reference level
dh = copy.deepcopy(rho)
Expand Down
4 changes: 4 additions & 0 deletions metric/metric.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ def compute_amoc_transport(line_args):
if args.shift_date is not None:
config.set('output', 'shift_date', args.shift_date)

# Update shift_date in config file
if utils.get_config_opt(config, 'options', 'eos') is None:
config.set('options', 'eos', 'teos10')

# Check files and options
if not utils.path.exists(args.config_file):
raise FileNotFoundError(errno.ENOENT, os.strerror(errno.ENOENT), args.config_file)
Expand Down
2 changes: 2 additions & 0 deletions metric/move/output.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ def create_netcdf(config, move_trans, model_trans, bdry_trans, int_trans, int_mo
bdry_maxlon = config.getfloat('options','bdry_maxlon')
int_maxlon = config.getfloat('options','int_maxlon')
georef = config.getfloat('options','georef_level')
eos = config.get('options','eos')

try:
vref_level = config.getfloat('options','vref_level')
Expand Down Expand Up @@ -111,6 +112,7 @@ def create_netcdf(config, move_trans, model_trans, bdry_trans, int_trans, int_mo
dataset.reference_to_model_velocity = vref_level
if config.getboolean('options', 'endpoint'):
dataset.geostrophic_computation = 'endpoint'
dataset.eos = eos
dataset.rhocp = move_trans.rhocp
dataset.contact = 'fredc.ucar.edu'
dataset.code_reference = 'https://github.com/NCAR/metric'
Expand Down
3 changes: 2 additions & 1 deletion metric/move/transports.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,8 @@ def calc_transports_from_sections(config, v, t_on_v, s_on_v, ssh_on_v):
intmin,intmax = utils.get_indrange(v.x, bdry_maxlon, int_maxlon) # boundary component

# Calculate dynamic heights
dh, rho = calc_dh(t_on_v, s_on_v, get_rho=True)
eos = config.get('options','eos')
dh, rho = calc_dh(t_on_v, s_on_v, eos, get_rho=True)

# Calculate geostrophic transports
if config.getboolean('options', 'td_geo'):
Expand Down
2 changes: 2 additions & 0 deletions metric/rapid/output.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ def create_netcdf(config, rapid_trans, model_trans, fc_trans,
int_maxlon = config.getfloat('options','int_maxlon')
georef = config.getfloat('options','georef_level')
ek_level = config.getfloat('options','ekman_depth')
eos = config.get('options','eos')

try:
vref_level = config.getfloat('options','vref_level')
Expand Down Expand Up @@ -113,6 +114,7 @@ def create_netcdf(config, rapid_trans, model_trans, fc_trans,
dataset.reference_to_model_velocity = vref_level
if config.getboolean('options', 'endpoint'):
dataset.geostrophic_computation = 'endpoint'
dataset.eos = eos
dataset.rhocp = rapid_trans.rhocp
dataset.ekman_level = ek_level
dataset.contact = 'fredc.ucar.edu'
Expand Down
3 changes: 2 additions & 1 deletion metric/rapid/transports.py
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,8 @@ def calc_transports_from_sections(config, v, tau, t_on_v, s_on_v, ssh_on_v):
intmin, intmax = utils.get_indrange(v.x, wbw_maxlon, int_maxlon) # Gyre interior

# Calculate dynamic heights
dh, rho = calc_dh(t_on_v, s_on_v, get_rho=True)
eos = config.get('options','eos')
dh, rho = calc_dh(t_on_v, s_on_v, eos, get_rho=True)

# Calculate geostrophic transports
if config.getboolean('options', 'td_geo'):
Expand Down
2 changes: 2 additions & 0 deletions metric/samba/output.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ def create_netcdf(config, samba_trans, model_trans, wbw_trans,
ebw_maxlon = config.getfloat('options','ebw_maxlon')
georef = config.getfloat('options','georef_level')
ek_level = config.getfloat('options','ekman_depth')
eos = config.get('options','eos')

try:
vref_level = config.getfloat('options','vref_level')
Expand Down Expand Up @@ -113,6 +114,7 @@ def create_netcdf(config, samba_trans, model_trans, wbw_trans,
dataset.reference_to_model_velocity = vref_level
if config.getboolean('options', 'endpoint'):
dataset.geostrophic_computation = 'endpoint'
dataset.eos = eos
dataset.rhocp = samba_trans.rhocp
dataset.ekman_level = ek_level
dataset.contact = 'fredc.ucar.edu'
Expand Down
3 changes: 2 additions & 1 deletion metric/samba/transports.py
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,8 @@ def calc_transports_from_sections(config, v, tau, t_on_v, s_on_v, ssh_on_v):
ebwmin, ebwmax = utils.get_indrange(v.x, int_maxlon, ebw_maxlon) # EBW

# Calculate dynamic heights
dh, rho = calc_dh(t_on_v, s_on_v, get_rho=True)
eos = config.get('options','eos')
dh, rho = calc_dh(t_on_v, s_on_v, eos, get_rho=True)

# Calculate geostrophic transports
if config.getboolean('options', 'td_geo'):
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ netCDF4
ConfigParser
argparse
matplotlib
gsw

0 comments on commit f2c99d4

Please sign in to comment.