Skip to content

Commit 3661d3d

Browse files
committed
add tridiagonal_solver
1 parent 9a08e8d commit 3661d3d

2 files changed

Lines changed: 75 additions & 0 deletions

File tree

src/ModelParams.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ include("Retention_van_Genuchten.jl")
4848
include("Retention_ParamTable.jl")
4949
include("Retention_PTF.jl")
5050

51+
include("tridiagonal_solver.jl")
5152

5253
export bounds, units, @bounds, @units
5354

src/tridiagonal_solver.jl

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
"""
2+
tridiagonal_solver(a, b, c, d)
3+
4+
Tridiagonal solver
5+
6+
# Description
7+
8+
Converted into a R code from the original code of Gordon Bonan: Bonan, G.
9+
(2019). Climate Change and Terrestrial Ecosystem Modeling. Cambridge:
10+
Cambridge University Press. doi:10.1017/9781107339217
11+
12+
Solve for U given the set of equations R * U = D, where U is a vector
13+
of length N, D is a vector of length N, and R is an N x N tridiagonal
14+
matrix defined by the vectors A, B, C each of length N. A(1) and
15+
C(N) are undefined and are not referenced.
16+
17+
|B(1) C(1) ... ... ... |
18+
|A(2) B(2) C(2) ... ... |
19+
R = | A(3) B(3) C(3) ... |
20+
| ... A(N-1) B(N-1) C(N-1)|
21+
| ... ... A(N) B(N) |
22+
23+
The system of equations is written as:
24+
25+
A_i * U_i-1 + B_i * U_i + C_i * U_i+1 = D_i
26+
27+
for i = 1 to N. The solution is found by rewriting the
28+
equations so that:
29+
30+
U_i = F_i - E_i * U_i+1
31+
32+
# Return
33+
- `Solution: U`
34+
35+
# Example
36+
```julia
37+
tridiagonal_solver!(a, b, c, d, e, f, u; ibeg)
38+
```
39+
"""
40+
function tridiagonal_solver!(a::V, b::V, c::V, d::V, e::V, f::V, u::V;
41+
ibeg::Int=1, N::Int=length(a)) where {T<:Real,V<:AbstractVector{T}}
42+
43+
# e = fill(NaN, N - 1)
44+
e[ibeg] = c[ibeg] / b[ibeg]
45+
@inbounds for i in ibeg+1:(N-1)
46+
e[i] = c[i] / (b[i] - a[i] * e[i-1])
47+
end
48+
49+
# f = fill(NaN, N)
50+
f[ibeg] = d[ibeg] / b[ibeg]
51+
@inbounds for i in ibeg+1:(N)
52+
f[i] = (d[i] - a[i] * f[i-1]) / (b[i] - a[i] * e[i-1])
53+
end
54+
55+
# u = fill(NaN, N)
56+
u[N] = f[N]
57+
@inbounds for i in N-1:-1:ibeg
58+
u[i] = f[i] - e[i] * u[i+1]
59+
end
60+
return u
61+
end
62+
63+
function tridiagonal_solver(a::V, b::V, c::V, d::V;
64+
ibeg::Int=1, N::Int=length(a)) where {T<:Real,V<:AbstractVector{T}}
65+
66+
e = fill(NaN, N - 1)
67+
f = fill(NaN, N)
68+
u = fill(NaN, N)
69+
tridiagonal_solver!(a, b, c, d, e, f, u; ibeg, N)
70+
return u
71+
end
72+
73+
74+
export tridiagonal_solver, tridiagonal_solver!

0 commit comments

Comments
 (0)