f2py'd versions of NEMO Fortran routines coded by Gurvan Madec, Fabien Roquet and others used to calculate density, thermal coefficient of expansion etc that can be called by a python script or by ipython or jupyter lab. Depending on how it is initialised, uses:
-
(
neos=2
) polynomial TEOS-10 EOS (Roquet et al., 2015) inputsT
andS
are Conservative Temperature and Absolute Salinity -
(
neos=-1
) MacDougall and Jackett 1994; Macdougall 1987 inputsT
andS
are potential temperature and practical salinity (psu) -
(
neos=0
) polynomial approximation to EOS-80 (Roquet, pers. comm.) inputsT
andS
are potential temperature and practical salinity (psu) -
(
neos=1
) Simplified EOS (Vallis, 2006)
Currently requires to be installed into an already existing conda/mamba python environment. If this environment does not exist, setup as described in Pre-installation, below.
I suggest that you use a conda or mamba installation of python. If you have neither, mamba is the one to install at is it faster and more reliable. First make sure that you have a ~/.bash_profile
file that reads your ~/.bashrc
i.e the ~/.bash_profile
file includes lines like
if [ -f ~/.bashrc ]; then
. ~/.bashrc # --> Read ~/.bashrc, if present.
fi
If the file~/.bash_profile
does not include such lines, then add the above, ideally immediately after /etc/bashrc
is read
If you have no ~/.bash_profile
file then create one:
Edit ~/.bash_profile
with whatever editor you use, E.g. open the file with vi
:
vi ~/.bash_profile
i
Paste the code below into vi
# not necessary but probably useful
if [ -f /etc/bashrc ]; then
. /etc/bashrc # --> Read /etc/bashrc, if present.
fi
# essential
if [ -f ~/.bashrc ]; then
. ~/.bashrc # --> Read ~/.bashrc, if present.
fi
Hit esc
and then :wq
Then download the miniforge installer, and run it:
cd
# Remove any old python setups
rm -rf miniconda3 anaconda mambaforge
wget https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-Linux-x86_64.sh
sh Miniforge3-Linux-x86_64.sh
Follow prompts; say yes to modifying .bashrc
so that base
environment is activated on login
Then create environment that you will use for diagnosis and into which
the nemo_eos package will go. I suggest xarray
, ipython
and
gsw
(for an alternative TEOS-10 EOs library to check against); you will wish to add others.
mamba create -n big python=3.10 xarray ipython
and move into this environment
mamba activate big
First go into parent directory into which you want to download the package.
cd </path/to/parent>
Then activate big
environment if not previously done
mamba activate big
Then git clone the source from github and move into new directory
git clone https://github.com/gnurser/nemo_eos.git
cd nemo_eos
Build and install
. install.bash
This first installs some required mamba packages into the big
environment at ~/miniforge3/envs/big/lib/python3.10/site-packages
and then also installs the shared library nemo_rho
into big
.
This enables any python program operating in the big
environment to
use routines as in NEMO that calculate the equation of state. Many of
the routines are accelerated by openMP threads.
-
eos_init(neos)
: Set EOS type -
set_eos_threads(nthreads)
: Specify numbernthreads
of threads that routines use for OpenMP. -
get_eos_threads()
: returns number of threads that routines use for OpenMP. -
get_r0(depth)
: For TEOS10 EOS and new EOS-80 calculate float64 depth-varying offsetr0=rho-r
from float64depth
in m. (Roquet et al., 2015) -
eos_insitu4(T, S, depth)
:float32
in situ density for 1Dfloat32
arrays ofT, S, depth
-
eos_insitu4_m(fillvalue, mask, T, S, depth)
: returns in situ density for 1Dfloat32
arrays ofT, S,depth
where 1D Boolean arraymask=False
and returnsfloat32
valuefill_value
wheremask=True
. -
eos_sigman4(T, S, depth_km)
:float32
potential density referenced tofloat32
depthdepth_km
km for 1Dfloat32
arraysT, S
-
eos_sigman4_m(fillvalue, mask, T, S, depth_km)
: masked version ofeos_sigman4
-
eos_sigma04(T, S, depth_km)
:float32
potential density referenced to the surface for 1Dfloat32
arraysT, S
-
eos_sigma04(T, S, depth_km)
: masked version ofeos_sigma04
. -
eos_rab4( T, S, depth, alpha, beta)
: returnsfloat32
1-D arrays of in situ alpha and beta for 1Dfloat32
arrays ofT, S, depth
. -
eos_rab4_m( fillvalue, mask, T, S, depth, alpha, beta)
: masked version ofeos_rab_ref
-
eos_rab_ref4(T, S, depth_km)
: returnsfloat32
1-D arrays of alpha and beta referenced tofloat32
d epthdepth_km
for 1Dfloat32
arrays ofT, S
. -
eos_rab_ref4_m
: masked version ofeos_rab_ref4
-
eos_pen4(T, S, depth, alpha_pe, beta_be, ppen
: returnsfloat32
1-D arrays of non-linear PE anomaly driven by temperature variations (alpha_pe
), salinity variations (beta_pe
), and total PE (ppen
) for 1Dfloat32
arrays ofT, S
anddepth
. -
eos_insitu04(T0, S0, depth_km, depth)
: returns 1Dfloat32
arrays of difference between in situ density at 1D depth arraydepth
and potential density at depthdepth_km
forfloat32
temperature and salinity variablesT0
andS0
-
eos_insitu04_m(fillvalue, mask, T0, S0, depth_km, depth)
: masked version of eos_insitu04
- Default Boussinesq ocean density
rho0
, EOS typeneos
- Coefficients for Vallis's simplified EOS:
rn_lambda1, rn_nu, rn_lambda2, rn_mu1, rn_mu2, rn_a0, rn_b0
If the gsw
package is installed comparisons are made with its speed
and the values it produces; otherwise it is just internal comparisons.
cd test
python set_test.py
cd test
ipython threads.ipy
Default is to test for array 1e6 long, and 1 vs 4 threads. Can do 1
vs
nthreads
and change array_length with the following. Note spaces
and double dash. Experience so far suggests nthreads=4
is good on
a laptop, but can increase to nthreads=16
on a unix server;
gives a speedup of at least 10x.
ipython -- threads.ipy --nthreads=16 --array_length=1.e7
I have suggested using ipython
here for simpliciy, but of course the below will also work in a Jupyter lab window.
ipython
Python 3.10.13 | packaged by conda-forge | (main, Dec 23 2023, 15:36:59) [Clang| 16.0.6 ]
Type 'copyright', 'credits' or 'license' for more information
IPython 8.22.1 -- An enhanced Interactive Python. Type '?' for help.
In [1]: from nemo_eos.nemo_rho import eos
In [2]: eos.rho0
Out[2]: array(1026.)
In [3]: eos.set_eos_threads(16)
In [4]: eos.get_eos_threads()
Out[4]: 16
Type in eos.<TAB>
to get list of functions, options, constants etc. Then select routine with cursor keys
In [5]: eos.eos_insitu4_m
eos_init eos_insitu4_m eos_rab_ref4 eos_sigman4 neos rn_lambda1 rn_nu
eos_insitu04 eos_pen4 eos_rab_ref4_m eos_sigman4_m rho0 rn_lambda2 set_eos
eos_insitu04_m eos_rab4 eos_sigma04 get_eos_threads rn_a0 rn_mu1 set_eos_threads
eos_insitu4 eos_rab4_m eos_sigma04_m get_r0 rn_b0 rn_mu2
Then when desired routine is selected, type and other options will disappear
In [5]: eos.eos_insitu4_m
Then type ?, and ipython will give description of how to call the routine:
In [5]: eos.eos_insitu4_m?
Call signature: eos.rho_mn4(*args, **kwargs)
Type: fortran
String form: <fortran function eos_insitu4_m>
Docstring:
rho = eos_insitu4_m(fillvalue,mask,theta,s,depth,[n])
Wrapper for `eos_insitu4_m`.
Parameters
----------
fillvalue : input float
mask : input rank-1 array('b') with bounds (n)
theta : input rank-1 array('f') with bounds (n)
s : input rank-1 array('f') with bounds (n)
depth : input rank-1 array('f') with bounds (n)
Other Parameters
----------------
n : input int, optional
Default: shape(mask, 0)
Returns
-------
rho : rank-1 array('f') with bounds (n)