nemo_eos
August 14, 2024 · View on GitHub
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) inputsTandSare Conservative Temperature and Absolute Salinity -
(
neos=-1) MacDougall and Jackett 1994; Macdougall 1987 inputsTandSare potential temperature and practical salinity (psu) -
(
neos=0) polynomial approximation to EOS-80 (Roquet, pers. comm.) inputsTandSare 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.
Pre-installation
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 miniforge
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
Installation
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.
Available routines
-
eos_init(neos): Set EOS type -
set_eos_threads(nthreads): Specify numbernthreadsof 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-rfrom float64depthin m. (Roquet et al., 2015) -
eos_insitu4(T, S, depth):float32in situ density for 1Dfloat32arrays ofT, S, depth -
eos_insitu4_m(fillvalue, mask, T, S, depth): returns in situ density for 1Dfloat32arrays ofT, S,depthwhere 1D Boolean arraymask=Falseand returnsfloat32valuefill_valuewheremask=True. -
eos_sigman4(T, S, depth_km):float32potential density referenced tofloat32depthdepth_kmkm for 1Dfloat32arraysT, S -
eos_sigman4_m(fillvalue, mask, T, S, depth_km): masked version ofeos_sigman4 -
eos_sigma04(T, S, depth_km):float32potential density referenced to the surface for 1Dfloat32arraysT, S -
eos_sigma04(T, S, depth_km): masked version ofeos_sigma04. -
eos_rab4( T, S, depth, alpha, beta): returnsfloat321-D arrays of in situ alpha and beta for 1Dfloat32arrays 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): returnsfloat321-D arrays of alpha and beta referenced tofloat32d epthdepth_kmfor 1Dfloat32arrays ofT, S. -
eos_rab_ref4_m: masked version ofeos_rab_ref4 -
eos_pen4(T, S, depth, alpha_pe, beta_be, ppen: returnsfloat321-D arrays of non-linear PE anomaly driven by temperature variations (alpha_pe), salinity variations (beta_pe), and total PE (ppen) for 1Dfloat32arrays ofT, Sanddepth. -
eos_insitu04(T0, S0, depth_km, depth): returns 1Dfloat32arrays of difference between in situ density at 1D depth arraydepthand potential density at depthdepth_kmforfloat32temperature and salinity variablesT0andS0 -
eos_insitu04_m(fillvalue, mask, T0, S0, depth_km, depth): masked version of eos_insitu04
Public variables accessible to python include:
- 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
Test and check sensitivity of speed to number of threads
If the gsw package is installed comparisons are made with its speed
and the values it produces; otherwise it is just internal comparisons.
Check test values OK
cd test
python set_test.py
Examine sensitivity to number of threads
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
Explore
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
In [5]: eos.eos_insitu4_m
Then type ?
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)