Skip to content

Commit 31eef9a

Browse files
committed
SM算法 ready to go
1 parent 2e0922d commit 31eef9a

9 files changed

Lines changed: 183 additions & 6 deletions

src/ModelParams.jl

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,10 @@ include("Kv_Profile.jl")
4141
include("Kv.jl")
4242
include("Model_SoilDiffEqs.jl")
4343
include("SoilColumn.jl")
44+
include("tridiagonal_solver.jl")
4445

45-
include("Retention.jl")
46-
include("Retention_Campbell.jl")
47-
include("Retention_van_Genuchten.jl")
48-
include("Retention_ParamTable.jl")
49-
include("Retention_PTF.jl")
46+
include("SoilMoisture/SoilMoisture.jl")
5047

51-
include("tridiagonal_solver.jl")
5248
include("soil_texture.jl")
5349

5450
include("Equilibrium.jl")
File renamed without changes.

src/SoilMoisture/SoilMoisture.jl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
include("Retention.jl")
2+
include("Retention_Campbell.jl")
3+
include("Retention_van_Genuchten.jl")
4+
include("Retention_ParamTable.jl")
5+
include("Retention_PTF.jl")
6+
7+
include("soil_moisture_Bonan.jl")
8+
include("soil_moisture_Bonan_Q0.jl")
9+
10+
11+
export soil_moisture!, soil_moisture_Q0!
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
function soil_moisture!(
2+
θ::V, ψ::V, θ_prev::V, ψ_prev::V, ∂θ∂ψ::V, K::V, K₊ₕ::V, tri::TriSolver{FT},
3+
ps::HydraulicProfile, sink::V, ψ0::FT;
4+
ibeg::Int, N::Int, Δz_cm::V, Δz₊ₕ_cm::V, dt::FT,
5+
ψ0_boundary::NamedTuple{(:i0, :dz0₊ₕ),Tuple{Int,FT}}, ψ0_location=:boundary,
6+
debug::Bool=true) where {FT<:Real,V<:AbstractVector{FT}}
7+
8+
(; u, a, b, c, d, e, f) = tri
9+
ψ_next = u
10+
dt = dt / 3600 # [s] -> [h]
11+
12+
for i in 1:N # backup
13+
θ_prev[i] = θ[i]
14+
ψ_prev[i] = ψ[i]
15+
end
16+
17+
# cal_ψ!(ψ, ps, θ; N, ibeg)
18+
# cal_K!(K, K₊ₕ, ps, θ; N, ibeg, Δz=Δz_cm)
19+
# cal_∂θ∂ψ!(∂θ∂ψ, ps, ψ; N, ibeg)
20+
cal_θKCap!(θ, K, K₊ₕ, ∂θ∂ψ, ps, ψ; N, ibeg, Δz=Δz_cm)
21+
22+
(; i0, dz0₊ₕ) = ψ0_boundary # TODO: improve this interface
23+
K0₊ₕ = (ψ0_location === :boundary || ibeg == 1) ? K[ibeg] : K₊ₕ[i0]
24+
25+
dt_half = 0.5 * dt
26+
# first round:
27+
@inbounds for i = ibeg:N
28+
if i == ibeg
29+
a[i] = 0.0
30+
c[i] = -K₊ₕ[i] / Δz₊ₕ_cm[i]
31+
b[i] = ∂θ∂ψ[i] * Δz_cm[i] / dt_half + K0₊ₕ / dz0₊ₕ - c[i]
32+
d[i] = ∂θ∂ψ[i] * Δz_cm[i] / dt_half * ψ[i] + K0₊ₕ / dz0₊ₕ * ψ0 + K0₊ₕ - K₊ₕ[i]
33+
elseif i < N
34+
a[i] = -K₊ₕ[i-1] / Δz₊ₕ_cm[i-1]
35+
c[i] = -K₊ₕ[i] / Δz₊ₕ_cm[i]
36+
b[i] = ∂θ∂ψ[i] * Δz_cm[i] / dt_half - a[i] - c[i]
37+
d[i] = ∂θ∂ψ[i] * Δz_cm[i] / dt_half * ψ[i] + K₊ₕ[i-1] - K₊ₕ[i]
38+
elseif i == N
39+
a[i] = -K₊ₕ[N-1] / Δz₊ₕ_cm[N-1]
40+
c[i] = 0.0
41+
b[i] = ∂θ∂ψ[i] * Δz_cm[i] / dt_half - a[i] - c[i]
42+
d[i] = ∂θ∂ψ[i] * Δz_cm[i] / dt_half * ψ[i] + K₊ₕ[N-1] - K[i]
43+
end
44+
d[i] -= sink[i]
45+
end
46+
tridiagonal_solver!(a, b, c, d, e, f, ψ_next; ibeg, N)
47+
48+
## update: θ, K and ∂θ∂ψ
49+
# cal_θ!(θ, ps, ψ_next; N, ibeg)
50+
# cal_K!(K, K₊ₕ, ps, θ; N, ibeg, Δz_cm)
51+
# cal_∂θ∂ψ!(∂θ∂ψ, ps, ψ_next; N, ibeg)
52+
cal_θKCap!(θ, K, K₊ₕ, ∂θ∂ψ, ps, ψ_next; N, ibeg, Δz=Δz_cm)
53+
K0₊ₕ = (ψ0_location === :boundary || ibeg == 1) ? K[ibeg] : K₊ₕ[i0]
54+
55+
## second round: in half step
56+
@inbounds for i = ibeg:N
57+
if i == ibeg
58+
a[i] = 0
59+
c[i] = -K₊ₕ[i] / (2 * Δz₊ₕ_cm[i])
60+
b[i] = ∂θ∂ψ[i] * Δz_cm[i] / dt - c[i] + K0₊ₕ / (2 * dz0₊ₕ)
61+
d[i] = ∂θ∂ψ[i] * Δz_cm[i] / dt * ψ[i] +
62+
K0₊ₕ / (2 * dz0₊ₕ) * (2ψ0 - ψ[i]) +
63+
c[i] * (ψ[i] - ψ[i+1]) + K0₊ₕ - K₊ₕ[i]
64+
elseif i < N
65+
a[i] = -K₊ₕ[i-1] / (2 * Δz₊ₕ_cm[i-1])
66+
c[i] = -K₊ₕ[i] / (2 * Δz₊ₕ_cm[i])
67+
b[i] = ∂θ∂ψ[i] * Δz_cm[i] / dt - a[i] - c[i]
68+
d[i] = ∂θ∂ψ[i] * Δz_cm[i] / dt * ψ[i] - a[i] * (ψ[i-1] - ψ[i]) +
69+
c[i] * (ψ[i] - ψ[i+1]) + K₊ₕ[i-1] - K₊ₕ[i]
70+
elseif i == N
71+
a[i] = -K₊ₕ[i-1] / (2 * Δz₊ₕ_cm[i-1])
72+
c[i] = 0
73+
b[i] = ∂θ∂ψ[i] * Δz_cm[i] / dt - a[i] - c[i]
74+
d[i] = ∂θ∂ψ[i] * Δz_cm[i] / dt * ψ[i] - a[i] * (ψ[i-1] - ψ[i]) + K₊ₕ[i-1] - K[i]
75+
end
76+
d[i] -= sink[i]
77+
end
78+
tridiagonal_solver!(a, b, c, d, e, f, ψ; ibeg, N)
79+
# cal_θ!(soil, ψ)
80+
81+
## Check water balance
82+
Q0 = -K0₊ₕ / (2 * dz0₊ₕ) * ((ψ0 - ψ_prev[ibeg]) + (ψ0 - ψ[ibeg])) - K0₊ₕ # 两个时刻的
83+
QN = -K[N]
84+
85+
= 0
86+
for i = 1:N
87+
+= (θ[i] - θ_prev[i]) * Δz_cm[i]
88+
end
89+
90+
err =- (QN - Q0) * dt
91+
debug && return Q0, QN, dθ, err
92+
return nothing
93+
end
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
function soil_moisture_Q0!(
2+
θ::V, ψ::V, θ_prev::V, ψ_prev::V, ∂θ∂ψ::V, K::V, K₊ₕ::V, tri::TriSolver{FT},
3+
ps::HydraulicProfile, sink::V, Q0::FT;
4+
ibeg::Int, N::Int, Δz_cm::V, Δz₊ₕ_cm::V, dt::FT) where {FT<:Real,V<:AbstractVector{FT}}
5+
6+
(; u, a, b, c, d, e, f) = tri
7+
ψ_next = u
8+
dt = dt / 3600 # [s] -> [h]
9+
10+
θ_prev[ibeg:N] .= θ[ibeg:N]
11+
ψ_prev[ibeg:N] .= ψ[ibeg:N]
12+
13+
cal_ψ!(ψ, ps, θ; N, ibeg)
14+
cal_K!(K, K₊ₕ, ps, θ; N, ibeg, Δz=Δz_cm)
15+
cal_∂θ∂ψ!(∂θ∂ψ, ps, ψ; N, ibeg)
16+
17+
@inbounds for i = ibeg:N
18+
if i == ibeg
19+
a[i] = 0
20+
c[i] = -K₊ₕ[i] / Δz₊ₕ_cm[i]
21+
b[i] = ∂θ∂ψ[i] * Δz_cm[i] / (0.5 * dt) - c[i]
22+
d[i] = ∂θ∂ψ[i] * Δz_cm[i] / (0.5 * dt) * ψ[i] - K₊ₕ[i] - Q0
23+
elseif i < N
24+
a[i] = -K₊ₕ[i-1] / Δz₊ₕ_cm[i-1]
25+
c[i] = -K₊ₕ[i] / Δz₊ₕ_cm[i]
26+
b[i] = ∂θ∂ψ[i] * Δz_cm[i] / (0.5 * dt) - a[i] - c[i]
27+
d[i] = ∂θ∂ψ[i] * Δz_cm[i] / (0.5 * dt) * ψ[i] + K₊ₕ[i-1] - K₊ₕ[i]
28+
elseif i == N
29+
a[i] = -K₊ₕ[N-1] / Δz₊ₕ_cm[N-1]
30+
c[i] = 0
31+
b[i] = ∂θ∂ψ[i] * Δz_cm[i] / (0.5 * dt) - a[i] - c[i]
32+
d[i] = ∂θ∂ψ[i] * Δz_cm[i] / (0.5 * dt) * ψ[i] + K₊ₕ[N-1] - K[i]
33+
end
34+
d[i] -= sink[i]
35+
end
36+
37+
tridiagonal_solver!(a, b, c, d, e, f, ψ_next; ibeg, N)
38+
39+
cal_θ!(θ, ps, ψ_next; N, ibeg)
40+
cal_K!(K, K₊ₕ, ps, θ; N, ibeg, Δz=Δz_cm)
41+
cal_∂θ∂ψ!(∂θ∂ψ, ps, ψ_next; N, ibeg)
42+
43+
@inbounds for i = ibeg:N
44+
if i == ibeg
45+
a[i] = 0
46+
c[i] = -K₊ₕ[i] / (2 * Δz₊ₕ_cm[i])
47+
b[i] = ∂θ∂ψ[i] * Δz_cm[i] / dt - c[i]
48+
d[i] = ∂θ∂ψ[i] * Δz_cm[i] / dt * ψ[i] - Q0 +
49+
c[i] * (ψ[i] - ψ[i+1]) - K₊ₕ[i]
50+
elseif i < N
51+
a[i] = -K₊ₕ[i-1] / (2 * Δz₊ₕ_cm[i-1])
52+
c[i] = -K₊ₕ[i] / (2 * Δz₊ₕ_cm[i])
53+
b[i] = ∂θ∂ψ[i] * Δz_cm[i] / dt - a[i] - c[i]
54+
d[i] = ∂θ∂ψ[i] * Δz_cm[i] / dt * ψ[i] - a[i] * (ψ[i-1] - ψ[i]) +
55+
c[i] * (ψ[i] - ψ[i+1]) + K₊ₕ[i-1] - K₊ₕ[i]
56+
else
57+
i == N
58+
a[i] = -K₊ₕ[i-1] / (2 * Δz₊ₕ_cm[i-1])
59+
c[i] = 0
60+
b[i] = ∂θ∂ψ[i] * Δz_cm[i] / dt - a[i] - c[i]
61+
d[i] = ∂θ∂ψ[i] * Δz_cm[i] / dt * ψ[i] - a[i] * (ψ[i-1] - ψ[i]) + K₊ₕ[i-1] - K[i]
62+
end
63+
d[i] -= sink[i]
64+
end
65+
66+
tridiagonal_solver!(a, b, c, d, e, f, ψ; ibeg, N)
67+
cal_θ!(θ, ps, ψ; N, ibeg)
68+
69+
QN = -K[N]
70+
= 0
71+
for i = ibeg:N
72+
+= (θ[i] - θ_prev[i]) * Δz_cm[i]
73+
end
74+
75+
err =- (QN - Q0) * dt
76+
Q0, QN, dθ, err
77+
end

0 commit comments

Comments
 (0)