Skip to content

Commit c35fe87

Browse files
MarcoArtianovchuravy
authored andcommitted
Add three-stage DIRK
1 parent 71d4f85 commit c35fe87

File tree

2 files changed

+85
-12
lines changed

2 files changed

+85
-12
lines changed

examples/trixi_dirk.jl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,9 @@ trixi_include(joinpath(examples_dir(), "tree_2d_dgsem", "elixir_advection_basic.
2727
sol = solve(
2828
ode,
2929
# Implicit.RKImplicitEuler();
30-
# Implicit.KS2();
31-
Implicit.Crouzeix();
30+
# Implicit.KS22();
31+
# Implicit.C23();
32+
Implicit.L33();
3233
dt = 1.0, # solve needs some value here but it will be overwritten by the stepsize_callback
3334
ode_default_options()..., callback = callbacks,
3435
# verbose=1,

libs/Theseus/src/Theseus.jl

Lines changed: 82 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -173,9 +173,9 @@ function (::RKImplicitEuler)(res, uₙ, Δt, f!, du, u, p, t, stages, stage, RK)
173173

174174
end
175175

176-
struct KS2 <: DIRK{2} end
177-
struct QZ2 <: DIRK{2} end
178-
struct Crouzeix <: DIRK{2} end
176+
struct KS22 <: DIRK{2} end
177+
struct QZ22 <: DIRK{2} end
178+
struct C23 <: DIRK{2} end
179179

180180
function (::DIRK{2})(res, uₙ, Δt, f!, du, u, p, t, stages, stage, RK)
181181
if stage == 1
@@ -190,6 +190,25 @@ function (::DIRK{2})(res, uₙ, Δt, f!, du, u, p, t, stages, stage, RK)
190190

191191
end
192192

193+
struct C34 <: DIRK{3} end
194+
struct L33 <: DIRK{3} end
195+
196+
function (::DIRK{3})(res, uₙ, Δt, f!, du, u, p, t, stages, stage, RK)
197+
if stage == 1
198+
f!(du, u, p, t + RK.c[stage] * Δt)
199+
return res .= u .- uₙ .- RK.a[stage, stage] * Δt .* du
200+
elseif stage == 2
201+
f!(du, u, p, t + RK.c[stage] * Δt)
202+
return res .= u .- uₙ .- RK.a[stage, 1] * Δt .* stages[1] - RK.a[stage,2] * Δt .* du
203+
elseif stage == 3
204+
f!(du, u, p, t + RK.c[stage] * Δt)
205+
return res .= u .- uₙ .- RK.a[stage, 1] * Δt .* stages[1] - RK.a[stage,2] * Δt .* stages[2] - RK.a[stage,3] * Δt .* du
206+
else
207+
@. u = uₙ + Δt * (RK.b[1] * stages[1] + RK.b[2] * stages[2] + RK.b[3] * stages[3])
208+
end
209+
210+
end
211+
193212
struct Rosenbrock <: Direct{3} end
194213

195214
function (::Rosenbrock)(res, uₙ, Δt, f!, du, u, p, t, stages, stage, workspace, M, RK)
@@ -272,7 +291,7 @@ function ImplicitEulerTableau()
272291
end
273292

274293
# Kraaijevanger and Spijker's two-stage Diagonally Implicit Runge–Kutta method:
275-
function KS2Tableau()
294+
function KS22Tableau()
276295
nstage = 2
277296
a = zeros(Float64, nstage, nstage)
278297
a[1,1] = 1/2
@@ -289,7 +308,7 @@ function KS2Tableau()
289308

290309
end
291310
# Qin and Zhang's two-stage, 2nd order, symplectic Diagonally Implicit Runge–Kutta method:
292-
function QZ2Tableau()
311+
function QZ22Tableau()
293312
nstage = 2
294313
a = zeros(Float64, nstage, nstage)
295314
a[1,1] = 1/4
@@ -306,7 +325,7 @@ function QZ2Tableau()
306325
end
307326

308327
# Crouzeix's two-stage, 3rd order Diagonally Implicit Runge–Kutta method
309-
function CrouzeixTableau()
328+
function C23Tableau()
310329
nstage = 2
311330
a = zeros(Float64, nstage, nstage)
312331
a[1,1] = 1/2 + sqrt(3)/6
@@ -321,7 +340,52 @@ function CrouzeixTableau()
321340
c[2] = 1/2 - sqrt(3)/6
322341
return DIRKButcher(a,b,c)
323342
end
343+
# Crouzeix's three-stage, 4th order Diagonally Implicit Runge–Kutta method:
344+
function C34Tableau()
345+
nstage = 3
346+
alpha = 2/sqrt(3)*cospi(1/18)
347+
a = zeros(Float64, nstage, nstage)
348+
a[1,1] = (1+alpha)/2
349+
a[2,1] = -alpha/2
350+
a[2,2] = a[1,1]
351+
a[3,1] = 1+ alpha
352+
a[3,2] = -(1+2*alpha)
353+
a[3,3] = (1+alpha)/2
354+
b = zeros(Float64, nstage)
355+
b[1] = 1/(6*alpha^2)
356+
b[2] = 1-1/(3*alpha^2)
357+
b[3] = 1/(6*alpha^2)
358+
359+
c = zeros(Float64, nstage)
360+
c[1] = a[1,1]
361+
c[2] = a[2,1] + a[2,2]
362+
c[3] = a[3,1] + a[3,2] + a[3,3]
363+
return DIRKButcher(a,b,c)
364+
end
324365

366+
# L-Stable third order, FSAL! It can be optmized, because of the FSAL.
367+
function L33Tableau()
368+
nstage = 3
369+
x = 0.4368665215
370+
alpha = 2/sqrt(3)*cospi(1/18)
371+
a = zeros(Float64, nstage, nstage)
372+
a[1,1] = x
373+
a[2,1] = (1-x)/2
374+
a[2,2] = x
375+
a[3,1] = -3*x^2/2 + 4*x - 1/4
376+
a[3,2] = 3*x^2/2 -5*x + 5/4
377+
a[3,3] = x
378+
b = zeros(Float64, nstage)
379+
b[1] = a[3,1]
380+
b[2] = a[3,2]
381+
b[3] = a[3,3]
382+
383+
c = zeros(Float64, nstage)
384+
c[1] = a[1,1]
385+
c[2] = a[2,1] + a[2,2]
386+
c[3] = a[3,1] + a[3,2] + a[3,3]
387+
return DIRKButcher(a,b,c)
388+
end
325389

326390
function RKTableau(alg::Direct)
327391
return RosenbrockTableau()
@@ -335,16 +399,24 @@ function RKTableau(alg::RKImplicitEuler)
335399
return ImplicitEulerTableau()
336400
end
337401

338-
function RKTableau(alg::KS2)
402+
function RKTableau(alg::KS22)
339403
return KS2Tableau()
340404
end
341405

342-
function RKTableau(alg::QZ2)
406+
function RKTableau(alg::QZ22)
343407
return QZ2Tableau()
344408
end
345409

346-
function RKTableau(alg::Crouzeix)
347-
return CrouzeixTableau()
410+
function RKTableau(alg::C23)
411+
return C23Tableau()
412+
end
413+
414+
function RKTableau(alg::C34)
415+
return C34Tableau()
416+
end
417+
418+
function RKTableau(alg::L33)
419+
return L33Tableau()
348420
end
349421

350422
function nonlinear_problem(alg::SimpleImplicitAlgorithm, f::F) where {F}

0 commit comments

Comments
 (0)