Internal functions
Equation of State
JMD95
Density of Sea Water using the Jackett and McDougall 1995 [1] function
Functions:
- rho :: computes in-situ density from salinity, potential temperature and
pressure (or depth)
- rho_s_t :: compute the partial derivatives of in-situ density with
respect to salinity and potential temperature
- rho_p :: compute the partial derivative of in-situ density with
respect to pressure (or depth)
Notes:
To make Boussinesq versions of these functions, see
neutralocean.eos.tools.make_bsq.
To make vectorized versions of these functions, see
neutralocean.eos.tools.vectorize_eos.
Jackett and McDougall, 1995, JAOT 12[4], pp. 381-388
- neutralocean.eos.jmd95.rho(s, t, p, pfac=1.0)[source]
Fast JMD95 [1] in-situ density.
- Parameters:
- sfloat
Practical salinity [PSS-78]
- tfloat
Potential temperature [IPTS-68]
- pfloat
Pressure [dbar]
- pfacfloat, Optional
Multiplicative scaling factor applied to
p. Default value is 1.0 [dbar-1]. SeeNotes.
- Returns:
- rhofloat
JMD95 in-situ density [kg m-3]
Notes
The Boussinesq version of this function is called with third input
pas depth [m] andpfac = pfac_default * Pa2db * grav * rho_cwheregravis the gravitational acceleration [m.s-2]rho_cis the Boussinesq reference density [kg.m-3],pfac_default = 1.0[dbar-1] is the non-Boussinesq value ofpfacPa2db = 1e-4[dbar.Pa-1]. Thus,p * Pa2db * grav * rho_cis the hydrostatic pressure [dbar] at depthpassuming the water column’s density wasrho_c.To create a Boussinesq version of this function that accepts 3 arguments (salinity, temperature, depth), use
neutralocean.eos.tools.make_bsq.This function is derived from
densjmd95.m, documented below. Input checks and expansion of variables have been removed. That code used arrays to store coefficients, and also began by multiplying the input pressure by 10 (dbar -> bar). The coefficients, modified to not need this multiplication by 10, have been taken out of arrays and simply hardcoded into the later expressions. The polynomial calculations have also been optimized to favour faster, nested multiplications.As such, the output of this function differs from the output of the original
densjmd95.mfunction, though the difference is at the level of machine precision.% DENSJMD95 Density of sea water %========================================================================= % % USAGE: dens = densjmd95(S,Theta,P) % % DESCRIPTION: % Density of Sea Water using Jackett and McDougall 1995 (JAOT 12) % polynomial (modified UNESCO polynomial). % % INPUT: (all must have same dimensions) % S = salinity [psu (PSS-78)] % Theta = potential temperature [degree C (IPTS-68)] % P = pressure [dbar] % (P may have dims 1x1, mx1, 1xn or mxn for S(mxn) ) % % OUTPUT: % dens = density [kg/m^3] % % AUTHOR: Martin Losch 2002-08-09 (mlosch@mit.edu) % Jackett and McDougall, 1995, JAOT 12(4), pp. 381-388 % created by mlosch on 2002-08-09 % $Header: /u/gcmpack/MITgcm/utils/matlab/densjmd95.m,v 1.2 2007/02/17 23:49:43 jmc Exp $ % $Name: $
[1]Jackett and McDougall, 1995, JAOT 12[4], pp. 381-388
- neutralocean.eos.jmd95.rho_s_t(s, t, p, pfac=1.0)[source]
Fast salinity and potential temperature partial derivatives of JMD95 in-situ density
- Parameters:
- s, t, p, pfacfloat
See
rho
- Returns:
- rho_sfloat
Partial derivative of JMD95 in-situ density with respect to practical salinity
s[kg m-3 psu-1]- rho_tfloat
Partial derivative of JMD95 in-situ density with respect to potential temperature
t[kg m-3 degC-1]
Notes
This function is derived from
rho.
JMDFWG06
Density of Sea Water using the Jackett et al. (2006) [1] function
Functions:
- rho :: computes in-situ density from salinity, potential temperature and
pressure (or depth)
- rho_s_t :: compute the partial derivatives of in-situ density with
respect to salinity and potential temperature
- rho_p :: compute the partial derivative of in-situ density with
respect to pressure (or depth)
Notes:
To make Boussinesq versions of these functions, see
neutralocean.eos.tools.make_bsq.
To make vectorized versions of these functions, see
neutralocean.eos.tools.vectorize_eos.
Jackett, D. R., McDougall, T. J., Feistel, R., Wright, D. G., & Griffies, S. M. (2006). Algorithms for Density, Potential Temperature, Conservative Temperature, and the Freezing Temperature of Seawater. Journal of Atmospheric and Oceanic Technology, 23(12), 1709–1728. https://doi.org/10.1175/JTECH1946.1
History
Code adapted from MOM5.1 (Griffies et al) originally written in Fortran 2022 January 14 - David Hutchinson - Translated into python 2022 January 14 - Geoff Stanley - code optimization, partial derivatives, check vals
- neutralocean.eos.jmdfwg06.rho(s, t, p, pfac=1.0)[source]
- Parameters:
- sfloat
Practical salinity [PSS-78]
- tfloat
Potential temperature [ITS-90]
- pfloat
Pressure [dbar]
- pfacfloat, Optional
Multiplicative scaling factor applied to
p. Default value is 1.0 [dbar-1]. SeeNotes.
- Returns:
- rhofloat
In-situ density [kg m-3]
Notes
The Boussinesq version of this function is called with third input
pas depth [m] andpfac = pfac_default * Pa2db * grav * rho_cwheregravis the gravitational acceleration [m.s-2]rho_cis the Boussinesq reference density [kg.m-3],pfac_default = 1.0[dbar-1] is the non-Boussinesq value ofpfacPa2db = 1e-4[dbar.Pa-1]. Thus,p * Pa2db * grav * rho_cis the hydrostatic pressure [dbar] at depthpassuming the water column’s density wasrho_c.To create a Boussinesq version of this function that accepts 3 arguments (salinity, temperature, depth), use
neutralocean.eos.tools.make_bsq.
TEOS-10 GSW
Specific Volume using 75-term polyTEOS10-75t [1] approximation to the TEOS-10 Gibbs Sea Water standard [2]
Functions:
- specvol :: compute specific volume from Absolute Salinity, Conservative Temperature and
pressure (or depth)
rho :: compute in-situ density as the reciprocol of specific volume
specvol_first_derivs :: compute first order partial derivatives of specvol
specvol_second_derivs :: compute second order partial derivatives of specvol
specvol_third_derivs :: compute third order partial derivatives of specvol
- specvol_s_t :: compute the partial derivatives of specvol with respect to
Absolute Salinity and Conservative Temperature
specvol_p :: compute the partial derivative of specvol with respect to pressure
- specvol_s_t_ss_st_tt_sp_tp :: compute various partial derivatives of specvol,
namely with respect to s, t, ss, st, tt, sp, tp.
- specvol_s_t_ss_st_tt_sp_tp_sss_sst_stt_ttt_ssp_stp_ttp_spp_tpp :: compute various
partial derivatives of specvol, namely with respect to s, t, ss, st, tt, sp, tp, sss, sst, stt, ttt, ssp, stp, ttp, spp, tpp.
Notes:
To make Boussinesq versions of these functions, see
neutralocean.eos.tools.make_bsq.
To make vectorized versions of these functions which return scalar outputs, see
neutralocean.eos.tools.vectorize_eos.
All functions here are derived from gsw_specvol, documented below.
# gsw_specvol specific volume (75-term equation)
#==========================================================================
#
# USAGE:
# specvol = gsw_specvol(SA,CT,p)
#
# DESCRIPTION:
# Calculates specific volume from Absolute Salinity, Conservative
# Temperature and pressure, using the computationally-efficient 75-term
# polynomial expression for specific volume (Roquet et al., 2015).
#
# Note that the 75-term equation has been fitted in a restricted range of
# parameter space, and is most accurate inside the "oceanographic funnel"
# described in McDougall et al. (2003). The GSW library function
# "gsw_infunnel(SA,CT,p)" is available to be used if one wants to test if
# some of one's data lies outside this "funnel".
#
# INPUT:
# SA = Absolute Salinity [ g/kg ]
# CT = Conservative Temperature (ITS-90) [ deg C ]
# p = sea pressure [ dbar ]
# ( i.e. absolute pressure - 10.1325 dbar )
#
# OUTPUT:
# specvol = specific volume [ m^3/kg ]
#
# AUTHOR:
# Fabien Roquet, Gurvan Madec, Trevor McDougall & Paul Barker
# [ help@teos-10.org ]
#
# VERSION NUMBER: 3.06 (30th August, 2018)
#
# REFERENCES:
# IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of
# seawater - 2010: Calculation and use of thermodynamic properties.
# Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
# UNESCO (English), 196 pp. Available from http://www.TEOS-10.org.
#
# McDougall, T.J., D.R. Jackett, D.G. Wright and R. Feistel, 2003:
# Accurate and computationally efficient algorithms for potential
# temperature and density of seawater. J. Atmos. Ocean. Tech., 20,
# 730-741.
#
# Roquet, F., G. Madec, T.J. McDougall, P.M. Barker, 2015: Accurate
# polynomial expressions for the density and specifc volume of seawater
# using the TEOS-10 standard. Ocean Modelling., 90, pp. 29-43.
#
# This software is available from http://www.TEOS-10.org
#
#==========================================================================
Roquet, F., G. Madec, T.J. McDougall, P.M. Barker, 2015: Accurate polynomial expressions for the density and specifc volume of seawater using the TEOS-10 standard. Ocean Modelling., 90, pp. 29-43.
McDougall, T.J. and P.M. Barker, 2011: Getting started with TEOS-10 and the Gibbs Seawater (GSW) Oceanographic Toolbox, 28pp., SCOR/IAPSO WG127, ISBN 978-0-646-55621-5.
- neutralocean.eos.gsw.specvol(SA, CT, p, pfac=0.0001)[source]
GSW specific volume.
- Parameters:
- SAfloat
Absolute Salinity [g/kg]
- CTfloat
Conservative Temperature (ITS-90) [deg C]
- pfloat
sea pressure (i.e. absolute pressure - 10.1325 dbar) [dbar]
- pfacfloat, Optional
Multiplicative scaling factor applied to
p. Default value is 1e-4 [dbar-1]. SeeNotes.
- Returns:
- specvolfloat
Specific volume [m3 kg-1]
Notes
The Boussinesq version of this function is called with third input
pas depth [m] andpfac = pfac_default * Pa2db * grav * rho_cwheregravis the gravitational acceleration [m.s-2]rho_cis the Boussinesq reference density [kg.m-3],pfac_default = 1e-4[dbar-1] is the non-Boussinesq value ofpfacPa2db = 1e-4[dbar.Pa-1]. Thus,p * Pa2db * grav * rho_cis the hydrostatic pressure [dbar] at depthpassuming the water column’s density wasrho_c.To create a Boussinesq version of this function that accepts 3 arguments (salinity, temperature, depth), use
neutralocean.eos.tools.make_bsq.
- neutralocean.eos.gsw.specvol_first_derivs(SA, CT, p, pfac=0.0001)[source]
Calculate all first order partial derivatives of specific volume
- Parameters:
- SA, CT, p, pfacfloat
See
specvol
- Returns:
- vsfloat
Partial derivative of specific volume w.r.t.
SA[m3 kg-1 / (g/kg)]- vtfloat
Partial derivative of specific volume w.r.t.
CT[m3 kg-1 / (deg C)]- vpfloat
Partial derivative of specific volume w.r.t.
p[m3 kg-1 / [p]]
- neutralocean.eos.gsw.specvol_second_derivs(SA, CT, p, pfac=0.0001)[source]
Calculate all second order partial derivatives of specific volume
- Parameters:
- SA, CT, p, pfacfloat
See
specvol
- Returns:
- vss, vst, vtt, vsp, vtp, vppfloat
Second order partial derivatives of specific volume w.r.t.
SA * SA,SA * CT,CT * CT,SA * p,CT * p, respectively.
- neutralocean.eos.gsw.specvol_third_derivs(SA, CT, p, pfac=0.0001)[source]
Calculate all third order partial derivatives of specific volume
- Parameters:
- SA, CT, p, pfacfloat
See
specvol
- Returns:
- vsss, vsst, vstt, vttt, vssp, vstp, vttp, vspp, vtppfloat
Third order partial derivatives of specific volume.
- neutralocean.eos.gsw.specvol_s_t(SA, CT, p, pfac=0.0001)[source]
Partial derivatives of specific volume with respect to salinity & temperature
- Parameters:
- SA, CT, p, pfacfloat
See
specvol
- Returns:
- vsfloat
Partial derivative of specific volume w.r.t.
SA[m3 kg-1 / (g/kg)]- vtfloat
Partial derivative of specific volume w.r.t.
CT[m3 kg-1 / (deg C)]
- neutralocean.eos.gsw.specvol_p(SA, CT, p, pfac=0.0001)[source]
Partial derivative of specific volume with respect to pressure
- Parameters:
- SA, CT, p, pfacfloat
See
specvol
- Returns:
- vpfloat
Partial derivative of specific volume w.r.t.
p[m3 kg-1 / [p]]
- neutralocean.eos.gsw.specvol_s_t_ss_st_tt_sp_tp(SA, CT, p, pfac=0.0001)[source]
Select partial derivatives of specific volume up to second order
- Parameters:
- SA, CT, p, pfacfloat
See
specvol
- Returns:
- s, t, ss, st, tt, sp, tpfloat
Partial derivatives of specific volume w.r.t.
SA,CT,SA*SA,SA*CT,CT*CT,SA*p,CT*p.
- neutralocean.eos.gsw.specvol_s_t_ss_st_tt_sp_tp_sss_sst_stt_ttt_ssp_stp_ttp_spp_tpp(SA, CT, p, pfac=0.0001)[source]
Select partial derivatives of specific volume up to third order
- Parameters:
- SA, CT, p, pfacfloat
See
specvol
- Returns:
- vs, vt, vss, vst, vtt, vsp, vtp, vsss, vsst, vstt, vttt, vssp, vstp, vttp, vspp, vtppfloat
Partial derivatives of specific volume.
(Vertical) Interpolation using Piecewise Polynomials (PP)
- neutralocean.ppinterp.pval(x, C, d=0)[source]
Evaluate a (derivative of a) single polynomial.
- Parameters:
- xfloat
Evaluation site
- Carray of float
Polynomial coefficients, starting with the highest order coefficient and ending with the coefficient of the constant term. The order of the polynomial is
len(C).- dint, Default 0
Order of the derivative to evaluate. When
0, just evaluate the polynomial.
- Returns:
- yfloat
The polynomial (or its
d’th derivative) evaluated atx.
- neutralocean.ppinterp.lib.valid_range(X, k, K)[source]
Indices to the first finite value and to the first NaN after the former, along last dimension.
- Parameters:
- Xndarray
Input array possibly containing some NaN elements
- Returns:
- kndarray of int
k[n]is the smallest index such thatX[n][k[n]]is finite. IfX[i]is NaN for alli, thenk[n] = len(X[n]).- Kndarray of int
If
X[n][i]is NaN for alli > k[n], thenK[n] = len(X[n]). IfX[n][i]is finite for alli > k[n], thenK[n] = len(X[n]). Otherwise,K[n]is the smallest index afterk[n]such thatX[n][K[n]]is NaN.
Notes
X[n][i]is non-NaN fori = k[n], ..., K[n] - 1.K[n] - k[n]is the size of the first contiguous block of valid values ofX[n].
- neutralocean.ppinterp.lib.valid_range_1(X)[source]
The index to the first finite value and to the first NaN after the former
- Parameters:
- X1D array
Input array possibly containing some NaN elements
- Returns:
- kint
First
ksuch thatX[k]is finite. IfX[i]is NaN for alli, thenk = len(X).- Kint
If
X[i]is NaN for alli > k, thenK = len(X). IfX[i]is finite for alli > k, thenK = len(X). Otherwise,Kis the first index afterksuch thatX[K]is NaN.
Notes
X[i]is non-NaN fori = k, ..., K - 1.K - kis the size of the first contiguous block of valid values ofX.
- neutralocean.ppinterp.lib.valid_range_1_two(X, Y)[source]
Indices bounding the first contiguous block of valid data in two 1D arrays
- Parameters:
- X, Y1D array
Input arrays of the same length, possibly containing some NaN elements
- Returns:
- kint
First
ksuch thatX[k]andY[k]are finite. IfX[i]orY[i]is NaN for alli, thenk = len(X).- Kint
If
X[i]orY[i]is NaN for alli > k, thenK = len(X). IfX[i]andY[i]are finite for alli > k, thenK = len(X). Otherwise,Kis the first index afterksuch thatX[K]orY[K]is NaN.
Notes
X[i]andY[i]are both non-NaN fori = k, ..., K - 1.K - kis the size of the first contiguous block of valid pairs of values of(X, Y).
- neutralocean.ppinterp.linear.linear_coeffs(X, Y)[source]
Piecewise Polynomial Coefficients for a linear interpolant
- Parameters:
- Xndarray
Independent variable. Must be same dimensions as
Y, with any dimension possibly a singleton: that is, must be broadcastable to the size ofY.Xmust be monotonically increasing in its last dimension. That is,X[*i,:]should be monotonically increasing for anyituple indexing all but the last dimension.- Yndarray
Dependent variable. Must be same dimensions as
X, with any dimension possibly a singleton: that is, must be broadcastable to the size ofX.
- Returns:
- Yppcndarray
Coefficients for a linear interpolant of
YtoX.
Notes
If
XandYhave NaN’s, only the first contiguous block of non-NaN data between bothXandYis used.Evaluate the piecewise polynomial at
xas>>> y = ppval(x, X, Yppc)
- neutralocean.ppinterp.pchip.pchip_coeffs(X, Y)[source]
Piecewise Polynomial Coefficients for a PCHIP (Piecewise Cubic Hermite Interpolating Polynomial)
- Parameters:
- Xndarray
Independent variable. Must be same dimensions as
Y, with any dimension possibly a singleton: that is, must be broadcastable to the size ofY.Xmust be monotonically increasing in its last dimension. That is,X[*i,:]should be monotonically increasing for anyituple indexing all but the last dimension.- Yndarray
Dependent variable. Must be same dimensions as
X, with any dimension possibly a singleton: that is, must be broadcastable to the size ofX.
- Returns:
- Yppcndarray
Coefficients for a PCHIP interpolant of
YtoX.
Notes
If
XandYhave NaN’s, only the first contiguous block of non-NaN data between bothXandYis used.Evaluate the piecewise polynomial at
xas>>> y = ppval(x, X, Yppc)
Root finding in 1D
Functions for finding the zero of a univariate function.
- neutralocean.fzero.brent_guess(f, x, A, B, t, args=())[source]
Find a zero of a function within a given range, starting from a guess
- Parameters:
- ffunction
Continuous function of a single variable.
- xfloat
initial guess for a root
- A, Bfloat
Range within which to search, satisfying
A < B- tfloat
Tolerance for convergence.
- argstuple
Additional arguments, beyond the optimization argument, to be passed to
f. Pass()whenfis univariate.
- Returns:
- float
Value of
xwheref(x) ~ 0.
- neutralocean.fzero.brent(f, a, b, t, args=())[source]
Find a zero of a univariate function within a given range
This is a bracketed root-finding method, so
f(a)andf(b)must differ in sign. If they do, a root is guaranteed to be found.- Parameters:
- ffunction
Continuous function of a single variable.
- a, bfloat
Range within which to search, satisfying
a < band ideallyf(a) * f(b) <= 0- tfloat
Tolerance for convergence.
- argstuple
Additional arguments, beyond the optimization argument, to be passed to
f. Pass()whenfis univariate.
- Returns:
- float
Value of
xwheref(x) ~ 0.
Notes
fshould be a@numba.njit’ed function (when this function isnjit’ed).
- neutralocean.fzero.guess_to_bounds(f, x, A, B, args=())[source]
Search for a range containing a sign change, expanding geometrically outwards from the initial guess.
This is used as a first step in zero-finding, providing a small search range for the Brent algorithm.
- Parameters:
- ffunction
Continuous function of a single variable. Note
f(x)should be real valued (no NaN’s) on the entire interval[A, B]; unexpected behaviour may result otherwise.- xfloat
Central point for starting the search
- A, Bfloat
Lower and upper bounds, containing
x, within which to search for a zero.- argstuple
Additional arguments beyond the optimization argument. Pass
()whenfis univariate.
- Returns:
- a, bfloat
Lower and upper bounds within which
f(x)changes sign.
Library functions
- neutralocean.lib.find_first_nan(a, axis=-1)[source]
The index to the first NaN along a given axis
- Parameters:
- andarray
Input array possibly containing some NaN elements
- axisint, Default -1
Axis along which to find the first NaN
- Returns:
- kndarray of int
For each 1D array
a1ofain the dimensionaxis,kgives: the index to the first NaN ofa1, or 0 ifa1has no NaNs, ora.shape[axis]ifa1is all NaN.For example, with
abeing 3D andaxis= -1: If alla[i,j,:]are NaN, thenk[i,j] = 0. If alla[i,j,:]are not NaN, thenk[i,j] = a.shape[-1]. Otherwise,K = k[i,j]is the smallest int such thata[i,j,K-1]is not NaN anda[i,j,K]is NaN.
Notes
This is similar to (and faster than)
numpy.argmax(numpy.isnan(a), axis), but differs for indices along whichais all NaN: this output containsa.shape[axis]whereas theargmaxapproach contains 0.
- neutralocean.lib.val_at(T, k)[source]
Evaluate nD array at given indices along its last dimension
- Parameters:
- Tndarray
Input array. Can be 1D or nD.
- kint or ndarray
Index at which to evaluate
Talong its last dimension. Can be an int or (n-1)D.
- Returns:
- Tkndarray
The input
Tevaluated with its last index equal tok.
Notes
If
Tis 3D andkis 2D, thenTk[i,j] = T[i,j,k[i,j]]for each valid(i,j).If
Tis 1D andkis 2D, thenTk[i,j] = T[k[i,j]]for each valid(i,j).If
Tis 3D andkis an int, thenTk[i,j] = T[i,j,k]for each valid(i,j).Examples
Evaluate temperature, having data in each water column, at the bottom grid cell
>>> T = np.empty((3, 2, 10)) # (longitude, latitude, depth), let us say >>> T[..., :] = np.arange(10, 0, -1) # decreasing along depth dim from 10 to 1 >>> T[0, 0, :] = np.nan # make cast (0,0) be land >>> T[0, 1, 3:] = np.nan # make cast (0,1) be only 3 ocean cells deep >>> n_good = find_first_nan(T) >>> val_at(T, n_good - 1) array([[nan, 8.], [ 1., 1.], [ 1., 1.]])
Evaluate the depth at the bottom grid cell
>>> Z = np.linspace(0, 4500, 10) # grid cell centre's are at depths 0, 500, 1000, ..., 4500. >>> val_at(Z, n_good - 1) # Z doesn't have NaN structure, so use n_good from T as above array([[ nan, 1000.], [4500., 4500.], [4500., 4500.]])
- neutralocean.lib.take_fill(a, idx, fillval=nan)[source]
Like numpy.take but fills with nan when indices are out of range
- Parameters:
- andarray
input data
- idx1d array
linear indices to elements of
a
- Returns:
- bndarray
The i’th element of b (in linear order) is the
idx[i]’th element ofa, (in linear order), or nan ifidx[i] < 0. Same shape asidx.
- neutralocean.lib.aggsum(a, idx, n)[source]
Aggregate data into groups and sum each group.
- Parameters:
- aarray
Input data to be aggregated into groups and summed.
- idxarray of int
Group label for each element of
a. To exclude elementiofafrom any group, letidx[i]be a negative int. Must be same size asa.- nint
Number of groups, including empty groups. As this is also the length of
b, must satisfyn >= np.max(idx) + 1.
- Returns:
- barray
The sum of each group of data from
a.
Notes
This is a simple implementation of
numpy_groupies.aggregate. See https://github.com/ml31415/numpy-groupies/