142 lines
3.8 KiB
Python
142 lines
3.8 KiB
Python
import numpy as np
|
||
from modules.volscatt import volscatt
|
||
from modules.dladgen import dladgen
|
||
from modules.campbell import campbell
|
||
from modules.Jfunc import Jfunc1, Jfunc2, Jfunc3
|
||
|
||
def sail(rho, tau, LIDFa, LIDFb, TypeLidf, lai, q, tts, tto, psi, rsoil,wl):
|
||
rd = np.pi / 180
|
||
cts = np.cos(rd * tts)
|
||
cto = np.cos(rd * tto)
|
||
ctscto = cts * cto
|
||
tants = np.tan(rd * tts)
|
||
tanto = np.tan(rd * tto)
|
||
cospsi = np.cos(rd * psi)
|
||
dso = np.sqrt(tants**2 + tanto**2 - 2 * tants * tanto * cospsi)
|
||
|
||
# Generate LIDF
|
||
if TypeLidf == 1:
|
||
lidf, litab = dladgen(LIDFa, LIDFb)
|
||
elif TypeLidf == 2:
|
||
lidf, litab = campbell(LIDFa)
|
||
|
||
# Initialize geometric coefficients
|
||
ks = ko = bf = sob = sof = 0
|
||
na = len(litab)
|
||
|
||
for i in range(na):
|
||
ttl = litab[i]
|
||
ctl = np.cos(rd * ttl)
|
||
chi_s, chi_o, frho, ftau = volscatt(tts, tto, psi, ttl)
|
||
|
||
ksli = chi_s / cts
|
||
koli = chi_o / cto
|
||
sobli = frho * np.pi / ctscto
|
||
sofli = ftau * np.pi / ctscto
|
||
bfli = ctl ** 2
|
||
|
||
ks += ksli * lidf[i]
|
||
ko += koli * lidf[i]
|
||
bf += bfli * lidf[i]
|
||
sob += sobli * lidf[i]
|
||
sof += sofli * lidf[i]
|
||
|
||
# Structure factors
|
||
sdb = 0.5 * (ks + bf)
|
||
sdf = 0.5 * (ks - bf)
|
||
dob = 0.5 * (ko + bf)
|
||
dof = 0.5 * (ko - bf)
|
||
ddb = 0.5 * (1 + bf)
|
||
ddf = 0.5 * (1 - bf)
|
||
|
||
sigb = ddb * rho + ddf * tau
|
||
sigf = ddf * rho + ddb * tau
|
||
att = 1 - sigf
|
||
m2 = (att + sigb) * (att - sigb)
|
||
m2[m2 <= 0] = 0
|
||
m = np.sqrt(m2)
|
||
|
||
sb = sdb * rho + sdf * tau
|
||
sf = sdf * rho + sdb * tau
|
||
vb = dob * rho + dof * tau
|
||
vf = dof * rho + dob * tau
|
||
w = sob * rho + sof * tau
|
||
|
||
if lai <= 0:
|
||
return rsoil, rsoil, rsoil, rsoil
|
||
|
||
e1 = np.exp(-m * lai)
|
||
e2 = e1**2
|
||
rinf = (att - m) / sigb
|
||
rinf2 = rinf**2
|
||
re = rinf * e1
|
||
denom = 1 - rinf2 * e2
|
||
|
||
J1ks = Jfunc1(ks, m, lai)
|
||
J2ks = Jfunc2(ks, m, lai)
|
||
J1ko = Jfunc1(ko, m, lai)
|
||
J2ko = Jfunc2(ko, m, lai)
|
||
|
||
Ps = (sf + sb * rinf) * J1ks
|
||
Qs = (sf * rinf + sb) * J2ks
|
||
Pv = (vf + vb * rinf) * J1ko
|
||
Qv = (vf * rinf + vb) * J2ko
|
||
|
||
rdd = rinf * (1 - e2) / denom
|
||
tdd = (1 - rinf2) * e1 / denom
|
||
tsd = (Ps - re * Qs) / denom
|
||
rsd = (Qs - re * Ps) / denom
|
||
tdo = (Pv - re * Qv) / denom
|
||
rdo = (Qv - re * Pv) / denom
|
||
|
||
tss = np.exp(-ks * lai)
|
||
too = np.exp(-ko * lai)
|
||
z = Jfunc3(ks, ko, lai)
|
||
g1 = (z - J1ks * too) / (ko + m)
|
||
g2 = (z - J1ko * tss) / (ks + m)
|
||
|
||
Tv1 = (vf * rinf + vb) * g1
|
||
Tv2 = (vf + vb * rinf) * g2
|
||
T1 = Tv1 * (sf + sb * rinf)
|
||
T2 = Tv2 * (sf * rinf + sb)
|
||
T3 = (rdo * Qs + tdo * Ps) * rinf
|
||
rsod = (T1 + T2 - T3) / (1 - rinf2)
|
||
|
||
# Hotspot effect
|
||
if q <= 0:
|
||
alf = 1e6
|
||
else:
|
||
alf = min((dso / q) * 2 / (ks + ko), 200)
|
||
|
||
if alf == 0:
|
||
tsstoo = tss
|
||
sumint = (1 - tss) / (ks * lai)
|
||
else:
|
||
fhot = lai * np.sqrt(ko * ks)
|
||
fint = (1 - np.exp(-alf)) * 0.05
|
||
sumint = 0
|
||
x1 = y1 = 0
|
||
f1 = 1
|
||
for i in range(20):
|
||
x2 = -np.log(1 - i * fint) / alf if i < 19 else 1
|
||
y2 = -(ko + ks) * lai * x2 + fhot * (1 - np.exp(-alf * x2)) / alf
|
||
f2 = np.exp(y2)
|
||
if y2 != y1:
|
||
sumint += (f2 - f1) * (x2 - x1) / (y2 - y1)
|
||
x1, y1, f1 = x2, y2, f2
|
||
tsstoo = f1
|
||
|
||
rsos = w * lai * sumint
|
||
rso = rsos + rsod
|
||
|
||
# Canopy–soil interaction
|
||
dn = 1 - rsoil * rdd
|
||
rddt = rdd + tdd * rsoil * tdd / dn
|
||
rsdt = rsd + (tsd + tss) * rsoil * tdd / dn
|
||
rdot = rdo + tdd * rsoil * (tdo + too) / dn
|
||
rsodt = rsod + ((tss + tsd) * tdo + (tsd + tss * rsoil * rdd) * too) * rsoil / dn
|
||
rsost = rsos + tsstoo * rsoil
|
||
rsot = rsost + rsodt
|
||
|
||
return np.column_stack((wl, rdot, rsot, rddt, rsdt))
|