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, ...@@ -122,9 +122,9 @@ def AirSeaFluxCode(spd, T, SST, lat=None, hum=None, P=None, hin=18, hout=10,
34. downward longwave radiation (Rl) 34. downward longwave radiation (Rl)
35. downward shortwave radiation (Rs) 35. downward shortwave radiation (Rs)
36. downward net longwave radiation (Rnl) 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 "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) "i": convergence fail at n)
2021 / Author S. Biri 2021 / Author S. Biri
...@@ -138,7 +138,9 @@ def AirSeaFluxCode(spd, T, SST, lat=None, hum=None, P=None, hin=18, hout=10, ...@@ -138,7 +138,9 @@ def AirSeaFluxCode(spd, T, SST, lat=None, hum=None, P=None, hin=18, hout=10,
skin, wl, gust, L, skin, wl, gust, L,
tol, meth, qmeth) tol, meth, qmeth)
flag = np.ones(spd.shape, dtype="object")*"n" 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 ref_ht = 10 # reference height
h_in = get_heights(hin, len(spd)) # heights of input measurements/fields h_in = get_heights(hin, len(spd)) # heights of input measurements/fields
h_out = get_heights(hout, 1) # desired height of output variables 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, ...@@ -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 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)) sst = np.where(SST < 200, np.copy(SST)+CtoK, np.copy(SST))
qair, qsea = get_hum(hum, T, sst, P, qmeth) qair, qsea = get_hum(hum, T, sst, P, qmeth)
Rb = np.empty(sst.shape)
#lapse rate #lapse rate
tlapse = gamma_moist(SST, T, qair/1000) tlapse = gamma_moist(SST, T, qair/1000)
Ta = np.where(T < 200, np.copy(T)+CtoK+tlapse*h_in[1], 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, ...@@ -163,26 +166,24 @@ def AirSeaFluxCode(spd, T, SST, lat=None, hum=None, P=None, hin=18, hout=10,
dt = Ta - sst dt = Ta - sst
dq = qair - qsea dq = qair - qsea
flag = np.where((dt > 10) & (flag == "n"), "t",
np.where((dt > 10) & (flag != "n"), flag+[","]+["t"],
flag))
# first guesses # first guesses
t10n, q10n = np.copy(Ta), np.copy(qair) t10n, q10n = np.copy(Ta), np.copy(qair)
tv10n = t10n*(1+0.61*q10n) tv10n = t10n*(1+0.6077*q10n)
# Zeng et al. 1998 # Zeng et al. 1998
tv=th*(1.+0.61*qair) # virtual potential T tv=th*(1+0.6077*qair) # virtual potential T
dtv=dt*(1.+0.61*qair)+0.61*th*dq dtv=dt*(1+0.6077*qair)+0.6077*th*dq
# ------------ # ------------
rho = P*100/(287.1*tv10n) rho = P*100/(287.1*tv10n)
lv = (2.501-0.00237*(sst-CtoK))*1e6 lv = (2.501-0.00237*(sst-CtoK))*1e6
cp = 1004.67*(1 + 0.00084*qsea) cp = 1004.67*(1 + 0.00084*qsea)
u10n = np.copy(spd) u10n = np.copy(spd)
cdn = cdn_calc(u10n, Ta, None, lat, meth) cd10n = cdn_calc(u10n, Ta, None, lat, meth)
ctn, ct, cqn, cq = (np.zeros(spd.shape)*np.nan, np.zeros(spd.shape)*np.nan, 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) np.zeros(spd.shape)*np.nan, np.zeros(spd.shape)*np.nan)
psim, psit, psiq = (np.zeros(spd.shape), np.zeros(spd.shape), psim, psit, psiq = (np.zeros(spd.shape), 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) tsr, tsrv = np.zeros(spd.shape), np.zeros(spd.shape)
qsr = np.zeros(spd.shape) qsr = np.zeros(spd.shape)
# cskin parameters # cskin parameters
...@@ -228,22 +229,23 @@ def AirSeaFluxCode(spd, T, SST, lat=None, hum=None, P=None, hin=18, hout=10, ...@@ -228,22 +229,23 @@ def AirSeaFluxCode(spd, T, SST, lat=None, hum=None, P=None, hin=18, hout=10,
elif (tol[0] == 'all'): elif (tol[0] == 'all'):
old = np.array([np.copy(u10n), np.copy(t10n), np.copy(q10n), old = 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)])
cdn[ind] = cdn_calc(u10n[ind], Ta[ind], None, lat[ind], meth) cd10n[ind] = cdn_calc(u10n[ind], Ta[ind], None, lat[ind], meth)
if (np.all(np.isnan(cdn))): if (np.all(np.isnan(cd10n))):
break break
logging.info('break %s at iteration %s cdn<0', meth, it) logging.info('break %s at iteration %s cd10n<0', meth, it)
zo[ind] = ref_ht/np.exp(kappa/np.sqrt(cdn[ind])) zo[ind] = ref_ht/np.exp(kappa/np.sqrt(cd10n[ind]))
psim[ind] = psim_calc(h_in[0, ind]/monob[ind], meth) 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]) cd[ind] = cd_calc(cd10n[ind], h_in[0, ind], ref_ht, psim[ind])
ctn[ind], cqn[ind] = ctcqn_calc(h_in[1, ind]/monob[ind], cdn[ind], ct10n[ind], cq10n[ind] = ctcqn_calc(h_in[1, ind]/monob[ind],
u10n[ind], zo[ind], Ta[ind], meth) cd10n[ind], u10n[ind], zo[ind],
Ta[ind], meth)
zot[ind] = ref_ht/(np.exp(np.power(kappa, 2) / 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) / 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) psit[ind] = psit_calc(h_in[1, ind]/monob[ind], meth)
psiq[ind] = psit_calc(h_in[2, 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, h_in[1, ind], h_in[2, ind], ref_ht,
psit[ind], psiq[ind]) psit[ind], psiq[ind])
usr[ind], tsr[ind], qsr[ind] = get_strs(h_in[:, ind], monob[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, ...@@ -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])) tsr[ind]/kappa*(np.log(h_in[1, ind]/ref_ht)-psit[ind]))
q10n[ind] = (qair[ind] - q10n[ind] = (qair[ind] -
qsr[ind]/kappa*(np.log(h_in[2, ind]/ref_ht)-psiq[ind])) qsr[ind]/kappa*(np.log(h_in[2, ind]/ref_ht)-psiq[ind]))
tv10n[ind] = t10n[ind]*(1+0.61*q10n[ind]) tv10n[ind] = t10n[ind]*(1+0.6077*q10n[ind])
tsrv[ind], monob[ind] = get_L(L, lat[ind], usr[ind], tsr[ind], tsrv[ind], monob[ind], Rb[ind] = get_L(L, lat[ind], usr[ind], tsr[ind],
qsr[ind], t10n[ind], h_in[:, ind], qsr[ind], h_in[:, ind], Ta[ind],
Ta[ind], sst[ind], sst[ind]-dter[ind]*cskin+dtwl[ind]*wl,
qair[ind], qsea[ind], q10n[ind], qair[ind], qsea[ind], wind[ind],
wind[ind], np.copy(monob[ind]), meth) 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) psim[ind] = psim_calc(h_in[0, ind]/monob[ind], meth)
psit[ind] = psit_calc(h_in[1, 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) 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, ...@@ -395,14 +399,24 @@ def AirSeaFluxCode(spd, T, SST, lat=None, hum=None, P=None, hin=18, hout=10,
# calculate output parameters # calculate output parameters
rho = (0.34838*P)/(tv10n) rho = (0.34838*P)/(tv10n)
t10n = t10n-(273.16+tlapse*ref_ht) t10n = t10n-(273.16+tlapse*ref_ht)
zo = ref_ht/np.exp(kappa/cdn**0.5) # solve for zo from cd10n
zot = ref_ht/(np.exp(kappa**2/(ctn*np.log(ref_ht/zo)))) zo = ref_ht/np.exp(kappa/np.sqrt(cd10n))
zoq = ref_ht/(np.exp(kappa**2/(cqn*np.log(ref_ht/zo)))) # 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 + uref = (spd-usr/kappa*(np.log(h_in[0]/h_out[0])-psim +
psim_calc(h_out[0]/monob, meth))) psim_calc(h_out[0]/monob, meth)))
tref = (Ta-tsr/kappa*(np.log(h_in[1]/h_out[1])-psit + tref = (Ta-tsr/kappa*(np.log(h_in[1]/h_out[1])-psit +
psit_calc(h_out[0]/monob, meth))) 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]) - qref = (qair-qsr/kappa*(np.log(h_in[2]/h_out[2]) -
psit+psit_calc(h_out[2]/monob, meth))) psit+psit_calc(h_out[2]/monob, meth)))
flag = np.where((q10n < 0) & (flag == "n"), "q", 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, ...@@ -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", flag = np.where((itera == -1) & (flag == "n"), "i",
np.where((itera == -1) & (flag != "n"), flag+[","]+["i"], np.where((itera == -1) & (flag != "n"), flag+[","]+["i"],
flag)) 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[0][:] = tau
res[1][:] = sensible res[1][:] = sensible
res[2][:] = latent res[2][:] = latent
...@@ -451,21 +499,24 @@ def AirSeaFluxCode(spd, T, SST, lat=None, hum=None, P=None, hin=18, hout=10, ...@@ -451,21 +499,24 @@ def AirSeaFluxCode(spd, T, SST, lat=None, hum=None, P=None, hin=18, hout=10,
res[33][:] = Rl res[33][:] = Rl
res[34][:] = Rs res[34][:] = Rs
res[35][:] = Rnl res[35][:] = Rnl
res[36][:] = np.sqrt(np.power(wind, 2)-np.power(spd, 2))
res[37][:] = Rb
res[38][:] = rh
if (out == 0): if (out == 0):
res[:, ind] = np.nan res[:, ind] = np.nan
# set missing values where data have non acceptable values # 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.asarray([np.where((spd < 0) | (q10n < 0), np.nan,
res = [np.where(q10n < 0, np.nan, res[i][:]) for i in range(36)] res[i][:]) for i in range(39)])
res = np.asarray(res)
# output with pandas # output with pandas
resAll = pd.DataFrame(data=res.T, index=range(len(spd)), resAll = pd.DataFrame(data=res.T, index=range(len(spd)),
columns=["tau", "shf", "lhf", "L", "cd", "cdn", "ct", columns=["tau", "shf", "lhf", "L", "cd", "cdn", "ct",
"ctn", "cq", "cqn", "tsrv", "tsr", "qsr", "ctn", "cq", "cqn", "tsrv", "tsr", "qsr",
"usr", "psim", "psit","psiq", "u10n", "t10n", "usr", "psim", "psit","psiq", "u10n", "t10n",
"tv10n", "q10n", "zo", "zot", "zoq", "uref", "tv10n", "q10n", "zo", "zot", "zoq", "uref",
"tref", "qref", "iteration", "dter", "dqer", "tref", "qref", "iteration", "dter", "dqer",
"dtwl", "qair", "qsea", "Rl", "Rs", "Rnl"]) "dtwl", "qair", "qsea", "Rl", "Rs", "Rnl",
"ug", "Rib", "rh"])
resAll["flag"] = flag resAll["flag"] = flag
return resAll 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) ...@@ -6,7 +6,7 @@ from util_subs import (CtoK, kappa, gc, visc_air)
def cdn_calc(u10n, Ta, Tp, lat, meth="S80"): def cdn_calc(u10n, Ta, Tp, lat, meth="S80"):
""" """
Calculates neutral drag coefficient Calculates 10m neutral drag coefficient
Parameters Parameters
---------- ----------
...@@ -56,7 +56,7 @@ def cdn_calc(u10n, Ta, Tp, lat, meth="S80"): ...@@ -56,7 +56,7 @@ def cdn_calc(u10n, Ta, Tp, lat, meth="S80"):
def cdn_from_roughness(u10n, Ta, Tp, lat, meth="S88"): 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 Parameters
---------- ----------
...@@ -97,9 +97,6 @@ def cdn_from_roughness(u10n, Ta, Tp, lat, meth="S88"): ...@@ -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 zo = a*np.power(usr, 2)/g+0.11*visc_air(Ta)/usr
elif (meth == "C35"): elif (meth == "C35"):
a = 0.011*np.ones(Ta.shape) 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) 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 zo = 0.11*visc_air(Ta)/usr+a*np.power(usr, 2)/g
elif (meth == "C40"): elif (meth == "C40"):
...@@ -117,7 +114,7 @@ def cdn_from_roughness(u10n, Ta, Tp, lat, meth="S88"): ...@@ -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 Calculates drag coefficient at reference height
...@@ -125,9 +122,9 @@ def cd_calc(cdn, height, ref_ht, psim): ...@@ -125,9 +122,9 @@ def cd_calc(cdn, height, ref_ht, psim):
---------- ----------
cdn : float cdn : float
neutral drag coefficient neutral drag coefficient
height : float hin : float
original sensor height [m] original sensor height [m]
ref_ht : float hout : float
reference height [m] reference height [m]
psim : float psim : float
momentum stability function momentum stability function
...@@ -136,14 +133,14 @@ def cd_calc(cdn, height, ref_ht, psim): ...@@ -136,14 +133,14 @@ def cd_calc(cdn, height, ref_ht, psim):
------- -------
cd : float 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 return cd
# --------------------------------------------------------------------- # ---------------------------------------------------------------------
def ctcqn_calc(zol, cdn, u10n, zo, Ta, meth="S80"): 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 Parameters
---------- ----------
...@@ -209,9 +206,6 @@ def ctcqn_calc(zol, cdn, u10n, zo, Ta, meth="S80"): ...@@ -209,9 +206,6 @@ def ctcqn_calc(zol, cdn, u10n, zo, Ta, meth="S80"):
1.0e-4/np.power(rr, 0.55)) # temperature roughness 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), 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)) 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) 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 == "ecmwf" or meth == "Beljaars"): elif (meth == "ecmwf" or meth == "Beljaars"):
...@@ -227,7 +221,7 @@ def ctcqn_calc(zol, cdn, u10n, zo, Ta, meth="S80"): ...@@ -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 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): ...@@ -245,8 +239,8 @@ def ctcq_calc(cdn, cd, ctn, cqn, ht, hq, ref_ht, psit, psiq):
original temperature sensor height [m] original temperature sensor height [m]
hq : float hq : float
original moisture sensor height [m] original moisture sensor height [m]
ref_ht : float hout : float
reference height [m] output height [m]
psit : float psit : float
heat stability function heat stability function
psiq : float psiq : float
...@@ -260,9 +254,9 @@ def ctcq_calc(cdn, cd, ctn, cqn, ht, hq, ref_ht, psit, psiq): ...@@ -260,9 +254,9 @@ def ctcq_calc(cdn, cd, ctn, cqn, ht, hq, ref_ht, psit, psiq):
moisture exchange coefficient moisture exchange coefficient
""" """
ct = (ctn*np.sqrt(cd/cdn) / 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) / 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 return ct, cq
# --------------------------------------------------------------------- # ---------------------------------------------------------------------
...@@ -736,8 +730,6 @@ def cs_ecmwf(rho, Rs, Rnl, cp, lv, usr, tsr, qsr, sst, lat): ...@@ -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 # # fraction of the solar radiation absorbed in layer delta eq. 8.153
# and Eq.(5) Zeng & Beljaars, 2005 # and Eq.(5) Zeng & Beljaars, 2005
fs = 0.065+11*d-6.6e-5/d*(1-np.exp(-d/8e-4)) 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 Q = Qnsol-fs*Rns
d = delta(aw, Q, usr, lat) d = delta(aw, Q, usr, lat)
dtc = Q*d/0.6 # (rhow*cw*kw)eq. 8.151 dtc = Q*d/0.6 # (rhow*cw*kw)eq. 8.151
...@@ -918,8 +910,8 @@ def get_gust(beta, Ta, usr, tsrv, zi, lat): ...@@ -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, def get_L(L, lat, usr, tsr, qsr, hin, Ta, sst, qair, qsea, wind, monob, psim,
wind, monob, meth): meth):
""" """
calculates Monin-Obukhov length and virtual star temperature 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, ...@@ -968,6 +960,7 @@ def get_L(L, lat, usr, tsr, qsr, t10n, hin, Ta, sst, qair, qsea, q10n,
""" """
g = gc(lat) g = gc(lat)
Rb = np.empty(sst.shape)
if (L == "S80"): if (L == "S80"):
# as in NCAR, LY04 # as in NCAR, LY04
tsrv = tsr*(1+0.6077*qair)+0.6077*Ta*qsr 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, ...@@ -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) temp = np.minimum(np.abs(temp), 10/hin[0])*np.sign(temp)
monob = 1/np.copy(temp) monob = 1/np.copy(temp)
elif (L == "ecmwf"): elif (L == "ecmwf"):
Rb = np.empty(sst.shape)
tsrv = tsr*(1+0.6077*qair)+0.6077*Ta*qsr 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] / # from eq. 3.24 ifs Cy46r1 pp. 37
(1005+1860*qair))) + thvs = sst*(1+0.6077*qsea) # virtual SST
0.6077*(qair-qsea)) 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) zo = (0.11*visc_air(Ta)/usr+0.018*np.power(usr, 2)/g)
zot = 0.40*visc_air(Ta)/usr 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) + monob, meth) +
psim_calc(zo/monob, meth), 2) / psim_calc(zo/monob, meth), 2) /
(np.log((hin[0]+zo)/zot) - (np.log((hin[1]+zo)/zot) -
psit_calc((hin[0]+zo)/monob, meth) + psit_calc((hin[1]+zo)/monob, meth) +
psit_calc(zot/monob, meth)))) psit_calc(zot/monob, meth))))
monob = hin[0]/zol monob = hin[1]/zol
return tsrv, monob 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, ...@@ -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): elif (np.size(gust) < 3):
sys.exit("gust input must be a 3x1 array") sys.exit("gust input must be a 3x1 array")
if (L not in [None, "S80", "ecmwf"]): 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" 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"
...@@ -149,4 +149,4 @@ def get_init(spd, T, SST, lat, P, Rl, Rs, cskin, skin, wl, gust, L, tol, meth, ...@@ -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] tol = ['flux', 1e-3, 0.1, 0.1]
elif (tol[0] not in ['flux', 'ref', 'all']): elif (tol[0] not in ['flux', 'ref', 'all']):
sys.exit("unknown tolerance input") sys.exit("unknown tolerance input")
return lat, P, Rl, Rs, cskin, skin, wl, gust, tol, L return lat, P, Rl, Rs, cskin, skin, wl, gust, tol, L
\ No newline at end of file
...@@ -384,6 +384,7 @@ def get_hum(hum, T, sst, P, qmeth): ...@@ -384,6 +384,7 @@ def get_hum(hum, T, sst, P, qmeth):
if (np.all(RH < 1)): if (np.all(RH < 1)):
sys.exit("input relative humidity units should be \%") sys.exit("input relative humidity units should be \%")
qair, qsea = np.nan, np.nan 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) 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) qair = qsat_air(T, P, RH, qmeth)/1000 # q of air (kg/kg)
elif (hum[0] == 'q'): elif (hum[0] == 'q'):
...@@ -396,6 +397,7 @@ def get_hum(hum, T, sst, P, qmeth): ...@@ -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))) 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))) es = 611.21*np.exp(17.502*((T-273.16)/(T-32.19)))
RH = 100*esd/es 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) 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) qsea = qsat_sea(sst, P, qmeth)/1000 # surface water q (kg/kg)
return qair, qsea 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 ...@@ -19,14 +19,14 @@ from tabulate import tabulate
#%% #%%
def reject_outliers(data, m=2): def reject_outliers(data, m=2):
x = np.copy(data) x = np.copy(data)
x = np.where(np.abs(x - np.nanmean(x)) < m*np.nanstd(x), x = np.where(np.abs(x-np.nanmean(x)) < m*np.nanstd(x), x, np.nan)
x, np.nan)
return x return x
def toy_ASFC(inF, outF, gustIn, cskinIn, tolIn, meth): 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 Parameters
---------- ----------
...@@ -39,7 +39,7 @@ def toy_ASFC(inF, outF, gustIn, cskinIn, tolIn, meth): ...@@ -39,7 +39,7 @@ def toy_ASFC(inF, outF, gustIn, cskinIn, tolIn, meth):
cskinIn : int cskinIn : int
cool skin option input 0 or 1 cool skin option input 0 or 1
tolIn : float 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 meth : str
parametrisation method option parametrisation method option
...@@ -70,14 +70,9 @@ def toy_ASFC(inF, outF, gustIn, cskinIn, tolIn, meth): ...@@ -70,14 +70,9 @@ def toy_ASFC(inF, outF, gustIn, cskinIn, tolIn, meth):
hin = np.array([hu, ht, ht]) hin = np.array([hu, ht, ht])
del hu, ht, inDt del hu, ht, inDt
#%% run AirSeaFluxCode #%% 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, hin=hin, Rs=sw, tol=tolIn, gust=gustIn,
cskin=cskinIn, meth=meth, L="ecmwf", n=30) 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'): elif (inF == 'era5_r360x180.nc'):
#%% load era5_r360x180.nc #%% load era5_r360x180.nc
...@@ -95,15 +90,20 @@ def toy_ASFC(inF, outF, gustIn, cskinIn, tolIn, meth): ...@@ -95,15 +90,20 @@ def toy_ASFC(inF, outF, gustIn, cskinIn, tolIn, meth):
u = np.array(fid.variables["u10"]) u = np.array(fid.variables["u10"])
v = np.array(fid.variables["v10"]) v = np.array(fid.variables["v10"])
lsm = np.array(fid.variables["lsm"]) lsm = np.array(fid.variables["lsm"])
icon = np.array(fid.variables["siconc"])
fid.close() fid.close()
spd = np.sqrt(np.power(u, 2)+np.power(v, 2)) spd = np.sqrt(np.power(u, 2)+np.power(v, 2))
del u, v, fid del u, v, fid
lsm = np.where(lsm > 0, np.nan, 1) # reverse 0 on land 1 over ocean 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]) hin = np.array([10, 2, 2])
latIn = np.tile(lat, (len(lon), 1)).T.reshape(len(lon)*len(lat)) latIn = np.tile(lat, (len(lon), 1)).T.reshape(len(lon)*len(lat))
date = np.copy(tim) date = np.copy(tim)
#%% run AirSeaFluxCode #%% 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 # reshape input and run code
for x in range(len(tim)): for x in range(len(tim)):
temp = AirSeaFluxCode(spd.reshape(len(tim), len(lon)*len(lat))[x, :], temp = AirSeaFluxCode(spd.reshape(len(tim), len(lon)*len(lat))[x, :],
...@@ -117,11 +117,15 @@ def toy_ASFC(inF, outF, gustIn, cskinIn, tolIn, meth): ...@@ -117,11 +117,15 @@ def toy_ASFC(inF, outF, gustIn, cskinIn, tolIn, meth):
Rl=lw.reshape(len(tim), len(lon)*len(lat))[x, :], Rl=lw.reshape(len(tim), len(lon)*len(lat))[x, :],
gust=gustIn, cskin=cskinIn, tol=tolIn, qmeth='WMO', gust=gustIn, cskin=cskinIn, tol=tolIn, qmeth='WMO',
meth=meth, n=30, L="ecmwf") meth=meth, n=30, L="ecmwf")
a = temp.loc[:,"tau":"Rnl"] a = temp.loc[:,"tau":"rh"]
a = a.to_numpy() a = a.to_numpy()
del temp flg[x, :] = temp["flag"]
res[x, :, :] = a 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 (outF[-3:] == '.nc'):
if (inF == 'era5_r360x180.nc'): if (inF == 'era5_r360x180.nc'):
...@@ -169,46 +173,55 @@ def toy_ASFC(inF, outF, gustIn, cskinIn, tolIn, meth): ...@@ -169,46 +173,55 @@ def toy_ASFC(inF, outF, gustIn, cskinIn, tolIn, meth):
Rl = fid.createVariable('Rl', 'f4', ('time','lat','lon')) Rl = fid.createVariable('Rl', 'f4', ('time','lat','lon'))
Rs = fid.createVariable('Rs', 'f4', ('time','lat','lon')) Rs = fid.createVariable('Rs', 'f4', ('time','lat','lon'))
Rnl = fid.createVariable('Rnl', '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 longitude[:] = lon
latitude[:] = lat latitude[:] = lat
Date[:] = tim Date[:] = tim
tau[:] = res[:, :, 0].reshape((len(tim), len(lat), len(lon)))*lsm tau[:] = res[:, :, 0].reshape((len(tim), len(lat), len(lon)))*msk
sensible[:] = res[:, :, 1].reshape((len(tim), len(lat), len(lon)))*lsm sensible[:] = res[:, :, 1].reshape((len(tim), len(lat), len(lon)))*msk
latent[:] = res[:, :, 2].reshape((len(tim), len(lat), len(lon)))*lsm latent[:] = res[:, :, 2].reshape((len(tim), len(lat), len(lon)))*msk
monob[:] = res[:, :, 3].reshape((len(tim), len(lat), len(lon)))*lsm monob[:] = res[:, :, 3].reshape((len(tim), len(lat), len(lon)))*msk
cd[:] = res[:, :, 4].reshape((len(tim), len(lat), len(lon)))*lsm cd[:] = res[:, :, 4].reshape((len(tim), len(lat), len(lon)))*msk
cdn[:] = res[:, :, 5].reshape((len(tim), len(lat), len(lon)))*lsm cdn[:] = res[:, :, 5].reshape((len(tim), len(lat), len(lon)))*msk
ct[:] = res[:, :, 6].reshape((len(tim), len(lat), len(lon)))*lsm ct[:] = res[:, :, 6].reshape((len(tim), len(lat), len(lon)))*msk
ctn[:] = res[:, :, 7].reshape((len(tim), len(lat), len(lon)))*lsm ctn[:] = res[:, :, 7].reshape((len(tim), len(lat), len(lon)))*msk
cq[:] = res[:, :, 8].reshape((len(tim), len(lat), len(lon)))*lsm cq[:] = res[:, :, 8].reshape((len(tim), len(lat), len(lon)))*msk
cqn[:] = res[:, :, 9].reshape((len(tim), len(lat), len(lon)))*lsm cqn[:] = res[:, :, 9].reshape((len(tim), len(lat), len(lon)))*msk
tsrv[:] = res[:, :, 10].reshape((len(tim), len(lat), len(lon)))*lsm tsrv[:] = res[:, :, 10].reshape((len(tim), len(lat), len(lon)))*msk
tsr[:] = res[:, :, 11].reshape((len(tim), len(lat), len(lon)))*lsm tsr[:] = res[:, :, 11].reshape((len(tim), len(lat), len(lon)))*msk
qsr[:] = res[:, :, 12].reshape((len(tim), len(lat), len(lon)))*lsm qsr[:] = res[:, :, 12].reshape((len(tim), len(lat), len(lon)))*msk
usr[:] = res[:, :, 13].reshape((len(tim), len(lat), len(lon)))*lsm usr[:] = res[:, :, 13].reshape((len(tim), len(lat), len(lon)))*msk
psim[:] = res[:, :, 14].reshape((len(tim), len(lat), len(lon)))*lsm psim[:] = res[:, :, 14].reshape((len(tim), len(lat), len(lon)))*msk
psit[:] = res[:, :, 15].reshape((len(tim), len(lat), len(lon)))*lsm psit[:] = res[:, :, 15].reshape((len(tim), len(lat), len(lon)))*msk
psiq[:] = res[:, :, 16].reshape((len(tim), len(lat), len(lon)))*lsm psiq[:] = res[:, :, 16].reshape((len(tim), len(lat), len(lon)))*msk
u10n[:] = res[:, :, 17].reshape((len(tim), len(lat), len(lon)))*lsm u10n[:] = res[:, :, 17].reshape((len(tim), len(lat), len(lon)))*msk
t10n[:] = res[:, :, 18].reshape((len(tim), len(lat), len(lon)))*lsm t10n[:] = res[:, :, 18].reshape((len(tim), len(lat), len(lon)))*msk
tv10n[:] = res[:, :, 19].reshape((len(tim), len(lat), len(lon)))*lsm tv10n[:] = res[:, :, 19].reshape((len(tim), len(lat), len(lon)))*msk
q10n[:] = res[:, :, 20].reshape((len(tim), len(lat), len(lon)))*lsm q10n[:] = res[:, :, 20].reshape((len(tim), len(lat), len(lon)))*msk
zo[:] = res[:, :, 21].reshape((len(tim), len(lat), len(lon)))*lsm zo[:] = res[:, :, 21].reshape((len(tim), len(lat), len(lon)))*msk
zot[:] = res[:, :, 22].reshape((len(tim), len(lat), len(lon)))*lsm zot[:] = res[:, :, 22].reshape((len(tim), len(lat), len(lon)))*msk
zoq[:] = res[:, :, 23].reshape((len(tim), len(lat), len(lon)))*lsm zoq[:] = res[:, :, 23].reshape((len(tim), len(lat), len(lon)))*msk
urefs[:] = res[:, :, 24].reshape((len(tim), len(lat), len(lon)))*lsm urefs[:] = res[:, :, 24].reshape((len(tim), len(lat), len(lon)))*msk
trefs[:] = res[:, :, 25].reshape((len(tim), len(lat), len(lon)))*lsm trefs[:] = res[:, :, 25].reshape((len(tim), len(lat), len(lon)))*msk
qrefs[:] = res[:, :, 26].reshape((len(tim), len(lat), len(lon)))*lsm qrefs[:] = res[:, :, 26].reshape((len(tim), len(lat), len(lon)))*msk
itera[:] = res[:, :, 27].reshape((len(tim), len(lat), len(lon)))*lsm itera[:] = res[:, :, 27].reshape((len(tim), len(lat), len(lon)))*msk
dter[:] = res[:, :, 28].reshape((len(tim), len(lat), len(lon)))*lsm dter[:] = res[:, :, 28].reshape((len(tim), len(lat), len(lon)))*msk
dqer[:] = res[:, :, 29].reshape((len(tim), len(lat), len(lon)))*lsm dqer[:] = res[:, :, 29].reshape((len(tim), len(lat), len(lon)))*msk
dtwl[:] = res[:, :, 30].reshape((len(tim), len(lat), len(lon)))*lsm dtwl[:] = res[:, :, 30].reshape((len(tim), len(lat), len(lon)))*msk
qair[:] = res[:, :, 31].reshape((len(tim), len(lat), len(lon)))*lsm qair[:] = res[:, :, 31].reshape((len(tim), len(lat), len(lon)))*msk
qsea[:] = res[:, :, 32].reshape((len(tim), len(lat), len(lon)))*lsm qsea[:] = res[:, :, 32].reshape((len(tim), len(lat), len(lon)))*msk
Rl = res[:, :, 33].reshape((len(tim), len(lat), len(lon))) Rl[:] = res[:, :, 33].reshape((len(tim), len(lat), len(lon)))*msk
Rs = res[:, :, 34].reshape((len(tim), len(lat), len(lon))) Rs[:] = res[:, :, 34].reshape((len(tim), len(lat), len(lon)))*msk
Rnl = res[:, :, 35].reshape((len(tim), len(lat), len(lon))) 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.long_name = 'Longitude'
longitude.units = 'degrees East' longitude.units = 'degrees East'
latitude.long_name = 'Latitude' latitude.long_name = 'Latitude'
...@@ -252,7 +265,7 @@ def toy_ASFC(inF, outF, gustIn, cskinIn, tolIn, meth): ...@@ -252,7 +265,7 @@ def toy_ASFC(inF, outF, gustIn, cskinIn, tolIn, meth):
tv10n.long_name = '10m neutral virtual temperature' tv10n.long_name = '10m neutral virtual temperature'
tv10n.units = 'degrees Celsius' tv10n.units = 'degrees Celsius'
q10n.long_name = '10m neutral specific humidity' q10n.long_name = '10m neutral specific humidity'
q10n.units = 'gr/kgr' q10n.units = 'kgr/kgr'
zo.long_name = 'momentum roughness length' zo.long_name = 'momentum roughness length'
zo.units = 'm' zo.units = 'm'
zot.long_name = 'temperature roughness length' zot.long_name = 'temperature roughness length'
...@@ -264,19 +277,33 @@ def toy_ASFC(inF, outF, gustIn, cskinIn, tolIn, meth): ...@@ -264,19 +277,33 @@ def toy_ASFC(inF, outF, gustIn, cskinIn, tolIn, meth):
trefs.long_name = 'temperature at ref height' trefs.long_name = 'temperature at ref height'
trefs.units = 'degrees Celsius' trefs.units = 'degrees Celsius'
qrefs.long_name = 'specific humidity at ref height' qrefs.long_name = 'specific humidity at ref height'
qrefs.units = 'gr/kgr' qrefs.units = 'kgr/kgr'
qair.long_name = 'specific humidity of air' qair.long_name = 'specific humidity of air'
qair.units = 'gr/kgr' qair.units = 'kgr/kgr'
qsea.long_name = 'specific humidity over water' qsea.long_name = 'specific humidity over water'
qsea.units = 'gr/kgr' qsea.units = 'kgr/kgr'
itera.long_name = 'number of iterations' 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() fid.close()
#%% delete variables #%% delete variables
del longitude, latitude, Date, tau, sensible, latent, monob, cd, cdn 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 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 tv10n, q10n, zo, zot, zoq, urefs, trefs, qrefs, itera, dter, dqer
del qair, qsea, Rl, Rs, Rnl, dtwl 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: else:
#%% save NetCDF4 #%% save NetCDF4
fid = nc.Dataset(outF,'w', format='NETCDF4') fid = nc.Dataset(outF,'w', format='NETCDF4')
...@@ -316,52 +343,61 @@ def toy_ASFC(inF, outF, gustIn, cskinIn, tolIn, meth): ...@@ -316,52 +343,61 @@ def toy_ASFC(inF, outF, gustIn, cskinIn, tolIn, meth):
itera = fid.createVariable('iter', 'i4', 'time') itera = fid.createVariable('iter', 'i4', 'time')
dter = fid.createVariable('dter', 'f4', 'time') dter = fid.createVariable('dter', 'f4', 'time')
dqer = fid.createVariable('dqer', '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') qair = fid.createVariable('qair', 'f4', 'time')
qsea = fid.createVariable('qsea', 'f4', 'time') qsea = fid.createVariable('qsea', 'f4', 'time')
Rl = fid.createVariable('Rl', 'f4', 'time') Rl = fid.createVariable('Rl', 'f4', 'time')
Rs = fid.createVariable('Rs', 'f4', 'time') Rs = fid.createVariable('Rs', 'f4', 'time')
Rnl = fid.createVariable('Rnl', '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 longitude[:] = lon
latitude[:] = lat latitude[:] = lat
Date[:] = date Date[:] = date
tau[:] = res[0] tau[:] = res["tau"]
sensible[:] = res[1] sensible[:] = res["shf"]
latent[:] = res[2] latent[:] = res["lhf"]
monob[:] = res[3] monob[:] = res["L"]
cd[:] = res[4] cd[:] = res["cd"]
cdn[:] = res[5] cdn[:] = res["cdn"]
ct[:] = res[6] ct[:] = res["ct"]
ctn[:] = res[7] ctn[:] = res["ctn"]
cq[:] = res[8] cq[:] = res["cq"]
cqn[:] = res[9] cqn[:] = res["cqn"]
tsrv[:] = res[10] tsrv[:] = res["tsrv"]
tsr[:] = res[11] tsr[:] = res["tsr"]
qsr[:] = res[12] qsr[:] = res["qsr"]
usr[:] = res[13] usr[:] = res["usr"]
psim[:] = res[14] psim[:] = res["psim"]
psit[:] = res[15] psit[:] = res["psit"]
psiq[:] = res[16] psiq[:] = res["psiq"]
u10n[:] = res[17] u10n[:] = res["u10n"]
t10n[:] = res[18] t10n[:] = res["t10n"]
tv10n[:] = res[19] tv10n[:] = res["tv10n"]
q10n[:] = res[20] q10n[:] = res["q10n"]
zo[:] = res[21] zo[:] = res["zo"]
zot[:] = res[22] zot[:] = res["zot"]
zoq[:] = res[23] zoq[:] = res["zoq"]
urefs[:] = res[24] urefs[:] = res["uref"]
trefs[:] = res[25] trefs[:] = res["tref"]
qrefs[:] = res[26] qrefs[:] = res["qref"]
itera[:] = res[27] itera[:] = res["iteration"]
dter[:] = res[28] dter[:] = res["dter"]
dqer[:] = res[29] dqer[:] = res["dqer"]
dtwl[:] = res[30] dtwl[:] = res["dtwl"]
qair[:] = res[31] qair[:] = res["qair"]
qsea[:] = res[32] qsea[:] = res["qsea"]
Rl[:] = res[33] Rl[:] = res["Rl"]
Rs[:] = res[34] Rs[:] = res["Rs"]
Rnl[:] = res[35] Rnl[:] = res["Rnl"]
ug[:] = res["ug"]
Rib[:] = res["Rib"]
rh[:] = res["rh"]
flag[:] = res["flag"]
longitude.long_name = 'Longitude' longitude.long_name = 'Longitude'
longitude.units = 'degrees East' longitude.units = 'degrees East'
latitude.long_name = 'Latitude' latitude.long_name = 'Latitude'
...@@ -405,7 +441,7 @@ def toy_ASFC(inF, outF, gustIn, cskinIn, tolIn, meth): ...@@ -405,7 +441,7 @@ def toy_ASFC(inF, outF, gustIn, cskinIn, tolIn, meth):
tv10n.long_name = '10m neutral virtual temperature' tv10n.long_name = '10m neutral virtual temperature'
tv10n.units = 'degrees Celsius' tv10n.units = 'degrees Celsius'
q10n.long_name = '10m neutral specific humidity' q10n.long_name = '10m neutral specific humidity'
q10n.units = 'gr/kgr' q10n.units = 'kgr/kgr'
zo.long_name = 'momentum roughness length' zo.long_name = 'momentum roughness length'
zo.units = 'm' zo.units = 'm'
zot.long_name = 'temperature roughness length' zot.long_name = 'temperature roughness length'
...@@ -417,27 +453,39 @@ def toy_ASFC(inF, outF, gustIn, cskinIn, tolIn, meth): ...@@ -417,27 +453,39 @@ def toy_ASFC(inF, outF, gustIn, cskinIn, tolIn, meth):
trefs.long_name = 'temperature at ref height' trefs.long_name = 'temperature at ref height'
trefs.units = 'degrees Celsius' trefs.units = 'degrees Celsius'
qrefs.long_name = 'specific humidity at ref height' qrefs.long_name = 'specific humidity at ref height'
qrefs.units = 'gr/kgr' qrefs.units = 'kgr/kgr'
qair.long_name = 'specific humidity of air' qair.long_name = 'specific humidity of air'
qair.units = 'gr/kgr' qair.units = 'kgr/kgr'
qsea.long_name = 'specific humidity over water' qsea.long_name = 'specific humidity over water'
qsea.units = 'gr/kgr' qsea.units = 'kgr/kgr'
itera.long_name = 'number of iterations' 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() fid.close()
#%% delete variables #%% delete variables
del longitude, latitude, Date, tau, sensible, latent, monob, cd, cdn 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 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 tv10n, q10n, zo, zot, zoq, urefs, trefs, qrefs, itera, dter, dqer
del qair, qsea, Rl, Rs, Rnl del qair, qsea, Rl, Rs, Rnl, ug, rh, Rib
del t, rh, date, p, sw, spd, hin del t, date, p, sw, spd, hin, sst
else: else:
#%% save as .csv #%% save as .csv
np.savetxt(outF, np.vstack((date, lon, lat, res)).T, res.insert(loc=0, column='date', value=date)
delimiter=',', res.insert(loc=1, column='lon', value=lon)
header="date, lon, lat, tau, shf, lhf, L, cd, cdn, ct, ctn," res.insert(loc=2, column='lat', value=lat)
" cq, cqn, tsrv, tsr, qsr, usr, psim, psit, psiq, u10n," res.to_csv(outF)
" t10n, tv10n, q10n, zo, zot, zoq, uref, tref, qref, iter,"
" dter, dqer, dtwl, qair, qsea, Rl, Rs, Rnl")
return res, lon, lat return res, lon, lat
#%% run function #%% run function
start_time = time.perf_counter() start_time = time.perf_counter()
...@@ -530,7 +578,7 @@ elif (inF == "data_all.csv"): ...@@ -530,7 +578,7 @@ elif (inF == "data_all.csv"):
ttl = ["tau (Nm$^{-2}$)", "shf (Wm$^{-2}$)", "lhf (Wm$^{-2}$)"] ttl = ["tau (Nm$^{-2}$)", "shf (Wm$^{-2}$)", "lhf (Wm$^{-2}$)"]
for i in range(3): for i in range(3):
plt.figure() plt.figure()
plt.plot(res[i],'.c', markersize=1) plt.plot(res[ttl[i][:3]],'.c', markersize=1)
plt.title(meth) plt.title(meth)
plt.xlabel("points") plt.xlabel("points")
plt.ylabel(ttl[i]) plt.ylabel(ttl[i])
...@@ -564,7 +612,8 @@ ttl = np.asarray(["tau ", "shf ", "lhf ", "L ", "cd ", "cdn ", ...@@ -564,7 +612,8 @@ ttl = np.asarray(["tau ", "shf ", "lhf ", "L ", "cd ", "cdn ",
"qsr ", "usr ", "psim ", "psit ", "psiq ", "u10n ", "qsr ", "usr ", "psim ", "psit ", "psiq ", "u10n ",
"t10n ", "tv10n", "q10n ", "zo ", "zot ", "zoq ", "t10n ", "tv10n", "q10n ", "zo ", "zot ", "zoq ",
"urefs", "trefs", "qrefs", "itera", "dter ", "dqer ", "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%"] header = ["var", "mean", "median", "min", "max", "5%", "95%"]
n = np.shape(res) n = np.shape(res)
stats = np.copy(ttl) stats = np.copy(ttl)
...@@ -582,16 +631,18 @@ if (inF == 'era5_r360x180.nc'): ...@@ -582,16 +631,18 @@ if (inF == 'era5_r360x180.nc'):
"2.2e")), file=open('./stats.txt', 'a')) "2.2e")), file=open('./stats.txt', 'a'))
print('-'*79+'\n', file=open('./stats.txt', 'a')) print('-'*79+'\n', file=open('./stats.txt', 'a'))
elif (inF == "data_all.csv"): elif (inF == "data_all.csv"):
stats = np.c_[stats, np.nanmean(res, axis=1)] a = res.loc[:,"tau":"rh"].to_numpy(dtype="float64").T
stats = np.c_[stats, np.nanmedian(res, axis=1)] stats = np.c_[stats, np.nanmean(a, axis=1)]
stats = np.c_[stats, np.nanmin(res, axis=1)] stats = np.c_[stats, np.nanmedian(a, axis=1)]
stats = np.c_[stats, np.nanmax(res, axis=1)] stats = np.c_[stats, np.nanmin(a, axis=1)]
stats = np.c_[stats, np.nanpercentile(res, 5, axis=1)] stats = np.c_[stats, np.nanmax(a, axis=1)]
stats = np.c_[stats, np.nanpercentile(res, 95, 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", print(tabulate(stats, headers=header, tablefmt="github", numalign="left",
floatfmt=("s", "2.2e", "2.2e", "2.2e", "2.2e", "2.2e", floatfmt=("s", "2.2e", "2.2e", "2.2e", "2.2e", "2.2e",
"2.2e")), file=open('./stats.txt', 'a')) "2.2e")), file=open('./stats.txt', 'a'))
print('-'*79+'\n', 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: {},' print('input file name: {}, \n method: {}, \n gustiness: {}, \n cskin: {},'
' \n tolerance: {}, \n output is written in: {}'.format(inF, meth, ' \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