Skip to content

Commit 5441d06

Browse files
committed
TL: added imex stability scripts for thomas
1 parent 4039b1e commit 5441d06

File tree

3 files changed

+174
-0
lines changed

3 files changed

+174
-0
lines changed

qmat/playgrounds/tibo/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,6 @@
22
- :class:`orthogonalPolynomials` : generate orthogonal polynomial values from any distribution.
33
- :class:`lorenz` : application example of the generic solvers to solve the Lorenz equations.
44
- :class:`imex` : starting development for the IMEX generic solvers.
5+
- :class:`imexStabilityRK` : investigating IMEX stability for RK methods
6+
- :class:`imexStabilitySDC` : investigating IMEX stability for SDC methods
57
"""
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
#!/usr/bin/env python3
2+
# -*- coding: utf-8 -*-
3+
"""
4+
Script investigating IMEX stability for RK methods
5+
"""
6+
import numpy as np
7+
import scipy.optimize as sco
8+
import matplotlib.pyplot as plt
9+
10+
from qmat.qcoeff.butcher import RK_SCHEMES
11+
from qmat.solvers.dahlquist import DahlquistIMEX
12+
13+
14+
# Script parameters
15+
implScheme = "ARK443ESDIRK"
16+
explScheme = "ARK443ERK"
17+
stepUpdate = False
18+
19+
20+
# Script execution
21+
lamE = np.linspace(0, 6, num=501)
22+
ratio = np.logspace(-3, 2, num=301)
23+
zI = -ratio[None, :]*lamE[:, None]
24+
zE = 1j*lamE[:, None]
25+
26+
problem = DahlquistIMEX(zI, zE)
27+
28+
schemeI = RK_SCHEMES[implScheme]()
29+
schemeE = RK_SCHEMES[explScheme]()
30+
31+
QI = schemeI.Q
32+
wI = schemeI.weights if stepUpdate else None
33+
QE = schemeE.Q
34+
wE = schemeE.weights if stepUpdate else None
35+
36+
uNum = problem.solve(QI, wI, QE, wE)
37+
38+
u1 = uNum[-1]
39+
stab = np.abs(u1)
40+
stab = np.clip(stab, 0, 1.2) # clip to ignore unstable area
41+
error = np.abs(u1 - np.exp(zI+zE))
42+
43+
44+
plt.figure("imex stability")
45+
plt.clf()
46+
47+
coords = (ratio, lamE)
48+
plt.contourf(*coords, stab, levels = [0, 0.2, 0.4, 0.6, 0.8, 1, 1.2])
49+
plt.colorbar()
50+
plt.contour(*coords, stab, levels=[1], colors="black")
51+
plt.contour(*coords, error, levels=[1], colors="red", linestyles=":")
52+
plt.contour(*coords, error, levels=[1e-1], colors="orange", linestyles="-.")
53+
plt.contour(*coords, error, levels=[1e-2], colors="gray", linestyles="--")
54+
plt.grid(True)
55+
plt.xscale('log')
56+
plt.ylabel(r"$\lambda_E \Delta t$")
57+
plt.xlabel(r"advection $\quad\leftarrow\quad\frac{-\lambda_I}{\lambda_E}\quad\rightarrow\quad$ diffusion", fontsize=20)
58+
plt.tight_layout()
59+
60+
61+
def imStab(x):
62+
return np.abs(DahlquistIMEX([0], [x*1j]).solve(QI, wI, QE, wE)[-1]) - 1
63+
64+
try:
65+
sol = sco.bisect(imStab, 1e-1, 1e2, xtol=1e-16)
66+
print(f"CFL max [RK] : {sol}")
67+
except:
68+
pass
69+
70+
plt.figure("stability on imaginary axis")
71+
plt.clf()
72+
plt.grid(True)
73+
x = np.linspace(0, 6, num=501)
74+
plt.plot(x, [imStab(s)[0] for s in x], label="RK")
75+
plt.ylim(-1, 0.5)
76+
plt.ylabel("over-amplification")
77+
plt.xlabel(r"$\lambda_E \Delta t$")
78+
plt.legend()
79+
plt.tight_layout()
80+
81+
plt.show()
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
#!/usr/bin/env python3
2+
# -*- coding: utf-8 -*-
3+
"""
4+
Script investigating IMEX stability for SDC methods
5+
"""
6+
import numpy as np
7+
import scipy.optimize as sco
8+
import matplotlib.pyplot as plt
9+
10+
from qmat.qcoeff.collocation import Collocation
11+
from qmat.qdelta import QDELTA_GENERATORS
12+
13+
from qmat.solvers.dahlquist import DahlquistIMEX
14+
15+
16+
# Script parameters
17+
nNodes = 4
18+
nSweeps = 4
19+
stepUpdate = False
20+
implSweep = "MIN-SR-FLEX"
21+
explSweep = "PIC"
22+
23+
24+
# Script execution
25+
lamE = np.linspace(0, 6, num=501)
26+
ratio = np.logspace(-3, 2, num=301)
27+
zI = -ratio[None, :]*lamE[:, None]
28+
zE = 1j*lamE[:, None]
29+
30+
problem = DahlquistIMEX(zI, zE)
31+
32+
coll = Collocation(nNodes=nNodes, nodeType="LEGENDRE", quadType="RADAU-RIGHT")
33+
34+
genI = QDELTA_GENERATORS[implSweep](qGen=coll)
35+
genE = QDELTA_GENERATORS[explSweep](qGen=coll)
36+
37+
sweeps = [k+1 for k in range(nSweeps)]
38+
39+
uNum = problem.solveSDC(
40+
coll.Q, coll.weights if stepUpdate else None,
41+
genI.genCoeffs(k=sweeps), genE.genCoeffs(k=sweeps),
42+
nSweeps=nSweeps)
43+
44+
u1 = uNum[-1]
45+
stab = np.abs(u1)
46+
stab = np.clip(stab, 0, 1.2) # clip to ignore unstable area
47+
error = np.abs(u1 - np.exp(zI+zE))
48+
49+
50+
plt.figure("imex stability")
51+
plt.clf()
52+
53+
coords = (ratio, lamE)
54+
plt.contourf(*coords, stab, levels = [0, 0.2, 0.4, 0.6, 0.8, 1, 1.2])
55+
plt.colorbar()
56+
plt.contour(*coords, stab, levels=[1], colors="black")
57+
plt.contour(*coords, error, levels=[1], colors="red", linestyles=":")
58+
plt.contour(*coords, error, levels=[1e-1], colors="orange", linestyles="-.")
59+
plt.contour(*coords, error, levels=[1e-2], colors="gray", linestyles="--")
60+
plt.grid(True)
61+
plt.xscale('log')
62+
plt.ylabel(r"$\lambda_E \Delta t$")
63+
plt.xlabel(r"advection $\quad\leftarrow\quad\frac{-\lambda_I}{\lambda_E}\quad\rightarrow\quad$ diffusion", fontsize=20)
64+
plt.tight_layout()
65+
66+
67+
def imStab(x):
68+
uSDC = DahlquistIMEX([0], [x*1j]).solveSDC(
69+
coll.Q, coll.weights if stepUpdate else None,
70+
genI.genCoeffs(k=sweeps), genE.genCoeffs(k=sweeps),
71+
nSweeps=nSweeps)
72+
return np.abs(uSDC[-1]) - 1
73+
74+
try:
75+
sol = sco.bisect(imStab, 1e-1, 1e2, xtol=1e-16)
76+
print(f"CFL max [SDC] : {sol}")
77+
except:
78+
pass
79+
80+
plt.figure("stability on imaginary axis")
81+
plt.clf()
82+
plt.grid(True)
83+
x = np.linspace(0, 6, num=501)
84+
plt.plot(x, [imStab(s)[0] for s in x], label="RK")
85+
plt.ylim(-1, 0.5)
86+
plt.ylabel("over-amplification")
87+
plt.xlabel(r"$\lambda_E \Delta t$")
88+
plt.legend()
89+
plt.tight_layout()
90+
91+
plt.show()

0 commit comments

Comments
 (0)