Skip to content

Commit 680271a

Browse files
committed
Implement 'regressed' RHS & G0 closure
1 parent b697470 commit 680271a

File tree

2 files changed

+76
-2
lines changed

2 files changed

+76
-2
lines changed

examples/L96m/L96m.jl

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ using Parameters # lets you have defaults for fields
1818
K::Int = 9
1919
J::Int = 8
2020
hx::Float64 = -0.8
21-
hy::Float64 = 1
22-
F::Float64 = 10
21+
hy::Float64 = 1.0
22+
F::Float64 = 10.0
2323
eps::Float64 = 2^(-7)
2424
G = nothing
2525
end
@@ -115,6 +115,42 @@ function balanced(rhs::Array{<:Real,1}, x::Array{<:Real,1}, p::L96m, t)
115115
return rhs
116116
end
117117

118+
function regressed(rhs::Array{<:Real,1}, x::Array{<:Real,1}, p::L96m, t)
119+
"""
120+
Compute slow-variable closed RHS of the Lorenz '96 Multiscale system;
121+
i.e. only slow variables with some closure instead of Yk.
122+
Closure is taken from p.G.
123+
Both `rhs` and `x` are vectors of size p.K.
124+
125+
Input:
126+
- `x` : vector of size K
127+
- `p` : parameters
128+
- `t` : time (not used here since L96m is autonomous)
129+
130+
Output:
131+
- `rhs` : regressed RHS computed at `x`
132+
133+
"""
134+
135+
K = p.K
136+
137+
# three boundary cases
138+
rhs[1] = -x[K] * (x[K-1] - x[2]) - x[1]
139+
rhs[2] = -x[1] * (x[K] - x[3]) - x[2]
140+
rhs[K] = -x[K-1] * (x[K-2] - x[1]) - x[K]
141+
142+
# general case
143+
rhs[3:K-1] = -x[2:K-2] .* (x[1:K-3] - x[4:K]) - x[3:K-1]
144+
145+
# add forcing
146+
rhs .+= p.F
147+
148+
# add closure
149+
rhs .+= p.hx * p.G(x)
150+
151+
return rhs
152+
end
153+
118154
function compute_Yk(p::L96m, z::Array{<:Real,1})
119155
"""
120156
Reshape a vector of y_{j,k} into a matrix, then sum along one dim and divide
@@ -126,4 +162,22 @@ function compute_Yk(p::L96m, z::Array{<:Real,1})
126162
) / p.J
127163
end
128164

165+
function set_G0(p::L96m; slope = nothing)
166+
"""
167+
Set the closure `p.G` to a linear one with slope `slope`.
168+
If unspecified, slope is equal to `p.hy`.
169+
"""
170+
if (slope == nothing) || (!isa(slope, Real))
171+
slope = p.hy
172+
end
173+
p.G = x -> slope * x
174+
end
175+
176+
function set_G0(p::L96m, slope::Real)
177+
"""
178+
Wrapper for set_G0(p::L96m; slope = nothing).
179+
"""
180+
set_G0(p, slope = slope)
181+
end
182+
129183

examples/L96m/main.jl

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ const hx = -0.8
3737
# IC section ###################################################################
3838
################################################################################
3939
l96 = L96m(hx = hx, J = 8)
40+
set_G0(l96) # set the linear closure (essentially, as in balanced)
4041

4142
z00 = Array{Float64}(undef, l96.K + l96.K * l96.J)
4243

@@ -57,6 +58,8 @@ elapsed_jit = @elapsed begin
5758
DE.solve(pb_jit, SOLVER, reltol = reltol, abstol = abstol, dtmax = dtmax)
5859
pb_jit = DE.ODEProblem(balanced, z00[1:l96.K], (0.0, T_compile), l96)
5960
DE.solve(pb_jit, SOLVER, reltol = reltol, abstol = abstol, dtmax = dtmax)
61+
pb_jit = DE.ODEProblem(regressed, z00[1:l96.K], (0.0, T_compile), l96)
62+
DE.solve(pb_jit, SOLVER, reltol = reltol, abstol = abstol, dtmax = dtmax)
6063
end
6164
println(" " ^ (LPAD_INTEGER + 6),
6265
"\t\telapsed:", lpad(elapsed_jit, LPAD_FLOAT))
@@ -104,6 +107,20 @@ end
104107
println("steps:", lpad(length(sol_bal.t), LPAD_INTEGER),
105108
"\t\telapsed:", lpad(elapsed_bal, LPAD_FLOAT))
106109

110+
# regressed L96m integration
111+
print(rpad("(regressed)", RPAD))
112+
elapsed_reg = @elapsed begin
113+
pb_reg = DE.ODEProblem(regressed, z0[1:l96.K], (0.0, T), l96)
114+
sol_reg = DE.solve(pb_reg,
115+
SOLVER,
116+
reltol = reltol,
117+
abstol = abstol,
118+
dtmax = dtmax
119+
)
120+
end
121+
println("steps:", lpad(length(sol_reg.t), LPAD_INTEGER),
122+
"\t\telapsed:", lpad(elapsed_reg, LPAD_FLOAT))
123+
107124
################################################################################
108125
# plot section #################################################################
109126
################################################################################
@@ -115,6 +132,9 @@ plt.plot(sol_dns.t, sol_dns[l96.K + (k-1)*l96.J + j,:],
115132
# plot balanced
116133
plt.plot(sol_bal.t, sol_bal[k,:], label = "balanced")
117134

135+
# plot regressed
136+
plt.plot(sol_reg.t, sol_reg[k,:], label = "regressed")
137+
118138
plt.legend()
119139
plt.show()
120140

0 commit comments

Comments
 (0)