Internal functions

Equation of State

neutralocean.eos.tools.make_bsq(fn, grav, rho_c, num_p_derivs=0)[source]

Make a Boussinesq version of a given equation of state (or its partial derivative(s))

Parameters:
fnfunction

Function with (salinity, temperature, pressure) as inputs. Typically this is the equation of state, returning the density or specific volume. However, it can also be a function for partial derivative(s) of the equation of state with respect to salinity, temperature, or pressure.

gravfloat

Gravitational acceleration [m s-2]

rho_cfloat

Boussinesq reference density [kg m-3]

num_p_derivsint, Default 0

Number of p partial derivatives that relate fn to the equation of state. For example,

  • if fn is the equation of state, or its partial derivative (of any order, with respect to salinity or temperature, pass 0.

  • if fn is the partial derivative of the equation of state with respect to pressure, pass 1.

  • if fn is the second partial derivative of the equation of state with respect to salinity and pressure (i.e. ∂²ρ/∂S∂p), pass 1.

Returns:
fn_bsqfunction

Boussinesq version of fn. The inputs to fn_bsq are (salinity, temperature, depth).

(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 at x.

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 that X[n][k[n]] is finite. If X[i] is NaN for all i, then k[n] = len(X[n]).

Kndarray of int

If X[n][i] is NaN for all i > k[n], then K[n] = len(X[n]). If X[n][i] is finite for all i > k[n], then K[n] = len(X[n]). Otherwise, K[n] is the smallest index after k[n] such that X[n][K[n]] is NaN.

Notes

X[n][i] is non-NaN for i = k[n], ..., K[n] - 1. K[n] - k[n] is the size of the first contiguous block of valid values of X[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 k such that X[k] is finite. If X[i] is NaN for all i, then k = len(X).

Kint

If X[i] is NaN for all i > k, then K = len(X). If X[i] is finite for all i > k, then K = len(X). Otherwise, K is the first index after k such that X[K] is NaN.

Notes

X[i] is non-NaN for i = k, ..., K - 1. K - k is the size of the first contiguous block of valid values of X.

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 k such that X[k] and Y[k] are finite. If X[i] or Y[i] is NaN for all i, then k = len(X).

Kint

If X[i] or Y[i] is NaN for all i > k, then K = len(X). If X[i] and Y[i] are finite for all i > k, then K = len(X). Otherwise, K is the first index after k such that X[K] or Y[K] is NaN.

Notes

X[i] and Y[i] are both non-NaN for i = k, ..., K - 1. K - k is the size of the first contiguous block of valid pairs of values of (X, Y).

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 () when f is univariate.

Returns:
float

Value of x where f(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) and f(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 < b and ideally f(a) * f(b) <= 0

tfloat

Tolerance for convergence.

argstuple

Additional arguments, beyond the optimization argument, to be passed to f. Pass () when f is univariate.

Returns:
float

Value of x where f(x) ~ 0.

Notes

f should be a @numba.njit’ed function (when this function is njit’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

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 () when f is univariate.

Returns:
a, bfloat

Lower and upper bounds within which f(x) changes sign.

Library functions

neutralocean.lib.find_first_nan(a)[source]

The index to the first NaN along the last axis

Parameters:
andarray

Input array possibly containing some NaN elements

Returns:
kndarray of int

The index to the first NaN along each 1D array making up a, as in the following example with a being 3D. If all a[i,j,:] are NaN, then k[i,j] = 0. If all a[i,j,:] are not NaN, then k[i,j] = a.shape[-1]. Otherwise, K = k[i,j] is the smallest int such that a[i,j,K-1] is not NaN, but a[i,j,K] is NaN.

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 T along its last dimension. Can be an int or (n-1)D.

Returns:
Tkndarray

The input T evaluated with its last index equal to k.

Notes

If T is 3D and k is 2D, then Tk[i,j] = T[i,j,k[i,j]] for each valid (i,j).

If T is 1D and k is 2D, then Tk[i,j] = T[k[i,j]] for each valid (i,j).

If T is 3D and k is an int, then Tk[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.]])