Test/gw_ocean_refstate.py

230 lines
12 KiB
Python

def refstate_meandensity(rho_in,grd,area_xyz_in):
# refstate_meandensity(rho,zlev,area_xyz) ################################################
# written by : Gabriel Wolf, g.a.wolf@reading.ac.uk
# adapted from get_refstate_meandensity.m of Remi Tailleux (10.04.2013)
# last modified : 20.09.2018
# Content/Description ####################################################################
# Usage : from gw_ocean_refstate import refstate_meandensity
# Input : area_xyz, rho, zlev
# area_xyz : hor. area for 3d grid [m**2], 3d
# rho : density [kg m**-3], 3d
# grd : Input grid [python class]
# Output : pp_rhor
# pp_rhor : interpolant for reference state
# ########################################################################################
# Load modules
import numpy as np
from scipy import interpolate
import pickle # To load interpolants of bathymetry data
# Allocation
rhor = np.zeros([grd.Nz,1])
# compute hor. averaged density field
rho_surf = area_xyz_in*rho_in
mask = np.isfinite(rho_surf)
rhor = sum(sum(mask*rho_surf,1),0)/sum(sum(area_xyz_in*mask,1),0)
# define arrays for interpolation of density profiles
pp_rhor = interpolate.PchipInterpolator(grd.z, rhor, axis=0)
# return interpolant for reference state
return pp_rhor
def refstate_sorted_stheta(th,s,rho,mask,ztarget,grd,sbin=[0.0,43.0,0.002],\
thbin=[-2.6,30.0,0.005],ref_EOS='jackettetal2004',test=False,case_str=[]):
# refstate_sorted_stheta(th,s,rho,mask,ztarget,grd,test) #################################
# written by : Gabriel Wolf, g.a.wolf@reading.ac.uk
# adapted from get_refstate_sorted.m of Remi Tailleux (10.04.2013)
# last modified : 24.09.2018
# Content/Description ####################################################################
# Reference : method based on Tailleux (2013), -> https://doi.org/10.1017/jfm.2013.509
# : summary of this framework in Saenz et al. (2015):
# -> https://doi.org/10.1175/JPO-D-14-0105.1
# Usage : from gw_ocean_refstate import refstate_sorted_stheta
# Input : grd, mask, ,ref_equofstate, rho, s, sbin, test, thbin, th, ztarget
# grd : Input grid [python class]
# mask : valid points [boolean], 3d
# ref_EOS : defines equ. of state [reference]
# : reference def. by publication, e.g. author1year for one author-public.,
# : author1andauthor2year for 2-author-public. or author1etalyear for more
# : than 2 authors
# rho : density [kg m**-3], 3d
# s : salinity [psu], 3d
# sbin : bin range for s to construct s-th-diagram [min,max,delta]
# test : further test plotting and value checking [boolean], 1d
# th : potential temperature [deg C], 3d
# thbin : bin range for th to construct s-th-diagram [min,max,delta]
# ztarget : target height level [m], 1d
# Output :pp_rhor_botup, pp_rhor_topdn
# pp_rhor_botup : interpolant for density reference state (calc. from bottom up)
# pp_rhor_topdn : interpolant for density reference state (calc. from bottom up)
# Testing : plot_sth_pdf
# plot_sth_pdf : plotting of sorted ocena-volumes in the S-TH-diagram
# ########################################################################################
# Testing variables %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
plot_sth_pdf = 1*test
if plot_sth_pdf == 1:
print ' Create test plot for sorted ocean-volumes in S-Th-diagram'
from myplot import myplot_2d
# Load modules %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
import numpy as np
from scipy import interpolate # for interpolation
from mycalc_ocean import calc_rho_from_theta, volume_census_levitus
# calc_rho_from_theta : to calculate density from pot. temperature
# volume_census_levitus : to create s-th-pdf with vol info
from myconstants import rho0, grav # necessary constants
# Allocation %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
n_target = len(ztarget)
s[mask==False] = np.nan
th[mask==False] = np.nan
rho[mask==False] = np.nan
# Compute the pdf of the salinity/theta data %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
try:
import pickle
with open('data_pdf_salth' + case_str + '.pickle', 'rb') as data_pdf:
dummy = pickle.load(data_pdf)
pdf_vol_lev = dummy[0]
vol_tot_ocean = dummy[1]
del dummy, data_pdf
pdf_vol_lev_norm = pdf_vol_lev/vol_tot_ocean
except:
pdf_vol_lev, vol_tot_ocean = volume_census_levitus(th, s, grd, thbin, sbin)
print ' Total volume ocean: ' + str(vol_tot_ocean) + ' m**3'
pdf_vol_lev_norm = pdf_vol_lev/vol_tot_ocean
import pickle
with open('data_pdf_salth' + case_str + '.pickle', 'wb') as output:
pdf_salth = [pdf_vol_lev, vol_tot_ocean]
pickle.dump(pdf_salth, output, -1)
# Define properties of the binned temperature/salinity data %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
print ' *** MISSING: property definition of binned temperature/salinity data ***'
n_sbin, n_thbin = pdf_vol_lev.shape
s_axis = np.arange(sbin[0]+sbin[2]*0.5,sbin[1],sbin[2])
th_axis = np.arange(thbin[0]+thbin[2]*0.5,thbin[1],thbin[2])
# Testing pdf-output (pdf_vol_lev_norm)
if plot_sth_pdf:
d_step = 1
xxx = np.arange(sbin[0],sbin[1],sbin[2]*d_step)
yyy = yyy=np.arange(thbin[0],thbin[1],thbin[2]*d_step)
ddd = pdf_vol_lev_norm[::d_step,::d_step]
ddd[ddd==0] = np.nan
ddd = np.log10(ddd)
print 'np.nanmax(ddd) = ',np.nanmax(ddd)
import datetime
plotname = 'Testplot_for_oceanvol_in_s_th_diagram_' + \
str(datetime.date.today()) + case_str + '.png'
myplot_2d(xxx,yyy,ddd.T,xlabel_c='salinity [psu]',ylabel_c='potential temp. [deg C]',\
plotname=plotname,saveplot=1,FS=14,d_xtick=0.2,title_c='S-TH',\
cbarlabel_c='Volume freq. distribution [log_10]')
#import pdb
#pdb.set_trace()
#iprint 'stop here'
del xxx, yyy, ddd
# define target pressure from target depths %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
ptarget = rho0 * grav * ztarget / 1e4
n_target = len(ptarget)
print ' *** why using constant density for target pressure and not variable one? ***'
# Seek the global min. and max. of density by bringing all parcels to the ocean surface
# (to find min.) and to ocean bottom (to find max.) --------------------------------------
# Allocation
rho_theta_surf = rho
rho_theta_deep = rho
p_surf = np.ones([grd.Nlon,grd.Nlat,grd.Nz])*ptarget[0]
p_deep = np.ones([grd.Nlon,grd.Nlat,grd.Nz])*ptarget[-1]
# Compute potential density reference to target pressure at surface
rho_theta_surf[mask] = calc_rho_from_theta(s[mask],th[mask],p_surf[mask],reference=ref_EOS)
# Compute potential density referenced to last target pressure
rho_theta_deep[mask] = calc_rho_from_theta(s[mask],th[mask],p_deep[mask],reference=ref_EOS)
# Compute global density minimum and maximum
rho_min = np.min(rho_theta_surf[mask])
rho_max = np.max(rho_theta_deep[mask])
# Compute upper and lower salinity curves in theta/salt space %%%%%%%%%%%%%%%%%%%%%%%%%%%%
# Allocation
s_lower = np.zeros(n_thbin)
s_upper = np.zeros(n_thbin)
# Computation
s_lower = calc_sal_from_rho(rho_min,th_axis,ptarget[0],reference=ref_EOS)
s_upper = calc_sal_from_rho(rho_max,th_axis,ptarget[-1],reference=ref_EOS)
# Compute the topography statistics %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
print ' Load topographic data for z-dependent ocean area and volume'
# Load or calculate z-dep. ocean area/volume
fn_topo = 'interp_of_topo' + '.pickle'
try:
with open(fn_topo, 'rb') as data_interp:
dummy = pickle.load(data_interp)
pp_area = dummy[0]
pp_volume = dummy[1]
del dummy, data_interp
except:
print ' -> Data could not be loaded. Therefore it will be calculated.'
pp_area, pp_volume = volume_etopo(fn_topo)
del fn_topo
# define z-dep. volume and its fraction
vol_target = pp_volume(ztarget)
frac_vol_target = vol_target/vol_target[-1]
# New attempt to compute the top-down profile %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
print ' Computing top-down profile for reference density'
# Allocation/Initialization
rhor_topdn = np.zeros(n_target)
rhor_topdn[0] = rho_min
rhor_topdn[-1] = rho_max
s_curves_td = np.zeros([n_target,n_thbin])
s_curves_td[0,:] = s_lower
s_curves_td[-1,:] = s_upper
scurv = np.copy(s_lower)
rho_l = np.copy(rho_min)
# Use optimization method to converge to correct salinity curve
print ' *** this loop is not necessary ***'
for i_iter in range(0,n_target-1):
rho_u = calc_rho_from_theta(sbin[1],thbin[0],ptarget[i_iter+1])
func = lambda rho_i : volume_from_sth(rho_i, pdf_vol_lev_norm,\
th_axis, ptarget[i_iter+1], scurv, sbin) - \
(frac_vol_target[i_iter+1]-frac_vol_target[i_iter])
rhor_topdn[i_iter+1] = fsolve(func, np.array([rho_l,rho_u]))
s_curves_td[i_iter+1,:] = calc_sal_from_rho(rhor_topdn[i_iter+1]*np.ones(n_thbin),\
th_axis,ptarget[i_iter+1]*np.ones(n_thbin))
s_curv = s_curves_td[i_iter+1,:]
rho_l = rhor_topdn[i_iter+1]
print ' -> [iter(target) rhor_topdn(iter) rho_l rho_u]',\
[i_iter,rhor_topdn[i_iter+1],rho_l, rho_u]
# New attempt at computing bottom-up profile %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
print ' *** MISSING: rhor bottom-up profile ***'
print ' Computing bottom-up profile for reference density'
# Allocation/Initialization
rhor_botup = np.zeros(n_target)
rhor_botup[0] = rho_min
rhor_botup[-1] = rho_max
s_curves_bu = np.zeros([n_target,n_thbin])
s_curves_bu[0,:] = s_lower
s_curves_bu[-1,:] = s_upper
scurv = np.copy(s_upper)
rho_u = np.copy(rho_max)
# Use optimization method to converge to correct salinity curve
print ' *** this loop is not necessary ***'
for i_iter in range(n_target-1,1,-1):
rho_l = calc_rho_from_theta(sbin[0],thbin[1],ptarget[i_iter-1])
func = lambda rho_i : vol_from_sth(rho_i, pdf_vol_lev_norm,\
th_axis, ptarget[i_iter-1],scurv, sbin) - \
(frac_vol_target[i_iter]-frac_vol_target[i_iter-1])
rhor_botup[i_iter+1] = fsolve(func, np.array([rho_l,rho_u]))
s_curves_bu[i_iter-1,:] = calc_sal_from_rho(rhor_botup[i_iter-1]*np.ones(n_thbin),\
th_axis,ptarget[i_iter-1]*np.ones(n_thbin))
s_curv = s_curves_bu[i_iter-1,:]
rho_u = rhor_botup[i_iter-1]
print ' -> [iter(target) rhor_botup(iter) rho_l rho_u]',\
[i_iter,rhor_botup[i_iter+1],rho_l, rho_u]
# Assign interpolants for the two possible reference states %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
pp_rhor_botup = interpolate.PchipInterpolator(ztarget, rhor_botup, axis=0)
pp_rhor_topdn = interpolate.PchipInterpolator(ztarget, rhor_topdn, axis=0)
# return interpolant for the two reference states %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
return pp_rhor_botup, pp_rhor_topdn