Commit b8115ade authored by sbiri's avatar sbiri
Browse files

Update AirSeaFluxCode.py, flux_subs.py, get_init.py, hum_subs.py, data_all.nc,...

Update AirSeaFluxCode.py, flux_subs.py, get_init.py, hum_subs.py, data_all.nc, Documentation.pdf, era5_r360x180.nc, run_ASFC.py files
Deleted data_Mxtr.nc, data_mod.nc, data_trp.nc, data_xtr.nc files
parent 8ce9ad6c
...@@ -53,8 +53,8 @@ def AirSeaFluxCode(spd, T, SST, lat=None, hum=None, P=None, ...@@ -53,8 +53,8 @@ def AirSeaFluxCode(spd, T, SST, lat=None, hum=None, P=None,
"S80","S88","LP82","YT96","UA","LY04","C30","C35","C40","ERA5" "S80","S88","LP82","YT96","UA","LY04","C30","C35","C40","ERA5"
qmeth : str qmeth : str
is the saturation evaporation method to use amongst is the saturation evaporation method to use amongst
"HylandWexler","Hardy","Preining","Wexler","GoffGratch","CIMO", "HylandWexler","Hardy","Preining","Wexler","GoffGratch","WMO",
"MagnusTetens","Buck","Buck2","WMO","WMO2000","Sonntag","Bolton", "MagnusTetens","Buck","Buck2","WMO2018","Sonntag","Bolton",
"IAPWS","MurphyKoop"] "IAPWS","MurphyKoop"]
default is Buck2 default is Buck2
tol : float tol : float
...@@ -76,10 +76,10 @@ def AirSeaFluxCode(spd, T, SST, lat=None, hum=None, P=None, ...@@ -76,10 +76,10 @@ def AirSeaFluxCode(spd, T, SST, lat=None, hum=None, P=None,
Returns Returns
------- -------
res : array that contains res : array that contains
1. momentum flux (W/m^2) 1. momentum flux (N/m^2)
2. sensible heat (W/m^2) 2. sensible heat (W/m^2)
3. latent heat (W/m^2) 3. latent heat (W/m^2)
4. Monin-Obhukov length (mb) 4. Monin-Obhukov length (m)
5. drag coefficient (cd) 5. drag coefficient (cd)
6. neutral drag coefficient (cdn) 6. neutral drag coefficient (cdn)
7. heat exhange coefficient (ct) 7. heat exhange coefficient (ct)
...@@ -104,10 +104,15 @@ def AirSeaFluxCode(spd, T, SST, lat=None, hum=None, P=None, ...@@ -104,10 +104,15 @@ def AirSeaFluxCode(spd, T, SST, lat=None, hum=None, P=None,
26. temperature at reference height (tref) 26. temperature at reference height (tref)
27. specific humidity at reference height (qref) 27. specific humidity at reference height (qref)
28. number of iterations until convergence 28. number of iterations until convergence
ind : int 29. cool-skin temperature depression (dter)
the indices in the matrix for the points that did not converge 30. cool-skin humidity depression (dqer)
after the maximum number of iterations 31. specific humidity of air (qair)
The code is based on bform.f and flux_calc.R modified by S. Biri 32. specific humidity at sea surface (qsea)
33. downward longwave radiation (Rl)
34. downward shortwave radiation (Rs)
35. downward net longwave radiation (Rnl)
2020 / Author S. Biri
""" """
logging.basicConfig(filename='flux_calc.log', logging.basicConfig(filename='flux_calc.log',
format='%(asctime)s %(message)s',level=logging.INFO) format='%(asctime)s %(message)s',level=logging.INFO)
...@@ -135,6 +140,7 @@ def AirSeaFluxCode(spd, T, SST, lat=None, hum=None, P=None, ...@@ -135,6 +140,7 @@ def AirSeaFluxCode(spd, T, SST, lat=None, hum=None, P=None,
np.nanmedian(qsea), np.nanmedian(qair)) np.nanmedian(qsea), np.nanmedian(qair))
if (np.all(np.isnan(qsea)) or np.all(np.isnan(qair))): if (np.all(np.isnan(qsea)) or np.all(np.isnan(qair))):
print("qsea and qair cannot be nan") print("qsea and qair cannot be nan")
# tlapse = gamma_moist(SST, T, qair/1000) lapse rate can be computed like this
dt = Ta - sst dt = Ta - sst
dq = qair - qsea dq = qair - qsea
# first guesses # first guesses
...@@ -289,7 +295,7 @@ def AirSeaFluxCode(spd, T, SST, lat=None, hum=None, P=None, ...@@ -289,7 +295,7 @@ def AirSeaFluxCode(spd, T, SST, lat=None, hum=None, P=None,
elif (tol[0] == 'all'): elif (tol[0] == 'all'):
new = np.array([np.copy(u10n), np.copy(t10n), np.copy(q10n), new = np.array([np.copy(u10n), np.copy(t10n), np.copy(q10n),
np.copy(tau), np.copy(sensible), np.copy(latent)]) np.copy(tau), np.copy(sensible), np.copy(latent)])
d = np.fabs(new-old) d = np.abs(new-old)
if (tol[0] == 'flux'): if (tol[0] == 'flux'):
ind = np.where((d[0, :] > tol[1])+(d[1, :] > tol[2]) + ind = np.where((d[0, :] > tol[1])+(d[1, :] > tol[2]) +
(d[2, :] > tol[3])) (d[2, :] > tol[3]))
...@@ -305,6 +311,7 @@ def AirSeaFluxCode(spd, T, SST, lat=None, hum=None, P=None, ...@@ -305,6 +311,7 @@ def AirSeaFluxCode(spd, T, SST, lat=None, hum=None, P=None,
else: else:
ii = True ii = True
itera[ind] = -1 itera[ind] = -1
# itera = np.where(itera > n, -1, itera)
logging.info('method %s | # of iterations:%s', meth, it) logging.info('method %s | # of iterations:%s', meth, it)
logging.info('method %s | # of points that did not converge :%s', meth, logging.info('method %s | # of points that did not converge :%s', meth,
ind[0].size) ind[0].size)
......
No preview for this file type
File deleted
File added
File deleted
File deleted
File deleted
File added
...@@ -32,7 +32,7 @@ def cdn_calc(u10n, Ta, Tp, lat, meth="S80"): ...@@ -32,7 +32,7 @@ def cdn_calc(u10n, Ta, Tp, lat, meth="S80"):
np.where((u10n <= 25) & (u10n >= 11), np.where((u10n <= 25) & (u10n >= 11),
(0.49+0.065*u10n)*0.001, 1.14*0.001)) (0.49+0.065*u10n)*0.001, 1.14*0.001))
elif (meth == "S88" or meth == "UA" or meth == "ERA5" or meth == "C30" or elif (meth == "S88" or meth == "UA" or meth == "ERA5" or meth == "C30" or
meth == "C35" or meth == "C40"): meth == "C35" or meth == "C40" or meth == "Beljaars"):
cdn = cdn_from_roughness(u10n, Ta, None, lat, meth) cdn = cdn_from_roughness(u10n, Ta, None, lat, meth)
elif (meth == "YT96"): elif (meth == "YT96"):
# for u<3 same as S80 # for u<3 same as S80
...@@ -101,7 +101,7 @@ def cdn_from_roughness(u10n, Ta, Tp, lat, meth="S88"): ...@@ -101,7 +101,7 @@ def cdn_from_roughness(u10n, Ta, Tp, lat, meth="S88"):
a = 0.011*np.ones(Ta.shape) a = 0.011*np.ones(Ta.shape)
a = np.where(u10n > 22, 0.0016*22-0.0035, 0.0016*u10n-0.0035) a = np.where(u10n > 22, 0.0016*22-0.0035, 0.0016*u10n-0.0035)
zo = a*np.power(usr, 2)/g+0.11*visc_air(Ta)/usr # surface roughness zo = a*np.power(usr, 2)/g+0.11*visc_air(Ta)/usr # surface roughness
elif (meth == "ERA5"): elif ((meth == "ERA5" or meth == "Beljaars")):
# eq. (3.26) p.38 over sea IFS Documentation cy46r1 # eq. (3.26) p.38 over sea IFS Documentation cy46r1
zo = 0.018*np.power(usr, 2)/g+0.11*visc_air(Ta)/usr zo = 0.018*np.power(usr, 2)/g+0.11*visc_air(Ta)/usr
else: else:
...@@ -209,7 +209,7 @@ def ctcqn_calc(zol, cdn, u10n, zo, Ta, meth="S80"): ...@@ -209,7 +209,7 @@ def ctcqn_calc(zol, cdn, u10n, zo, Ta, meth="S80"):
# 5e-5/np.power(rr, 0.6)) # moisture roughness as in C30 # 5e-5/np.power(rr, 0.6)) # moisture roughness as in C30
cqn = kappa**2/np.log(10/zo)/np.log(10/zoq) cqn = kappa**2/np.log(10/zo)/np.log(10/zoq)
ctn = kappa**2/np.log(10/zo)/np.log(10/zot) ctn = kappa**2/np.log(10/zo)/np.log(10/zot)
elif (meth == "ERA5"): elif (meth == "ERA5" or meth == "Beljaars"):
# eq. (3.26) p.38 over sea IFS Documentation cy46r1 # eq. (3.26) p.38 over sea IFS Documentation cy46r1
usr = np.sqrt(cdn*np.power(u10n, 2)) usr = np.sqrt(cdn*np.power(u10n, 2))
zot = 0.40*visc_air(Ta)/usr zot = 0.40*visc_air(Ta)/usr
...@@ -274,8 +274,8 @@ def get_stabco(meth="S80"): ...@@ -274,8 +274,8 @@ def get_stabco(meth="S80"):
""" """
alpha, beta, gamma = 0, 0, 0 alpha, beta, gamma = 0, 0, 0
if (meth == "S80" or meth == "S88" or meth == "LY04" or if (meth == "S80" or meth == "S88" or meth == "LY04" or
meth == "UA" or meth == "ERA5" or meth == "C30" or meth == "C35" or meth == "UA" or meth == "ERA5" or meth == "C30" or
meth == "C40"): meth == "C35" or meth == "C40" or meth == "Beljaars"):
alpha, beta, gamma = 16, 0.25, 5 # Smith 1980, from Dyer (1974) alpha, beta, gamma = 16, 0.25, 5 # Smith 1980, from Dyer (1974)
elif (meth == "LP82"): elif (meth == "LP82"):
alpha, beta, gamma = 16, 0.25, 7 alpha, beta, gamma = 16, 0.25, 7
...@@ -308,6 +308,8 @@ def psim_calc(zol, meth="S80"): ...@@ -308,6 +308,8 @@ def psim_calc(zol, meth="S80"):
psim = psim_era5(zol) psim = psim_era5(zol)
elif (meth == "C30" or meth == "C35" or meth == "C40"): elif (meth == "C30" or meth == "C35" or meth == "C40"):
psim = psiu_26(zol, meth) psim = psiu_26(zol, meth)
elif (meth == "Beljaars"): # Beljaars (1997) eq. 16, 17
psim = np.where(zol < 0, psim_conv(zol, meth), psi_Bel(zol))
else: else:
psim = np.where(zol < 0, psim_conv(zol, meth), psim = np.where(zol < 0, psim_conv(zol, meth),
psim_stab(zol, meth)) psim_stab(zol, meth))
...@@ -334,6 +336,8 @@ def psit_calc(zol, meth="S80"): ...@@ -334,6 +336,8 @@ def psit_calc(zol, meth="S80"):
psi_era5(zol)) psi_era5(zol))
elif (meth == "C30" or meth == "C35" or meth == "C40"): elif (meth == "C30" or meth == "C35" or meth == "C40"):
psit = psit_26(zol) psit = psit_26(zol)
elif (meth == "Beljaars"): # Beljaars (1997) eq. 16, 17
psit = np.where(zol < 0, psi_conv(zol, meth), psi_Bel(zol))
else: else:
psit = np.where(zol < 0, psi_conv(zol, meth), psit = np.where(zol < 0, psi_conv(zol, meth),
psi_stab(zol, meth)) psi_stab(zol, meth))
...@@ -341,6 +345,26 @@ def psit_calc(zol, meth="S80"): ...@@ -341,6 +345,26 @@ def psit_calc(zol, meth="S80"):
# --------------------------------------------------------------------- # ---------------------------------------------------------------------
def psi_Bel(zol):
""" Calculates momentum/heat stability function
Parameters
----------
zol : float
height over MO length
meth : str
parameterisation method
Returns
-------
psit : float
"""
a, b, c, d = 0.7, 0.75, 5, 0.35
psi = -(a*zol+b*(zol-c/d)*np.exp(-d*zol)+b*c/d)
return psi
# ---------------------------------------------------------------------
def psi_era5(zol): def psi_era5(zol):
""" Calculates heat stability function for stable conditions """ Calculates heat stability function for stable conditions
for method ERA5 for method ERA5
...@@ -578,8 +602,11 @@ def get_skin(sst, qsea, rho, Rl, Rs, Rnl, cp, lv, tkt, usr, tsr, qsr, lat): ...@@ -578,8 +602,11 @@ def get_skin(sst, qsea, rho, Rl, Rs, Rnl, cp, lv, tkt, usr, tsr, qsr, lat):
Returns Returns
------- -------
dter : float dter : float
cool-skin temperature depression
dqer : float dqer : float
cool-skin humidity depression
tkt : float
cool skin thickness
""" """
# coded following Saunders (1967) with lambda = 6 # coded following Saunders (1967) with lambda = 6
g = gc(lat, None) g = gc(lat, None)
...@@ -717,7 +744,7 @@ def get_L(L, lat, usr, tsr, qsr, t10n, tv10n, qair, h_in, T, Ta, th, tv, sst, ...@@ -717,7 +744,7 @@ def get_L(L, lat, usr, tsr, qsr, t10n, tv10n, qair, h_in, T, Ta, th, tv, sst,
(np.log((h_in[0]+zo)/zot) - (np.log((h_in[0]+zo)/zot) -
psit_calc((h_in[0]+zo)/monob, meth) + psit_calc((h_in[0]+zo)/monob, meth) +
psit_calc(zot/monob, meth)))) psit_calc(zot/monob, meth))))
monob = h_in[0]/zol monob = h_in[0]/zol
return tsrv, monob return tsrv, monob
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
......
...@@ -73,6 +73,7 @@ def get_init(spd, T, SST, lat, P, Rl, Rs, cskin, gust, L, tol, meth, qmeth): ...@@ -73,6 +73,7 @@ def get_init(spd, T, SST, lat, P, Rl, Rs, cskin, gust, L, tol, meth, qmeth):
MO length switch MO length switch
""" """
# check if input is correct (type, size, value) and set defaults
if ((type(spd) != np.ndarray) or (type(T) != np.ndarray) or if ((type(spd) != np.ndarray) or (type(T) != np.ndarray) or
(type(SST) != np.ndarray)): (type(SST) != np.ndarray)):
sys.exit("input type of spd, T and SST should be numpy.ndarray") sys.exit("input type of spd, T and SST should be numpy.ndarray")
...@@ -82,11 +83,11 @@ def get_init(spd, T, SST, lat, P, Rl, Rs, cskin, gust, L, tol, meth, qmeth): ...@@ -82,11 +83,11 @@ def get_init(spd, T, SST, lat, P, Rl, Rs, cskin, gust, L, tol, meth, qmeth):
sys.exit("input dtype of spd, T and SST should be float") sys.exit("input dtype of spd, T and SST should be float")
# if input values are nan break # if input values are nan break
if meth not in ["S80", "S88", "LP82", "YT96", "UA", "LY04", "C30", "C35", if meth not in ["S80", "S88", "LP82", "YT96", "UA", "LY04", "C30", "C35",
"C40","ERA5"]: "C40", "ERA5", "Beljaars"]:
sys.exit("unknown method") sys.exit("unknown method")
if qmeth not in ["HylandWexler", "Hardy", "Preining", "Wexler", "CIMO", if qmeth not in ["HylandWexler", "Hardy", "Preining", "Wexler",
"GoffGratch", "MagnusTetens", "Buck", "Buck2", "WMO", "GoffGratch", "WMO", "MagnusTetens", "Buck", "Buck2",
"WMO2000", "Sonntag", "Bolton", "IAPWS", "MurphyKoop"]: "WMO2018", "Sonntag", "Bolton", "IAPWS", "MurphyKoop"]:
sys.exit("unknown q-method") sys.exit("unknown q-method")
if (np.all(np.isnan(spd)) or np.all(np.isnan(T)) or np.all(np.isnan(SST))): if (np.all(np.isnan(spd)) or np.all(np.isnan(T)) or np.all(np.isnan(SST))):
sys.exit("input wind, T or SST is empty") sys.exit("input wind, T or SST is empty")
...@@ -107,11 +108,13 @@ def get_init(spd, T, SST, lat, P, Rl, Rs, cskin, gust, L, tol, meth, qmeth): ...@@ -107,11 +108,13 @@ def get_init(spd, T, SST, lat, P, Rl, Rs, cskin, gust, L, tol, meth, qmeth):
meth == "LY04")): meth == "LY04")):
cskin = 0 cskin = 0
elif ((cskin == None) and (meth == "C30" or meth == "C35" or meth == "C40" elif ((cskin == None) and (meth == "C30" or meth == "C35" or meth == "C40"
or meth == "ERA5")): or meth == "ERA5" or meth == "Beljaars")):
cskin = 1 cskin = 1
if (np.all(gust == None) and (meth == "C30" or meth == "C35" or meth == "C40")): if (np.all(gust == None) and (meth == "C30" or meth == "C35" or
meth == "C40")):
gust = [1, 1.2, 600] gust = [1, 1.2, 600]
elif (np.all(gust == None) and (meth == "UA" or meth == "ERA5")): elif (np.all(gust == None) and (meth == "UA" or meth == "ERA5" or
meth == "Beljaars")):
gust = [1, 1, 1000] gust = [1, 1, 1000]
elif np.all(gust == None): elif np.all(gust == None):
gust = [1, 1.2, 800] gust = [1, 1.2, 800]
...@@ -124,7 +127,7 @@ def get_init(spd, T, SST, lat, P, Rl, Rs, cskin, gust, L, tol, meth, qmeth): ...@@ -124,7 +127,7 @@ def get_init(spd, T, SST, lat, P, Rl, Rs, cskin, gust, L, tol, meth, qmeth):
if ((L == None) and (meth == "S80" or meth == "S88" or meth == "LP82" if ((L == None) and (meth == "S80" or meth == "S88" or meth == "LP82"
or meth == "YT96" or meth == "LY04" or or meth == "YT96" or meth == "LY04" or
meth == "UA" or meth == "C30" or meth == "C35" meth == "UA" or meth == "C30" or meth == "C35"
or meth == "C40")): or meth == "C40" or meth == "Beljaars")):
L = "S80" L = "S80"
elif ((L == None) and (meth == "ERA5")): elif ((L == None) and (meth == "ERA5")):
L = "ERA5" L = "ERA5"
......
...@@ -24,19 +24,16 @@ def VaporPressure(temp, P, phase, meth): ...@@ -24,19 +24,16 @@ def VaporPressure(temp, P, phase, meth):
'ice' : Calculate vapor pressure over ice 'ice' : Calculate vapor pressure over ice
meth : str meth : str
formula to be used formula to be used
MartiMauersberger : vaporpressure formula from Marti Mauersberger Hardy : vaporpressure formula from Hardy (1998)
MagnusTetens : vaporpressure formula from Magnus Tetens MagnusTetens : vaporpressure formula from Magnus Tetens
GoffGratch : vaporpressure formula from Goff Gratch GoffGratch : vaporpressure formula from Goff Gratch
Buck_original : vaporpressure formula from Buck (original) Buck : vaporpressure formula from Buck (1981)
Buck_manual : vaporpressure formula from the Buck manual Buck2 : vaporpressure formula from the Buck (2012)
CIMO : vaporpressure formula recommended by CIMO WMO : vaporpressure formula from WMO (1988)
Vaisala : vaporpressure formula from Vaisala WMO2018 : vaporpressure formula from WMO (2018)
WMO_Goff : vaporpressure formula from WMO, which should have been Goff
WMO2000 : vaporpressure formula from WMO (2000) containing a typo
Wexler : vaporpressure formula from Wexler (1976) Wexler : vaporpressure formula from Wexler (1976)
Sonntag : vaporpressure formula from Sonntag (1994) Sonntag : vaporpressure formula from Sonntag (1994)
Bolton : vaporpressure formula from Bolton (1980) Bolton : vaporpressure formula from Bolton (1980)
Fukuta : vaporpressure formula from Fukuta (2003)
HylandWexler : vaporpressure formula from Hyland and Wexler (1983) HylandWexler : vaporpressure formula from Hyland and Wexler (1983)
IAPWS : vaporpressure formula from IAPWS (2002) IAPWS : vaporpressure formula from IAPWS (2002)
Preining : vaporpressure formula from Preining (2002) Preining : vaporpressure formula from Preining (2002)
...@@ -111,12 +108,6 @@ def VaporPressure(temp, P, phase, meth): ...@@ -111,12 +108,6 @@ def VaporPressure(temp, P, phase, meth):
1.3816e-7*(np.power(10, 11.344*(1-T/Ts))-1) + 1.3816e-7*(np.power(10, 11.344*(1-T/Ts))-1) +
8.1328e-3*(np.power(10, -3.49149*(Ts/T-1))-1) + 8.1328e-3*(np.power(10, -3.49149*(Ts/T-1))-1) +
np.log10(ews)) np.log10(ews))
if (meth == 'CIMO'):
"""Source: Annex 4B, Guide to Meteorological Instruments and
Methods of Observation, WMO Publication No 8, 7th edition, Geneva,
2008. (CIMO Guide)"""
Psat = (6.112*np.exp(17.62*temp/(243.12+temp)) *
(1.0016+3.15e-6*P-0.074/P))
if (meth == 'MagnusTetens'): if (meth == 'MagnusTetens'):
"""Source: Murray, F. W., On the computation of \ """Source: Murray, F. W., On the computation of \
saturation vapor pressure, J. Appl. Meteorol., \ saturation vapor pressure, J. Appl. Meteorol., \
...@@ -134,7 +125,7 @@ def VaporPressure(temp, P, phase, meth): ...@@ -134,7 +125,7 @@ def VaporPressure(temp, P, phase, meth):
if (meth == 'Buck2'): if (meth == 'Buck2'):
"""Bucks vapor pressure formulation based on Tetens formula. """Bucks vapor pressure formulation based on Tetens formula.
Source: Buck Research, Model CR-1A Hygrometer Operating Manual, Source: Buck Research, Model CR-1A Hygrometer Operating Manual,
Sep 2001""" May 2012"""
Psat = (6.1121*np.exp((18.678-(temp)/234.5)*(temp)/(257.14+temp)) * Psat = (6.1121*np.exp((18.678-(temp)/234.5)*(temp)/(257.14+temp)) *
(1+1e-4*(7.2+P*(0.0320)+5.9e-6*np.power(T, 2)))) (1+1e-4*(7.2+P*(0.0320)+5.9e-6*np.power(T, 2))))
if (meth == 'WMO'): if (meth == 'WMO'):
...@@ -147,18 +138,12 @@ def VaporPressure(temp, P, phase, meth): ...@@ -147,18 +138,12 @@ def VaporPressure(temp, P, phase, meth):
Ts = 273.16 # triple point temperature in K Ts = 273.16 # triple point temperature in K
Psat = np.power(10, 10.79574*(1-Ts/T)-5.028*np.log10(T/Ts) + Psat = np.power(10, 10.79574*(1-Ts/T)-5.028*np.log10(T/Ts) +
1.50475e-4*(1-np.power(10, -8.2969*(T/Ts-1))) + 1.50475e-4*(1-np.power(10, -8.2969*(T/Ts-1))) +
0.42873e-3*(np.power(10, -4.76955*(1-Ts/T))-1) + 0.42873e-3*(np.power(10, 4.76955*(1-Ts/T))-1) + # in eq. 13 is -4.76955; in aerobulk is like this
0.78614)
if (meth == 'WMO2000'):
"""WMO formulation, which is very similar to Goff & Gratch.
Source : WMO technical regulations, WMO-NO 49, Vol I, General
Meteorological Standards and Recommended Practices, App. A,
Corrigendum Aug 2000."""
Ts = 273.16 # triple point temperature in K
Psat = np.power(10, 10.79574*(1-Ts/T)-5.028*np.log10(T/Ts) +
1.50475e-4*(1-np.power(10, -8.2969*(T/Ts-1))) +
0.42873e-3*(np.power(10, -4.76955*(1.-Ts/T))-1) +
0.78614) 0.78614)
if (meth == 'WMO2018'):
"""WMO 2018 edition. Annex 4.B, eq. 4.B.1, 4.B.2, 4.B.5 """
Psat = 6.112*np.exp(17.62*temp/(243.12+temp))*(1.0016+3.15e-6*P -
0.074/P)
if (meth == 'Sonntag'): if (meth == 'Sonntag'):
"""Source: Sonntag, D., Advancements in the field of hygrometry, """Source: Sonntag, D., Advancements in the field of hygrometry,
Meteorol. Z., N. F., 3, 51-66, 1994.""" Meteorol. Z., N. F., 3, 51-66, 1994."""
...@@ -413,3 +398,38 @@ def get_hum(hum, T, sst, P, qmeth): ...@@ -413,3 +398,38 @@ def get_hum(hum, T, sst, P, qmeth):
qsea = qsat_sea(sst, P, qmeth)/1000 # surface water q (g/kg) qsea = qsat_sea(sst, P, qmeth)/1000 # surface water q (g/kg)
return qair, qsea return qair, qsea
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
def gamma_moist(sst, t, q):
"""
Computes the moist adiabatic lapse-rate
Parameters
----------
sst : float
sea surface temperature [K]
t : float
air temperature [K]
q : float
specific humidity of air [kg/kg]
Returns
-------
gamma : float
lapse rate [K/m]
"""
if (np.nanmin(sst) < 200): # if sst in Celsius convert to Kelvin
sst = sst+CtoK
if (np.nanmin(t) < 200): # if sst in Celsius convert to Kelvin
t = t+CtoK
t = np.maximum(t, 180)
q = np.maximum(q, 1e-6)
w = q/(1-q) # mixing ratio w = q/(1-q)
iRT = 1/(287.05*t)
# latent heat of vaporization of water as a function of temperature
lv = (2.501-0.00237*(sst-CtoK))*1e6
gamma = 9.8*(1+lv*w*iRT)/(1005+np.power(lv, 2)*w*(287.05/461.495)*iRT/t)
return gamma
#------------------------------------------------------------------------------
This diff is collapsed.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment