Commit 2736253b authored by sbiri's avatar sbiri
Browse files

Update flux_subs.py, AirSeaFluxCode.py, get_init.py, toy_ASFC.py, hum_subs.py files

Deleted Documentation.pdf, data_all_out.csv, data_all_stats.txt, readme.txt files
parent 9cb34607
......@@ -122,9 +122,9 @@ def AirSeaFluxCode(spd, T, SST, lat=None, hum=None, P=None, hin=18, hout=10,
34. downward longwave radiation (Rl)
35. downward shortwave radiation (Rs)
36. downward net longwave radiation (Rnl)
37. flag ("n": normal, "ul": spd<2m/s,
37. flag ("n": normal, "o": out of nominal range,
"u": u10n<0, "q":q10n<0
"t": DT>10, "l": z/L<0.01,
"m": missing, "l": z/L<0.01,
"i": convergence fail at n)
2021 / Author S. Biri
......@@ -138,7 +138,9 @@ def AirSeaFluxCode(spd, T, SST, lat=None, hum=None, P=None, hin=18, hout=10,
skin, wl, gust, L,
tol, meth, qmeth)
flag = np.ones(spd.shape, dtype="object")*"n"
flag = np.where(spd < 2, "ul", flag)
flag = np.where(np.isnan(spd+T+SST+lat+hum[1]+P+Rs) & (flag == "n"),
"m", np.where(np.isnan(spd+T+SST+lat+hum[1]+P+Rs) &
(flag != "n"), flag+[","]+["m"], flag))
ref_ht = 10 # reference height
h_in = get_heights(hin, len(spd)) # heights of input measurements/fields
h_out = get_heights(hout, 1) # desired height of output variables
......@@ -152,6 +154,7 @@ def AirSeaFluxCode(spd, T, SST, lat=None, hum=None, P=None, hin=18, hout=10,
np.copy(T)*np.power(1000/P,287.1/1004.67)) # potential T
sst = np.where(SST < 200, np.copy(SST)+CtoK, np.copy(SST))
qair, qsea = get_hum(hum, T, sst, P, qmeth)
Rb = np.empty(sst.shape)
#lapse rate
tlapse = gamma_moist(SST, T, qair/1000)
Ta = np.where(T < 200, np.copy(T)+CtoK+tlapse*h_in[1],
......@@ -163,26 +166,24 @@ def AirSeaFluxCode(spd, T, SST, lat=None, hum=None, P=None, hin=18, hout=10,
dt = Ta - sst
dq = qair - qsea
flag = np.where((dt > 10) & (flag == "n"), "t",
np.where((dt > 10) & (flag != "n"), flag+[","]+["t"],
flag))
# first guesses
t10n, q10n = np.copy(Ta), np.copy(qair)
tv10n = t10n*(1+0.61*q10n)
tv10n = t10n*(1+0.6077*q10n)
# Zeng et al. 1998
tv=th*(1.+0.61*qair) # virtual potential T
dtv=dt*(1.+0.61*qair)+0.61*th*dq
tv=th*(1+0.6077*qair) # virtual potential T
dtv=dt*(1+0.6077*qair)+0.6077*th*dq
# ------------
rho = P*100/(287.1*tv10n)
lv = (2.501-0.00237*(sst-CtoK))*1e6
cp = 1004.67*(1 + 0.00084*qsea)
u10n = np.copy(spd)
cdn = cdn_calc(u10n, Ta, None, lat, meth)
ctn, ct, cqn, cq = (np.zeros(spd.shape)*np.nan, np.zeros(spd.shape)*np.nan,
cd10n = cdn_calc(u10n, Ta, None, lat, meth)
ct10n, ct, cq10n, cq = (np.zeros(spd.shape)*np.nan, np.zeros(spd.shape)*np.nan,
np.zeros(spd.shape)*np.nan, np.zeros(spd.shape)*np.nan)
psim, psit, psiq = (np.zeros(spd.shape), np.zeros(spd.shape),
np.zeros(spd.shape))
cd = cd_calc(cdn, h_in[0], ref_ht, psim)
cd = cd_calc(cd10n, h_in[0], ref_ht, psim)
tsr, tsrv = np.zeros(spd.shape), np.zeros(spd.shape)
qsr = np.zeros(spd.shape)
# cskin parameters
......@@ -228,22 +229,23 @@ def AirSeaFluxCode(spd, T, SST, lat=None, hum=None, P=None, hin=18, hout=10,
elif (tol[0] == 'all'):
old = np.array([np.copy(u10n), np.copy(t10n), np.copy(q10n),
np.copy(tau), np.copy(sensible), np.copy(latent)])
cdn[ind] = cdn_calc(u10n[ind], Ta[ind], None, lat[ind], meth)
if (np.all(np.isnan(cdn))):
cd10n[ind] = cdn_calc(u10n[ind], Ta[ind], None, lat[ind], meth)
if (np.all(np.isnan(cd10n))):
break
logging.info('break %s at iteration %s cdn<0', meth, it)
zo[ind] = ref_ht/np.exp(kappa/np.sqrt(cdn[ind]))
logging.info('break %s at iteration %s cd10n<0', meth, it)
zo[ind] = ref_ht/np.exp(kappa/np.sqrt(cd10n[ind]))
psim[ind] = psim_calc(h_in[0, ind]/monob[ind], meth)
cd[ind] = cd_calc(cdn[ind], h_in[0, ind], ref_ht, psim[ind])
ctn[ind], cqn[ind] = ctcqn_calc(h_in[1, ind]/monob[ind], cdn[ind],
u10n[ind], zo[ind], Ta[ind], meth)
cd[ind] = cd_calc(cd10n[ind], h_in[0, ind], ref_ht, psim[ind])
ct10n[ind], cq10n[ind] = ctcqn_calc(h_in[1, ind]/monob[ind],
cd10n[ind], u10n[ind], zo[ind],
Ta[ind], meth)
zot[ind] = ref_ht/(np.exp(np.power(kappa, 2) /
(ctn[ind]*np.log(ref_ht/zo[ind]))))
(ct10n[ind]*np.log(ref_ht/zo[ind]))))
zoq[ind] = ref_ht/(np.exp(np.power(kappa, 2) /
(cqn[ind]*np.log(ref_ht/zo[ind]))))
(cq10n[ind]*np.log(ref_ht/zo[ind]))))
psit[ind] = psit_calc(h_in[1, ind]/monob[ind], meth)
psiq[ind] = psit_calc(h_in[2, ind]/monob[ind], meth)
ct[ind], cq[ind] = ctcq_calc(cdn[ind], cd[ind], ctn[ind], cqn[ind],
ct[ind], cq[ind] = ctcq_calc(cd10n[ind], cd[ind], ct10n[ind], cq10n[ind],
h_in[1, ind], h_in[2, ind], ref_ht,
psit[ind], psiq[ind])
usr[ind], tsr[ind], qsr[ind] = get_strs(h_in[:, ind], monob[ind],
......@@ -325,12 +327,14 @@ def AirSeaFluxCode(spd, T, SST, lat=None, hum=None, P=None, hin=18, hout=10,
tsr[ind]/kappa*(np.log(h_in[1, ind]/ref_ht)-psit[ind]))
q10n[ind] = (qair[ind] -
qsr[ind]/kappa*(np.log(h_in[2, ind]/ref_ht)-psiq[ind]))
tv10n[ind] = t10n[ind]*(1+0.61*q10n[ind])
tsrv[ind], monob[ind] = get_L(L, lat[ind], usr[ind], tsr[ind],
qsr[ind], t10n[ind], h_in[:, ind],
Ta[ind], sst[ind],
qair[ind], qsea[ind], q10n[ind],
wind[ind], np.copy(monob[ind]), meth)
tv10n[ind] = t10n[ind]*(1+0.6077*q10n[ind])
tsrv[ind], monob[ind], Rb[ind] = get_L(L, lat[ind], usr[ind], tsr[ind],
qsr[ind], h_in[:, ind], Ta[ind],
sst[ind]-dter[ind]*cskin+dtwl[ind]*wl,
qair[ind], qsea[ind], wind[ind],
np.copy(monob[ind]), psim[ind],
meth)
# sst[ind]-dter[ind]*cskin+dtwl[ind]*wl
psim[ind] = psim_calc(h_in[0, ind]/monob[ind], meth)
psit[ind] = psit_calc(h_in[1, ind]/monob[ind], meth)
psiq[ind] = psit_calc(h_in[2, ind]/monob[ind], meth)
......@@ -395,14 +399,24 @@ def AirSeaFluxCode(spd, T, SST, lat=None, hum=None, P=None, hin=18, hout=10,
# calculate output parameters
rho = (0.34838*P)/(tv10n)
t10n = t10n-(273.16+tlapse*ref_ht)
zo = ref_ht/np.exp(kappa/cdn**0.5)
zot = ref_ht/(np.exp(kappa**2/(ctn*np.log(ref_ht/zo))))
zoq = ref_ht/(np.exp(kappa**2/(cqn*np.log(ref_ht/zo))))
# solve for zo from cd10n
zo = ref_ht/np.exp(kappa/np.sqrt(cd10n))
# adjust neutral cdn at any output height
cdn = np.power(kappa/np.log(hout/zo), 2)
cd = cd_calc(cdn, h_in[0], h_out[0], psim)
# solve for zot, zoq from ct10n, cq10n
zot = ref_ht/(np.exp(kappa**2/(ct10n*np.log(ref_ht/zo))))
zoq = ref_ht/(np.exp(kappa**2/(cq10n*np.log(ref_ht/zo))))
# adjust neutral ctn, cqn at any output height
ctn =np.power(kappa,2)/(np.log(hout/zo)*np.log(hout/zot))
cqn =np.power(kappa,2)/(np.log(hout/zo)*np.log(hout/zoq))
ct, cq = ctcq_calc(cdn, cd, ctn, cqn, h_in[1], h_in[2], h_out[1],
psit, psiq)
uref = (spd-usr/kappa*(np.log(h_in[0]/h_out[0])-psim +
psim_calc(h_out[0]/monob, meth)))
tref = (Ta-tsr/kappa*(np.log(h_in[1]/h_out[1])-psit +
psit_calc(h_out[0]/monob, meth)))
tref = tref-(273.16+tlapse*h_out[1])
tref = tref-(CtoK+tlapse*h_out[1])
qref = (qair-qsr/kappa*(np.log(h_in[2]/h_out[2]) -
psit+psit_calc(h_out[2]/monob, meth)))
flag = np.where((q10n < 0) & (flag == "n"), "q",
......@@ -414,7 +428,41 @@ def AirSeaFluxCode(spd, T, SST, lat=None, hum=None, P=None, hin=18, hout=10,
flag = np.where((itera == -1) & (flag == "n"), "i",
np.where((itera == -1) & (flag != "n"), flag+[","]+["i"],
flag))
res = np.zeros((36, len(spd)))
if (meth == "S80"):
flag = np.where(((u10n < 6) | (u10n > 22)) & (flag == "n"), "o",
np.where(((u10n < 6) | (u10n > 22)) & (flag != "n"),
flag+[","]+["o"], flag))
elif (meth == "LP82"):
flag = np.where(((u10n < 3) | (u10n > 25)) & (flag == "n"), "o",
np.where(((u10n < 3) | (u10n > 25)) & (flag != "n"),
flag+[","]+["o"], flag))
elif (meth == "YT96"):
flag = np.where(((u10n < 3) | (u10n > 26)) & (flag == "n"), "o",
np.where(((u10n < 3) | (u10n > 26)) & (flag != "n"),
flag+[","]+["o"], flag))
elif (meth == "UA"):
flag = np.where(((u10n < 0.5) | (u10n > 18)) & (flag == "n"), "o",
np.where(((u10n < 0.5) | (u10n > 18)) & (flag != "n"),
flag+[","]+["o"], flag))
elif (meth == "LY04"):
flag = np.where((u10n < 0.5) & (flag == "n"), "o",
np.where((u10n < 0.5) & (flag != "n"),
flag+[","]+["o"], flag))
if (hum == None):
rh = np.ones(sst.shape)*80
elif (hum[0] == 'rh'):
rh = hum[1]
rh = np.where(rh > 100, np.nan, rh)
elif (hum[0] == 'Td'):
Td = hum[1] # dew point temperature (K)
Td = np.where(Td < 200, np.copy(Td)+CtoK, np.copy(Td))
T = np.where(T < 200, np.copy(T)+CtoK, np.copy(T))
esd = 611.21*np.exp(17.502*((Td-273.16)/(Td-32.19)))
es = 611.21*np.exp(17.502*((T-273.16)/(T-32.19)))
rh = 100*esd/es
rh = np.where(rh > 100, np.nan, rh)
res = np.zeros((39, len(spd)))
res[0][:] = tau
res[1][:] = sensible
res[2][:] = latent
......@@ -451,21 +499,24 @@ def AirSeaFluxCode(spd, T, SST, lat=None, hum=None, P=None, hin=18, hout=10,
res[33][:] = Rl
res[34][:] = Rs
res[35][:] = Rnl
res[36][:] = np.sqrt(np.power(wind, 2)-np.power(spd, 2))
res[37][:] = Rb
res[38][:] = rh
if (out == 0):
res[:, ind] = np.nan
# set missing values where data have non acceptable values
res = [np.where(spd < 0, np.nan, res[i][:]) for i in range(36)]
res = [np.where(q10n < 0, np.nan, res[i][:]) for i in range(36)]
res = np.asarray(res)
res = np.asarray([np.where((spd < 0) | (q10n < 0), np.nan,
res[i][:]) for i in range(39)])
# output with pandas
resAll = pd.DataFrame(data=res.T, index=range(len(spd)),
columns=["tau", "shf", "lhf", "L", "cd", "cdn", "ct",
"ctn", "cq", "cqn", "tsrv", "tsr", "qsr",
"usr", "psim", "psit","psiq", "u10n", "t10n",
"tv10n", "q10n", "zo", "zot", "zoq", "uref",
"tref", "qref", "iteration", "dter", "dqer",
"dtwl", "qair", "qsea", "Rl", "Rs", "Rnl"])
"ctn", "cq", "cqn", "tsrv", "tsr", "qsr",
"usr", "psim", "psit","psiq", "u10n", "t10n",
"tv10n", "q10n", "zo", "zot", "zoq", "uref",
"tref", "qref", "iteration", "dter", "dqer",
"dtwl", "qair", "qsea", "Rl", "Rs", "Rnl",
"ug", "Rib", "rh"])
resAll["flag"] = flag
return resAll
File deleted
This source diff could not be displayed because it is too large. You can view the blob instead.
Input summary
input file name: data_all.csv,
method: UA,
gustiness: [1, 1, 1000],
cskin: 0,
tolerance: ['flux', 0.001, 0.1, 0.1]
| var | mean | median | min | max | 5% | 95% |
|-------|-----------|-----------|-----------|----------|-----------|----------|
| tau | 7.24e-02 | 4.95e-02 | 4.96e-04 | 5.64e-01 | 7.33e-03 | 2.12e-01 |
| shf | 6.80e+00 | 6.16e+00 | -4.06e+01 | 5.56e+01 | -9.07e+00 | 2.52e+01 |
| lhf | 8.26e+01 | 6.71e+01 | -4.15e+01 | 5.46e+02 | -2.89e-01 | 2.13e+02 |
| L | 4.11e+02 | -4.40e+01 | -1.62e+05 | 1.20e+06 | -5.15e+02 | 3.19e+02 |
| cd | 1.15e-03 | 1.16e-03 | 3.44e-04 | 2.02e-03 | 8.74e-04 | 1.37e-03 |
| cdn | 1.15e-03 | 1.12e-03 | 9.70e-04 | 1.71e-03 | 9.86e-04 | 1.41e-03 |
| ct | 1.18e-03 | 1.18e-03 | 3.60e-04 | 2.87e-03 | 8.90e-04 | 1.46e-03 |
| ctn | 1.12e-03 | 1.12e-03 | 1.04e-03 | 1.25e-03 | 1.05e-03 | 1.21e-03 |
| cq | 1.18e-03 | 1.18e-03 | 3.60e-04 | 2.87e-03 | 8.90e-04 | 1.46e-03 |
| cqn | 1.12e-03 | 1.12e-03 | 1.04e-03 | 1.25e-03 | 1.05e-03 | 1.21e-03 |
| tsrv | -5.18e-02 | -5.57e-02 | -2.34e-01 | 8.52e-02 | -1.27e-01 | 3.28e-02 |
| tsr | -2.70e-02 | -2.80e-02 | -1.67e-01 | 8.30e-02 | -8.42e-02 | 3.53e-02 |
| qsr | -1.37e-04 | -1.24e-04 | -5.57e-04 | 4.67e-05 | -3.24e-04 | 6.52e-07 |
| usr | 2.20e-01 | 2.04e-01 | 2.02e-02 | 6.92e-01 | 7.95e-02 | 4.20e-01 |
| psim | 4.77e-01 | 4.56e-01 | -8.86e+00 | 4.10e+00 | -7.94e-01 | 1.75e+00 |
| psit | 9.03e-01 | 8.44e-01 | -8.86e+00 | 5.74e+00 | -8.02e-01 | 2.75e+00 |
| psiq | 9.03e-01 | 8.44e-01 | -8.86e+00 | 5.74e+00 | -8.02e-01 | 2.75e+00 |
| u10n | 6.37e+00 | 6.10e+00 | 1.17e+00 | 1.67e+01 | 2.56e+00 | 1.12e+01 |
| t10n | 1.79e+01 | 1.82e+01 | -2.76e+00 | 2.98e+01 | 2.82e+00 | 2.79e+01 |
| tv10n | 2.93e+02 | 2.93e+02 | 2.71e+02 | 3.08e+02 | 2.77e+02 | 3.04e+02 |
| q10n | 1.06e-02 | 9.67e-03 | -1.49e-03 | 2.52e-02 | 3.58e-03 | 1.78e-02 |
| zo | 8.96e-05 | 6.30e-05 | 2.65e-05 | 6.37e-04 | 2.94e-05 | 2.39e-04 |
| zot | 6.01e-05 | 6.18e-05 | 1.63e-05 | 1.23e-04 | 4.09e-05 | 7.13e-05 |
| zoq | 6.01e-05 | 6.18e-05 | 1.63e-05 | 1.23e-04 | 4.09e-05 | 7.13e-05 |
| urefs | 6.18e+00 | 5.93e+00 | 6.25e-01 | 1.65e+01 | 2.30e+00 | 1.11e+01 |
| trefs | 1.80e+01 | 1.84e+01 | -2.75e+00 | 2.98e+01 | 2.87e+00 | 2.80e+01 |
| qrefs | 1.10e-02 | 1.00e-02 | 7.66e-04 | 2.53e-02 | 3.66e-03 | 1.83e-02 |
| itera | 3.41e+00 | 3.00e+00 | 2.00e+00 | 6.00e+00 | 3.00e+00 | 4.00e+00 |
| dter | 0.00e+00 | 0.00e+00 | 0.00e+00 | 0.00e+00 | 0.00e+00 | 0.00e+00 |
| dqer | 0.00e+00 | 0.00e+00 | 0.00e+00 | 0.00e+00 | 0.00e+00 | 0.00e+00 |
| dtwl | 3.00e-01 | 3.00e-01 | 3.00e-01 | 3.00e-01 | 3.00e-01 | 3.00e-01 |
| qair | 1.09e-02 | 9.90e-03 | 7.43e-04 | 2.53e-02 | 3.64e-03 | 1.82e-02 |
| qsea | 1.47e-02 | 1.39e-02 | 3.26e-03 | 2.61e-02 | 4.76e-03 | 2.46e-02 |
| Rl | 3.70e+02 | 3.70e+02 | 3.70e+02 | 3.70e+02 | 3.70e+02 | 3.70e+02 |
| Rs | 2.61e+02 | 2.33e+02 | 1.67e-02 | 9.71e+02 | 2.84e+01 | 5.37e+02 |
| Rnl | 4.25e+01 | 4.50e+01 | -6.02e+01 | 1.06e+02 | -3.65e+01 | 9.96e+01 |
-------------------------------------------------------------------------------
......@@ -6,7 +6,7 @@ from util_subs import (CtoK, kappa, gc, visc_air)
def cdn_calc(u10n, Ta, Tp, lat, meth="S80"):
"""
Calculates neutral drag coefficient
Calculates 10m neutral drag coefficient
Parameters
----------
......@@ -56,7 +56,7 @@ def cdn_calc(u10n, Ta, Tp, lat, meth="S80"):
def cdn_from_roughness(u10n, Ta, Tp, lat, meth="S88"):
"""
Calculates neutral drag coefficient from roughness length
Calculates 10m neutral drag coefficient from roughness length
Parameters
----------
......@@ -97,9 +97,6 @@ def cdn_from_roughness(u10n, Ta, Tp, lat, meth="S88"):
zo = a*np.power(usr, 2)/g+0.11*visc_air(Ta)/usr
elif (meth == "C35"):
a = 0.011*np.ones(Ta.shape)
# a = np.where(u10n > 19, 0.0017*19-0.0050,
# np.where((u10n > 7) & (u10n <= 18),
# 0.0017*u10n-0.0050, a))
a = np.where(u10n > 19, 0.0017*19-0.0050, 0.0017*u10n-0.0050)
zo = 0.11*visc_air(Ta)/usr+a*np.power(usr, 2)/g
elif (meth == "C40"):
......@@ -117,7 +114,7 @@ def cdn_from_roughness(u10n, Ta, Tp, lat, meth="S88"):
# ---------------------------------------------------------------------
def cd_calc(cdn, height, ref_ht, psim):
def cd_calc(cdn, hin, hout, psim):
"""
Calculates drag coefficient at reference height
......@@ -125,9 +122,9 @@ def cd_calc(cdn, height, ref_ht, psim):
----------
cdn : float
neutral drag coefficient
height : float
hin : float
original sensor height [m]
ref_ht : float
hout : float
reference height [m]
psim : float
momentum stability function
......@@ -136,14 +133,14 @@ def cd_calc(cdn, height, ref_ht, psim):
-------
cd : float
"""
cd = (cdn/np.power(1+(np.sqrt(cdn)*(np.log(height/ref_ht)-psim))/kappa, 2))
cd = (cdn/np.power(1+(np.sqrt(cdn)*(np.log(hin/hout)-psim))/kappa, 2))
return cd
# ---------------------------------------------------------------------
def ctcqn_calc(zol, cdn, u10n, zo, Ta, meth="S80"):
"""
Calculates neutral heat and moisture exchange coefficients
Calculates 10m neutral heat and moisture exchange coefficients
Parameters
----------
......@@ -209,9 +206,6 @@ def ctcqn_calc(zol, cdn, u10n, zo, Ta, meth="S80"):
1.0e-4/np.power(rr, 0.55)) # temperature roughness
zoq = np.where(2.0e-5/np.power(rr,0.22) > 1.1e-4/np.power(rr,0.9),
1.1e-4/np.power(rr,0.9), 2.0e-5/np.power(rr,0.22))
# moisture roughness determined by the CLIMODE, GASEX and CBLAST data
# zoq = np.where(5e-5/np.power(rr, 0.6) > 1.15e-4, 1.15e-4,
# 5e-5/np.power(rr, 0.6)) # moisture roughness as in C30
cqn = kappa**2/np.log(10/zo)/np.log(10/zoq)
ctn = kappa**2/np.log(10/zo)/np.log(10/zot)
elif (meth == "ecmwf" or meth == "Beljaars"):
......@@ -227,7 +221,7 @@ def ctcqn_calc(zol, cdn, u10n, zo, Ta, meth="S80"):
# ---------------------------------------------------------------------
def ctcq_calc(cdn, cd, ctn, cqn, ht, hq, ref_ht, psit, psiq):
def ctcq_calc(cdn, cd, ctn, cqn, ht, hq, hout, psit, psiq):
"""
Calculates heat and moisture exchange coefficients at reference height
......@@ -245,8 +239,8 @@ def ctcq_calc(cdn, cd, ctn, cqn, ht, hq, ref_ht, psit, psiq):
original temperature sensor height [m]
hq : float
original moisture sensor height [m]
ref_ht : float
reference height [m]
hout : float
output height [m]
psit : float
heat stability function
psiq : float
......@@ -260,9 +254,9 @@ def ctcq_calc(cdn, cd, ctn, cqn, ht, hq, ref_ht, psit, psiq):
moisture exchange coefficient
"""
ct = (ctn*np.sqrt(cd/cdn) /
(1+ctn*((np.log(ht/ref_ht)-psit)/(kappa*np.sqrt(cdn)))))
(1+ctn*((np.log(ht/hout)-psit)/(kappa*np.sqrt(cdn)))))
cq = (cqn*np.sqrt(cd/cdn) /
(1+cqn*((np.log(hq/ref_ht)-psiq)/(kappa*np.sqrt(cdn)))))
(1+cqn*((np.log(hq/hout)-psiq)/(kappa*np.sqrt(cdn)))))
return ct, cq
# ---------------------------------------------------------------------
......@@ -736,8 +730,6 @@ def cs_ecmwf(rho, Rs, Rnl, cp, lv, usr, tsr, qsr, sst, lat):
# # fraction of the solar radiation absorbed in layer delta eq. 8.153
# and Eq.(5) Zeng & Beljaars, 2005
fs = 0.065+11*d-6.6e-5/d*(1-np.exp(-d/8e-4))
# fs = np.maximum(0.065+11*delta-(6.6e-5/delta)*(1-np.exp(-delta/8e-4)),
# 0.01)
Q = Qnsol-fs*Rns
d = delta(aw, Q, usr, lat)
dtc = Q*d/0.6 # (rhow*cw*kw)eq. 8.151
......@@ -918,8 +910,8 @@ def get_gust(beta, Ta, usr, tsrv, zi, lat):
# ---------------------------------------------------------------------
def get_L(L, lat, usr, tsr, qsr, t10n, hin, Ta, sst, qair, qsea, q10n,
wind, monob, meth):
def get_L(L, lat, usr, tsr, qsr, hin, Ta, sst, qair, qsea, wind, monob, psim,
meth):
"""
calculates Monin-Obukhov length and virtual star temperature
......@@ -968,6 +960,7 @@ def get_L(L, lat, usr, tsr, qsr, t10n, hin, Ta, sst, qair, qsea, q10n,
"""
g = gc(lat)
Rb = np.empty(sst.shape)
if (L == "S80"):
# as in NCAR, LY04
tsrv = tsr*(1+0.6077*qair)+0.6077*Ta*qsr
......@@ -977,20 +970,26 @@ def get_L(L, lat, usr, tsr, qsr, t10n, hin, Ta, sst, qair, qsea, q10n,
temp = np.minimum(np.abs(temp), 10/hin[0])*np.sign(temp)
monob = 1/np.copy(temp)
elif (L == "ecmwf"):
Rb = np.empty(sst.shape)
tsrv = tsr*(1+0.6077*qair)+0.6077*Ta*qsr
Rb = g*hin[1]/(wind*wind)*((Ta-sst)/(Ta-0.5*(Ta-sst+g*hin[1] /
(1005+1860*qair))) +
0.6077*(qair-qsea))
# from eq. 3.24 ifs Cy46r1 pp. 37
thvs = sst*(1+0.6077*qsea) # virtual SST
dthv = (Ta-sst)*(1+0.6077*qair)+0.6077*Ta*(qair-qsea)
tv = 0.5*(thvs+Ta*(1+0.6077*qair)) # estimate tv within surface layer
# adjust wind to T sensor's height
uz = (wind-usr/kappa*(np.log(hin[0]/hin[1])-psim +
psim_calc(hin[1]/monob, meth)))
Rb = g*dthv*hin[1]/(tv*uz*uz)
zo = (0.11*visc_air(Ta)/usr+0.018*np.power(usr, 2)/g)
zot = 0.40*visc_air(Ta)/usr
zol = (Rb*(np.power(np.log((hin[0]+zo)/zo)-psim_calc((hin[0]+zo) /
zol = (Rb*(np.power(np.log((hin[1]+zo)/zo)-psim_calc((hin[1]+zo) /
monob, meth) +
psim_calc(zo/monob, meth), 2) /
(np.log((hin[0]+zo)/zot) -
psit_calc((hin[0]+zo)/monob, meth) +
(np.log((hin[1]+zo)/zot) -
psit_calc((hin[1]+zo)/monob, meth) +
psit_calc(zot/monob, meth))))
monob = hin[0]/zol
return tsrv, monob
monob = hin[1]/zol
return tsrv, monob, Rb
#------------------------------------------------------------------------------
......
......@@ -137,7 +137,7 @@ def get_init(spd, T, SST, lat, P, Rl, Rs, cskin, skin, wl, gust, L, tol, meth,
elif (np.size(gust) < 3):
sys.exit("gust input must be a 3x1 array")
if (L not in [None, "S80", "ecmwf"]):
sys.exit("L input must be either None, 0, 1, 2 or 3")
sys.exit("L input must be either None, S80 or ecmwf")
if ((L == None) and (meth == "S80" or meth == "S88" or meth == "LP82"
or meth == "YT96" or meth == "LY04" or
meth == "UA" or meth == "C30" or meth == "C35"
......@@ -149,4 +149,4 @@ def get_init(spd, T, SST, lat, P, Rl, Rs, cskin, skin, wl, gust, L, tol, meth,
tol = ['flux', 1e-3, 0.1, 0.1]
elif (tol[0] not in ['flux', 'ref', 'all']):
sys.exit("unknown tolerance input")
return lat, P, Rl, Rs, cskin, skin, wl, gust, tol, L
\ No newline at end of file
return lat, P, Rl, Rs, cskin, skin, wl, gust, tol, L
......@@ -384,6 +384,7 @@ def get_hum(hum, T, sst, P, qmeth):
if (np.all(RH < 1)):
sys.exit("input relative humidity units should be \%")
qair, qsea = np.nan, np.nan
RH = np.where(RH > 100, np.nan, RH) # ensure RH <=100
qsea = qsat_sea(sst, P, qmeth)/1000 # surface water q (kg/kg)
qair = qsat_air(T, P, RH, qmeth)/1000 # q of air (kg/kg)
elif (hum[0] == 'q'):
......@@ -396,6 +397,7 @@ def get_hum(hum, T, sst, P, qmeth):
esd = 611.21*np.exp(17.502*((Td-273.16)/(Td-32.19)))
es = 611.21*np.exp(17.502*((T-273.16)/(T-32.19)))
RH = 100*esd/es
RH = np.where(RH > 100, np.nan, RH) # ensure RH <=100
qair = qsat_air(T, P, RH, qmeth)/1000 # q of air (kg/kg)
qsea = qsat_sea(sst, P, qmeth)/1000 # surface water q (kg/kg)
return qair, qsea
......
input file name: data_all.csv,
method: UA,
gustiness: [1, 1, 1000],
cskin: 0,
tolerance: ['all', 0.01, 0.01, 1e-05, 0.001, 0.1, 0.1],
output is written in: data_all_out.csv
......@@ -19,14 +19,14 @@ from tabulate import tabulate
#%%
def reject_outliers(data, m=2):
x = np.copy(data)
x = np.where(np.abs(x - np.nanmean(x)) < m*np.nanstd(x),
x, np.nan)
x = np.where(np.abs(x-np.nanmean(x)) < m*np.nanstd(x), x, np.nan)
return x
def toy_ASFC(inF, outF, gustIn, cskinIn, tolIn, meth):
"""
Example routine of how to run AirSeaFluxCode with the test data given
and save output either as .csv or NetCDF
Parameters
----------
......@@ -39,7 +39,7 @@ def toy_ASFC(inF, outF, gustIn, cskinIn, tolIn, meth):
cskinIn : int
cool skin option input 0 or 1
tolIn : float
tolerance input option e.g. ['all', 0.01, 0.01, 5e-05, 0.01, 1, 1]
tolerance input option e.g. ['all', 0.01, 0.01, 1e-05, 1e-3, 0.1, 0.1]
meth : str
parametrisation method option
......@@ -70,14 +70,9 @@ def toy_ASFC(inF, outF, gustIn, cskinIn, tolIn, meth):
hin = np.array([hu, ht, ht])
del hu, ht, inDt
#%% run AirSeaFluxCode
temp = AirSeaFluxCode(spd, t, sst, lat=lat, hum=['rh', rh], P=p,
res = AirSeaFluxCode(spd, t, sst, lat=lat, hum=['rh', rh], P=p,
hin=hin, Rs=sw, tol=tolIn, gust=gustIn,
cskin=cskinIn, meth=meth, L="ecmwf", n=30)
res = temp.loc[:,"tau":"Rnl"]
res = res.to_numpy().T
del temp
#%% delete variables
del spd, t, sst, rh, p, sw, hin
elif (inF == 'era5_r360x180.nc'):
#%% load era5_r360x180.nc
......@@ -95,15 +90,20 @@ def toy_ASFC(inF, outF, gustIn, cskinIn, tolIn, meth):
u = np.array(fid.variables["u10"])
v = np.array(fid.variables["v10"])
lsm = np.array(fid.variables["lsm"])
icon = np.array(fid.variables["siconc"])
fid.close()
spd = np.sqrt(np.power(u, 2)+np.power(v, 2))
del u, v, fid
lsm = np.where(lsm > 0, np.nan, 1) # reverse 0 on land 1 over ocean
icon = np.where(icon < 0, np.nan, 1)
msk = lsm*icon
hin = np.array([10, 2, 2])
latIn = np.tile(lat, (len(lon), 1)).T.reshape(len(lon)*len(lat))
date = np.copy(tim)
#%% run AirSeaFluxCode
res = np.zeros((len(tim),len(lon)*len(lat), 36))
res = np.zeros((len(tim),len(lon)*len(lat), 39))
flg = np.empty((len(tim),len(lon)*len(lat)), dtype="object")
# reshape input and run code
for x in range(len(tim)):
temp = AirSeaFluxCode(spd.reshape(len(tim), len(lon)*len(lat))[x, :],
......@@ -117,11 +117,15 @@ def toy_ASFC(inF, outF, gustIn, cskinIn, tolIn, meth):
Rl=lw.reshape(len(tim), len(lon)*len(lat))[x, :],
gust=gustIn, cskin=cskinIn, tol=tolIn, qmeth='WMO',
meth=meth, n=30, L="ecmwf")
a = temp.loc[:,"tau":"Rnl"]
a = temp.loc[:,"tau":"rh"]
a = a.to_numpy()
del temp
flg[x, :] = temp["flag"]
res[x, :, :] = a
del a
del a, temp
n = np.shape(res)
res = np.asarray([res[:, :, i]*msk.reshape(n[0], n[1])
for i in range(39)])
res = np.moveaxis(res, 0, -1)
if (outF[-3:] == '.nc'):
if (inF == 'era5_r360x180.nc'):
......@@ -169,46 +173,55 @@ def toy_ASFC(inF, outF, gustIn, cskinIn, tolIn, meth):
Rl = fid.createVariable('Rl', 'f4', ('time','lat','lon'))
Rs = fid.createVariable('Rs', 'f4', ('time','lat','lon'))
Rnl = fid.createVariable('Rnl', 'f4', ('time','lat','lon'))
ug = fid.createVariable('ug', 'f4', ('time','lat','lon'))
Rib = fid.createVariable('Rib', 'f4', ('time','lat','lon'))
rh = fid.createVariable('rh', 'f4', ('time','lat','lon'))
flag = fid.createVariable('flag', 'S1', ('time','lat','lon'))
longitude[:] = lon
latitude[:] = lat
Date[:] = tim
tau[:] = res[:, :, 0].reshape((len(tim), len(lat), len(lon)))*lsm
sensible[:] = res[:, :, 1].reshape((len(tim), len(lat), len(lon)))*lsm
latent[:] = res[:, :, 2].reshape((len(tim), len(lat), len(lon)))*lsm
monob[:] = res[:, :, 3].reshape((len(tim), len(lat), len(lon)))*lsm
cd[:] = res[:, :, 4].reshape((len(tim), len(lat), len(lon)))*lsm
cdn[:] = res[:, :, 5].reshape((len(tim), len(lat), len(lon)))*lsm
ct[:] = res[:, :, 6].reshape((len(tim), len(lat), len(lon)))*lsm
ctn[:] = res[:, :, 7].reshape((len(tim), len(lat), len(lon)))*lsm
cq[:] = res[:, :, 8].reshape((len(tim), len(lat), len(lon)))*lsm
cqn[:] = res[:, :, 9].reshape((len(tim), len(lat), len(lon)))*lsm
tsrv[:] = res[:, :, 10].reshape((len(tim), len(lat), len(lon)))*lsm
tsr[:] = res[:, :, 11].reshape((len(tim), len(lat), len(lon)))*lsm
qsr[:] = res[:, :, 12].reshape((len(tim), len(lat), len(lon)))*lsm
usr[:] = res[:, :, 13].reshape((len(tim), len(lat), len(lon)))*lsm
psim[:] = res[:, :, 14].reshape((len(tim), len(lat), len(lon)))*lsm
psit[:] = res[:, :, 15].reshape((len(tim), len(lat), len(lon)))*lsm
psiq[:] = res[:, :, 16].reshape((len(tim), len(lat), len(lon)))*lsm
u10n[:] = res[:, :, 17].reshape((len(tim), len(lat), len(lon)))*lsm
t10n[:] = res[:, :, 18].reshape((len(tim), len(lat), len(lon)))*lsm
tv10n[:] = res[:, :, 19].reshape((len(tim), len(lat), len(lon)))*lsm
q10n[:] = res[:, :, 20].reshape((len(tim), len(lat), len(lon)))*lsm
zo[:] = res[:, :, 21].reshape((len(tim), len(lat), len(lon)))*lsm
zot[:] = res[:, :, 22].reshape((len(tim), len(lat), len(lon)))*lsm
zoq[:] = res[:, :, 23].reshape((len(tim), len(lat), len(lon)))*lsm
urefs[:] = res[:, :, 24].reshape((len(tim), len(lat), len(lon)))*lsm
trefs[:] = res[:, :, 25].reshape((len(tim), len(lat), len(lon)))*lsm
qrefs[:] = res[:, :, 26].reshape((len(tim), len(lat), len(lon)))*lsm
itera[:] = res[:, :, 27].reshape((len(tim), len(lat), len(lon)))*lsm
dter[:] = res[:, :, 28].reshape((len(tim), len(lat), len(lon)))*lsm
dqer[:] = res[:, :, 29].reshape((len(tim), len(lat), len(lon)))*lsm
dtwl[:] = res[:, :, 30].reshape((len(tim), len(lat), len(lon)))*lsm
qair[:] = res[:, :, 31].reshape((len(tim), len(lat), len(lon)))*lsm
qsea[:] = res[:, :, 32].reshape((len(tim), len(lat), len(lon)))*lsm
Rl = res[:, :, 33].reshape((len(tim), len(lat), len(lon)))
Rs = res[:, :, 34].reshape((len(tim), len(lat), len(lon)))
Rnl = res[:, :, 35].reshape((len(tim), len(lat), len(lon)))
tau[:] = res[:, :, 0].reshape((len(tim), len(lat), len(lon)))*msk
sensible[:] = res[:, :, 1].reshape((len(tim), len(lat), len(lon)))*msk
latent[:] = res[:, :, 2].reshape((len(tim), len(lat), len(lon)))*msk
monob[:] = res[:, :, 3].reshape((len(tim), len(lat), len(lon)))*msk
cd[:] = res[:, :, 4].reshape((len(tim), len(lat), len(lon)))*msk
cdn[:] = res[:, :, 5].reshape((len(tim), len(lat), len(lon)))*msk
ct[:] = res[:, :, 6].reshape((len(tim), len(lat), len(lon)))*msk
ctn[:] = res[:, :, 7].reshape((len(tim), len(lat), len(lon)))*msk
cq[:] = res[:, :, 8].reshape((len(tim), len(lat), len(lon)))*msk
cqn[:] = res[:, :, 9].reshape((len(tim), len(lat), len(lon)))*msk
tsrv[:] = res[:, :, 10].reshape((len(tim), len(lat), len(lon)))*msk
tsr[:] = res[:, :, 11].reshape((len(tim), len(lat), len(lon)))*msk
qsr[:] = res[:, :, 12].reshape((len(tim), len(lat), len(lon)))*msk
usr[:] = res[:, :, 13].reshape((len(tim), len(lat), len(lon)))*msk
psim[:] = res[:, :, 14].reshape((len(tim), len(lat), len(lon)))*msk
psit[:] = res[:, :, 15].reshape((len(tim), len(lat), len(lon)))*msk
psiq[:] = res[:, :, 16].reshape((len(tim), len(lat), len(lon)))*msk
u10n[:] = res[:, :, 17].reshape((len(tim), len(lat), len(lon)))*msk
t10n[:] = res[:, :, 18].reshape((len(tim), len(lat), len(lon)))*msk
tv10n[:] = res[:, :, 19].reshape((len(tim), len(lat), len(lon)))*msk
q10n[:] = res[:, :, 20].reshape((len(tim), len(lat), len(lon)))*msk
zo[:] = res[:, :, 21].reshape((len(tim), len(lat), len(lon)))*msk
zot[:] = res[:, :, 22].reshape((len(tim), len(lat), len(lon)))*msk
zoq[:] = res[:, :, 23].reshape((len(tim), len(lat), len(lon)))*msk
urefs[:] = res[:, :, 24].reshape((len(tim), len(lat), len(lon)))*msk
trefs[:] = res[:, :, 25].reshape((len(tim), len(lat), len(lon)))*msk
qrefs[:] = res[:, :, 26].reshape((len(tim), len(lat), len(lon)))*msk
itera[:] = res[:, :, 27].reshape((len(tim), len(lat), len(lon)))*msk
dter[:] = res[:, :, 28].reshape((len(tim), len(lat), len(lon)))*msk
dqer[:] = res[:, :, 29].reshape((len(tim), len(lat), len(lon)))*msk
dtwl[:] = res[:, :, 30].reshape((len(tim), len(lat), len(lon)))*msk
qair[:] = res[:, :, 31].reshape((len(tim), len(lat), len(lon)))*msk
qsea[:] = res[:, :, 32].reshape((len(tim), len(lat), len(lon)))*msk
Rl[:] = res[:, :, 33].reshape((len(tim), len(lat), len(lon)))*msk
Rs[:] = res[:, :, 34].reshape((len(tim), len(lat), len(lon)))*msk
Rnl[:] = res[:, :, 35].reshape((len(tim), len(lat), len(lon)))*msk
ug[:] = res[:, :, 36].reshape((len(tim), len(lat), len(lon)))*msk
Rib[:] = res[:, :, 37].reshape((len(tim), len(lat), len(lon)))*msk
rh[:] = res[:, :, 38].reshape((len(tim), len(lat), len(lon)))*msk
flag[:] = flg.reshape((len(tim), len(lat), len(lon)))
longitude.long_name = 'Longitude'
longitude.units = 'degrees East'
latitude.long_name = 'Latitude'
......@@ -252,7 +265,7 @@ def toy_ASFC(inF, outF, gustIn, cskinIn, tolIn, meth):
tv10n.long_name = '10m neutral virtual temperature'
tv10n.units = 'degrees Celsius'
q10n.long_name = '10m neutral specific humidity'
q10n.units = 'gr/kgr'
q10n.units = 'kgr/kgr'
zo.long_name = 'momentum roughness length'
zo.units = 'm'
zot.long_name = 'temperature roughness length'
......@@ -264,19 +277,33 @@ def toy_ASFC(inF, outF, gustIn, cskinIn, tolIn, meth):
trefs.long_name = 'temperature at ref height'
trefs.units = 'degrees Celsius'
qrefs.long_name = 'specific humidity at ref height'
qrefs.units = 'gr/kgr'
qrefs.units = 'kgr/kgr'
qair.long_name = 'specific humidity of air'
qair.units = 'gr/kgr'
qair.units = 'kgr/kgr'
qsea.long_name = 'specific humidity over water'
qsea.units = 'gr/kgr'
qsea.units = 'kgr/kgr'
itera.long_name = 'number of iterations'
Rl.long_name = 'downward longwave radiation'
Rl.units = 'W/m^2'
Rs.long_name = 'downward shortwave radiation'
Rs.units = 'W/m^2'
Rnl.long_name = 'downward net longwave radiation'
Rnl.units = 'W/m^2'
ug.long_name = 'gust wind speed'
ug.units = 'm/s'
Rib.long_name = 'bulk Richardson number'
rh.long_name = 'relative humidity'
rh.units = '%'
flag.long_name = ('flag "n" normal, "u": u10n < 0, "q": q10n < 0,'
'"l": zol<0.01, "m": missing, "i": points that'
'have not converged')
fid.close()
#%% delete variables
del longitude, latitude, Date, tau, sensible, latent, monob, cd, cdn
del ct, ctn, cq, cqn, tsrv, tsr, qsr, usr, psim, psit, psiq, u10n, t10n
del tv10n, q10n, zo, zot, zoq, urefs, trefs, qrefs, itera, dter, dqer
del qair, qsea, Rl, Rs, Rnl, dtwl
del tim, T, Td, p, lw, sw, lsm, spd, hin, latIn
del tim, T, Td, p, lw, sw, lsm, spd, hin, latIn, icon, msk
else:
#%% save NetCDF4
fid = nc.Dataset(outF,'w', format='NETCDF4')
......@@ -316,52 +343,61 @@ def toy_ASFC(inF, outF, gustIn, cskinIn, tolIn, meth):
itera = fid.createVariable('iter', 'i4', 'time')
dter = fid.createVariable('dter', 'f4', 'time')
dqer = fid.createVariable('dqer', 'f4', 'time')
dtwl = fid.createVariable('dter', 'f4', 'time')
dtwl = fid.createVariable('dtwl', 'f4', 'time')
qair = fid.createVariable('qair', 'f4', 'time')
qsea = fid.createVariable('qsea', 'f4', 'time')
Rl = fid.createVariable('Rl', 'f4', 'time')
Rs = fid.createVariable('Rs', 'f4', 'time')
Rnl = fid.createVariable('Rnl', 'f4', 'time')
ug = fid.createVariable('ug', 'f4', 'time')
Rib = fid.createVariable('Rib', 'f4', 'time')
rh = fid.createVariable('rh', 'f4', 'time')
flag = fid.createVariable('flag', 'S1', 'time')
longitude[:] = lon
latitude[:] = lat
Date[:] = date
tau[:] = res[0]
sensible[:] = res[1]
latent[:] = res[2]
monob[:] = res[3]
cd[:] = res[4]
cdn[:] = res[5]
ct[:] = res[6]
ctn[:] = res[7]
cq[:] = res[8]
cqn[:] = res[9]
tsrv[:] = res[10]
tsr[:] = res[11]
qsr[:] = res[12]
usr[:] = res[13]
psim[:] = res[14]
psit[:] = res[15]
psiq[:] = res[16]
u10n[:] = res[17]
t10n[:] = res[18]
tv10n[:] = res[19]
q10n[:] = res[20]
zo[:] = res[21]
zot[:] = res[22]
zoq[:] = res[23]
urefs[:] = res[24]
trefs[:] = res[25]
qrefs[:] = res[26]
itera[:] = res[27]
dter[:] = res[28]
dqer[:] = res[29]
dtwl[:] = res[30]
qair[:] = res[31]
qsea[:] = res[32]
Rl[:] = res[33]
Rs[:] = res[34]
Rnl[:] = res[35]
tau[:] = res["tau"]
sensible[:] = res["shf"]
latent[:] = res["lhf"]
monob[:] = res["L"]
cd[:] = res["cd"]
cdn[:] = res["cdn"]
ct[:] = res["ct"]
ctn[:] = res["ctn"]
cq[:] = res["cq"]
cqn[:] = res["cqn"]
tsrv[:] = res["tsrv"]
tsr[:] = res["tsr"]
qsr[:] = res["qsr"]
usr[:] = res["usr"]
psim[:] = res["psim"]
psit[:] = res["psit"]
psiq[:] = res["psiq"]
u10n[:] = res["u10n"]
t10n[:] = res["t10n"]
tv10n[:] = res["tv10n"]
q10n[:] = res["q10n"]
zo[:] = res["zo"]
zot[:] = res["zot"]
zoq[:] = res["zoq"]
urefs[:] = res["uref"]
trefs[:] = res["tref"]
qrefs[:] = res["qref"]
itera[:] = res["iteration"]
dter[:] = res["dter"]
dqer[:] = res["dqer"]
dtwl[:] = res["dtwl"]
qair[:] = res["qair"]
qsea[:] = res["qsea"]
Rl[:] = res["Rl"]
Rs[:] = res["Rs"]
Rnl[:] = res["Rnl"]
ug[:] = res["ug"]
Rib[:] = res["Rib"]
rh[:] = res["rh"]
flag[:] = res["flag"]
longitude.long_name = 'Longitude'
longitude.units = 'degrees East'
latitude.long_name = 'Latitude'
......@@ -405,7 +441,7 @@ def toy_ASFC(inF, outF, gustIn, cskinIn, tolIn, meth):
tv10n.long_name = '10m neutral virtual temperature'
tv10n.units = 'degrees Celsius'
q10n.long_name = '10m neutral specific humidity'
q10n.units = 'gr/kgr'
q10n.units = 'kgr/kgr'
zo.long_name = 'momentum roughness length'
zo.units = 'm'
zot.long_name = 'temperature roughness length'
......@@ -417,27 +453,39 @@ def toy_ASFC(inF, outF, gustIn, cskinIn, tolIn, meth):
trefs.long_name = 'temperature at ref height'
trefs.units = 'degrees Celsius'
qrefs.long_name = 'specific humidity at ref height'
qrefs.units = 'gr/kgr'
qrefs.units = 'kgr/kgr'
qair.long_name = 'specific humidity of air'
qair.units = 'gr/kgr'
qair.units = 'kgr/kgr'
qsea.long_name = 'specific humidity over water'
qsea.units = 'gr/kgr'
qsea.units = 'kgr/kgr'
itera.long_name = 'number of iterations'
Rl.long_name = 'downward longwave radiation'
Rl.units = 'W/m^2'
Rs.long_name = 'downward shortwave radiation'
Rs.units = 'W/m^2'
Rnl.long_name = 'downward net longwave radiation'
Rnl.units = 'W/m^2'
ug.long_name = 'gust wind speed'
ug.units = 'm/s'
Rib.long_name = 'bulk Richardson number'
rh.long_name = 'relative humidity'
rh.units = '%'
flag.long_name = ('flag "n" normal, "u": u10n < 0, "q": q10n < 0,'
'"l": zol<0.01, "m": missing, "i": points that'
'have not converged')
fid.close()
#%% delete variables
del longitude, latitude, Date, tau, sensible, latent, monob, cd, cdn
del ct, ctn, cq, cqn, tsrv, tsr, qsr, usr, psim, psit, psiq, u10n, t10n
del tv10n, q10n, zo, zot, zoq, urefs, trefs, qrefs, itera, dter, dqer
del qair, qsea, Rl, Rs, Rnl
del t, rh, date, p, sw, spd, hin
del qair, qsea, Rl, Rs, Rnl, ug, rh, Rib
del t, date, p, sw, spd, hin, sst
else:
#%% save as .csv
np.savetxt(outF, np.vstack((date, lon, lat, res)).T,
delimiter=',',
header="date, lon, lat, tau, shf, lhf, L, cd, cdn, ct, ctn,"
" cq, cqn, tsrv, tsr, qsr, usr, psim, psit, psiq, u10n,"
" t10n, tv10n, q10n, zo, zot, zoq, uref, tref, qref, iter,"
" dter, dqer, dtwl, qair, qsea, Rl, Rs, Rnl")
res.insert(loc=0, column='date', value=date)
res.insert(loc=1, column='lon', value=lon)
res.insert(loc=2, column='lat', value=lat)
res.to_csv(outF)
return res, lon, lat
#%% run function
start_time = time.perf_counter()
......@@ -530,7 +578,7 @@ elif (inF == "data_all.csv"):
ttl = ["tau (Nm$^{-2}$)", "shf (Wm$^{-2}$)", "lhf (Wm$^{-2}$)"]
for i in range(3):
plt.figure()
plt.plot(res[i],'.c', markersize=1)
plt.plot(res[ttl[i][:3]],'.c', markersize=1)
plt.title(meth)
plt.xlabel("points")
plt.ylabel(ttl[i])
......@@ -564,7 +612,8 @@ ttl = np.asarray(["tau ", "shf ", "lhf ", "L ", "cd ", "cdn ",
"qsr ", "usr ", "psim ", "psit ", "psiq ", "u10n ",
"t10n ", "tv10n", "q10n ", "zo ", "zot ", "zoq ",
"urefs", "trefs", "qrefs", "itera", "dter ", "dqer ",
"dtwl ", "qair ", "qsea ", "Rl ", "Rs ", "Rnl "])
"dtwl ", "qair ", "qsea ", "Rl ", "Rs ", "Rnl ",
"ug ", "Rib ", "rh "])
header = ["var", "mean", "median", "min", "max", "5%", "95%"]
n = np.shape(res)
stats = np.copy(ttl)
......@@ -582,16 +631,18 @@ if (inF == 'era5_r360x180.nc'):
"2.2e")), file=open('./stats.txt', 'a'))
print('-'*79+'\n', file=open('./stats.txt', 'a'))
elif (inF == "data_all.csv"):
stats = np.c_[stats, np.nanmean(res, axis=1)]
stats = np.c_[stats, np.nanmedian(res, axis=1)]
stats = np.c_[stats, np.nanmin(res, axis=1)]
stats = np.c_[stats, np.nanmax(res, axis=1)]
stats = np.c_[stats, np.nanpercentile(res, 5, axis=1)]
stats = np.c_[stats, np.nanpercentile(res, 95, axis=1)]
a = res.loc[:,"tau":"rh"].to_numpy(dtype="float64").T
stats = np.c_[stats, np.nanmean(a, axis=1)]
stats = np.c_[stats, np.nanmedian(a, axis=1)]
stats = np.c_[stats, np.nanmin(a, axis=1)]
stats = np.c_[stats, np.nanmax(a, axis=1)]
stats = np.c_[stats, np.nanpercentile(a, 5, axis=1)]
stats = np.c_[stats, np.nanpercentile(a, 95, axis=1)]
print(tabulate(stats, headers=header, tablefmt="github", numalign="left",
floatfmt=("s", "2.2e", "2.2e", "2.2e", "2.2e", "2.2e",
"2.2e")), file=open('./stats.txt', 'a'))
print('-'*79+'\n', file=open('./stats.txt', 'a'))
del a
print('input file name: {}, \n method: {}, \n gustiness: {}, \n cskin: {},'
' \n tolerance: {}, \n output is written in: {}'.format(inF, meth,
......
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