Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add SSPRK schemes with higher stage count #606

Merged
merged 40 commits into from
Dec 19, 2024
Merged
Show file tree
Hide file tree
Changes from 36 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
7c6a607
empty commit to force CI
JHopeCollins Nov 4, 2024
9b2a545
set constant_jacobian for mass matrices in SIQN forcing solvers
JHopeCollins Nov 4, 2024
4257fcf
direct solver breaks RK test
JHopeCollins Nov 6, 2024
45077a4
tighter solver tolerance breaks RK test
JHopeCollins Nov 6, 2024
3df9ca9
Merge remote-tracking branch 'origin/main' into JHopeCollins/lvs_cons…
JHopeCollins Nov 6, 2024
6055d24
fixing the jacobian of linear time derivatives for explicit RK break…
JHopeCollins Nov 6, 2024
e41439c
fixing the preconditioner of linear time derivatives for explicit RK…
JHopeCollins Nov 6, 2024
fed1bdc
fieldsplitting ERK mass solves breaks LSWE test
JHopeCollins Nov 6, 2024
50dd3ba
fix the matrices in the linear solvers between reference state updates
JHopeCollins Nov 6, 2024
43c8831
remove fieldsplitting of ERK mass solves for now
JHopeCollins Nov 6, 2024
2849a2e
Using an iterative method for the mass solves in the SIQN forcing ter…
JHopeCollins Nov 6, 2024
43c4de8
fix the matrices in the diagnostics
JHopeCollins Nov 6, 2024
e2cc19e
fieldsplitting ERK mass solves for nonlinear time-derivatives
JHopeCollins Nov 6, 2024
c5fd4d8
all mass solver updates that break tests
JHopeCollins Nov 6, 2024
2e5158f
fieldsplit SIQN forcing mass solves
JHopeCollins Nov 7, 2024
ce977cc
Merge branch 'main' into JHopeCollins/lvs_constant_jacobian
JHopeCollins Dec 5, 2024
9411bf4
mass solves - only use CG on continuous fields (is the selection corr…
JHopeCollins Dec 5, 2024
bb21860
safe mass solves?
JHopeCollins Dec 6, 2024
b9620ea
the lightest of mass solves?
JHopeCollins Dec 6, 2024
050333b
Merge branch 'main' into JHopeCollins/lvs_constant_jacobian
JHopeCollins Dec 17, 2024
845c550
add a comment to explain why we invalidate the solver jacobians when …
JHopeCollins Dec 18, 2024
0bd0d7d
Merge remote-tracking branch 'origin' into JHopeCollins/lvs_constant_…
JHopeCollins Dec 18, 2024
b6886ee
record information about function space continuity in Spaces
JHopeCollins Dec 18, 2024
2155a80
set some sensible default mass solve parameters
JHopeCollins Dec 18, 2024
1e56565
make update_reference_profiles an abstract method for LinearSolvers
JHopeCollins Dec 18, 2024
0f62d7e
Merge remote-tracking branch 'origin/main' into JHopeCollins/lvs_cons…
JHopeCollins Dec 18, 2024
f4dd05d
bugfix continuity check in mass_parameters and more detail in docstring
JHopeCollins Dec 18, 2024
32602c5
move is_cg to core.function_spaces
JHopeCollins Dec 18, 2024
c5eb881
set params in correct place
JHopeCollins Dec 18, 2024
3e20ce7
mass solve bugfix
JHopeCollins Dec 18, 2024
385d30a
construct explicit mass solve from correct function space
JHopeCollins Dec 18, 2024
bca9ebb
revert to simple monolithic mass solves for now
JHopeCollins Dec 18, 2024
cd7f412
Merge remote-tracking branch 'origin/main' into JHopeCollins/lvs_cons…
JHopeCollins Dec 18, 2024
6e9e2c0
updated KGOs
JHopeCollins Dec 18, 2024
333f17b
add 4 and 5 stage SSPRK3 schemes
JHopeCollins Dec 18, 2024
4b9f7d4
Merge remote-tracking branch 'origin/main' into JHopeCollins/more_ssp…
JHopeCollins Dec 18, 2024
6b8b2a0
ssprk3 docstring for 5 stage
JHopeCollins Dec 18, 2024
43bbdad
more ssprk schemes
JHopeCollins Dec 18, 2024
d806fb5
Merge branch 'main' into JHopeCollins/more_ssprk_schemes
tommbendall Dec 18, 2024
ca02fee
Merge branch 'main' into JHopeCollins/more_ssprk_schemes
tommbendall Dec 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 49 additions & 8 deletions gusto/time_discretisation/explicit_runge_kutta.py
Original file line number Diff line number Diff line change
Expand Up @@ -532,19 +532,37 @@ def __init__(

class SSPRK3(ExplicitRungeKutta):
u"""
Implements the 3-stage Strong-Stability-Preserving Runge-Kutta method
for solving ∂y/∂t = F(y). It can be written as: \n
Implements 3rd order Strong-Stability-Preserving Runge-Kutta methods
for solving ∂y/∂t = F(y). \n

The 3-stage method can be written as: \n

k0 = F[y^n] \n
k1 = F[y^n + dt*k1] \n
k2 = F[y^n + (1/4)*dt*(k0+k1)] \n
y^(n+1) = y^n + (1/6)*dt*(k0 + k1 + 4*k2) \n

The 4-stage method can be written as: \n

k0 = F[y^n] \n
k1 = F[y^n + (1/2)*dt*k1] \n
k2 = F[y^n + (1/2)*dt*(k0+k1)] \n
k3 = F[y^n + (1/6)*dt*(k0+k1+k2)] \n
y^(n+1) = y^n + (1/6)*dt*(k0 + k1 + k2 + 3*k3) \n

The 5-stage method can be written as: \n

k0 = F[y^n] \n
k1 = F[y^n + (1/2)*dt*k1] \n
JHopeCollins marked this conversation as resolved.
Show resolved Hide resolved
k2 = F[y^n + (1/2)*dt*(k0+k1)] \n
k3 = F[y^n + (1/6)*dt*(k0+k1+k2)] \n
y^(n+1) = y^n + (1/6)*dt*(k0 + k1 + k2 + 3*k3) \n
"""
def __init__(
self, domain, field_name=None, subcycling_options=None,
rk_formulation=RungeKuttaFormulation.increment,
solver_parameters=None, limiter=None, options=None,
augmentation=None
augmentation=None, stages=3
):
"""
Args:
Expand All @@ -569,13 +587,36 @@ def __init__(
augmentation (:class:`Augmentation`): allows the equation solved in
this time discretisation to be augmented, for instances with
extra terms of another auxiliary variable. Defaults to None.
stages (int, optional): number of stages: (3, 4, 5). Defaults to 3.
"""

butcher_matrix = np.array([
[1., 0., 0.],
[1./4., 1./4., 0.],
[1./6., 1./6., 2./3.]
])
if stages == 3:
butcher_matrix = np.array([
[1., 0., 0.],
[1./4., 1./4., 0.],
[1./6., 1./6., 2./3.]
])
self.cfl_limit = 1
elif stages == 4:
butcher_matrix = np.array([
[1./2., 0., 0., 0.],
[1./2., 1./2., 0., 0.],
[1./6., 1./6., 1./6., 0.],
[1./6., 1./6., 1./6., 1./2.]
])
self.cfl_limit = 2
elif stages == 5:
self.cfl_limit = 2.65062919294483
butcher_matrix = np.array([
[0.37726891511710, 0., 0., 0., 0.],
[0.37726891511710, 0.37726891511710, 0., 0., 0.],
[0.16352294089771, 0.16352294089771, 0.16352294089771, 0., 0.],
[0.14904059394856, 0.14831273384724, 0.14831273384724, 0.34217696850008, 0.],
[0.19707596384481, 0.11780316509765, 0.11709725193772, 0.27015874934251, 0.29786487010104]
])
else:
raise ValueError(f"{stages} stage 3rd order SSPRK not implemented")

super().__init__(domain, butcher_matrix, field_name=field_name,
subcycling_options=subcycling_options,
rk_formulation=rk_formulation,
Expand Down
25 changes: 20 additions & 5 deletions integration-tests/model/test_time_discretisation.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,12 @@ def run(timestepper, tmax, f_end):

@pytest.mark.parametrize(
"scheme", [
"ssprk3_increment", "TrapeziumRule", "ImplicitMidpoint", "QinZhang",
"ssprk3_increment_3", "ssprk3_predictor_3", "ssprk3_linear_3",
"ssprk3_increment_4", "ssprk3_predictor_4", "ssprk3_linear_4",
"ssprk3_increment_5", "ssprk3_predictor_5", "ssprk3_linear_5",
"TrapeziumRule", "ImplicitMidpoint", "QinZhang",
"RK4", "Heun", "BDF2", "TR_BDF2", "AdamsBashforth", "Leapfrog",
"AdamsMoulton", "AdamsMoulton", "ssprk3_predictor", "ssprk3_linear"
"AdamsMoulton", "AdamsMoulton"
]
)
def test_time_discretisation(tmpdir, scheme, tracer_setup):
Expand All @@ -30,12 +33,24 @@ def test_time_discretisation(tmpdir, scheme, tracer_setup):
V = domain.spaces("DG")
eqn = AdvectionEquation(domain, V, "f")

if scheme == "ssprk3_increment":
if scheme == "ssprk3_increment_3":
transport_scheme = SSPRK3(domain, rk_formulation=RungeKuttaFormulation.increment)
elif scheme == "ssprk3_predictor":
elif scheme == "ssprk3_predictor_3":
transport_scheme = SSPRK3(domain, rk_formulation=RungeKuttaFormulation.predictor)
elif scheme == "ssprk3_linear":
elif scheme == "ssprk3_linear_3":
transport_scheme = SSPRK3(domain, rk_formulation=RungeKuttaFormulation.linear)
if scheme == "ssprk3_increment_4":
transport_scheme = SSPRK3(domain, rk_formulation=RungeKuttaFormulation.increment, stages=4)
elif scheme == "ssprk3_predictor_4":
transport_scheme = SSPRK3(domain, rk_formulation=RungeKuttaFormulation.predictor, stages=4)
elif scheme == "ssprk3_linear_4":
transport_scheme = SSPRK3(domain, rk_formulation=RungeKuttaFormulation.linear, stages=4)
if scheme == "ssprk3_increment_5":
transport_scheme = SSPRK3(domain, rk_formulation=RungeKuttaFormulation.increment, stages=5)
elif scheme == "ssprk3_predictor_5":
transport_scheme = SSPRK3(domain, rk_formulation=RungeKuttaFormulation.predictor, stages=5)
elif scheme == "ssprk3_linear_5":
transport_scheme = SSPRK3(domain, rk_formulation=RungeKuttaFormulation.linear, stages=5)
elif scheme == "TrapeziumRule":
transport_scheme = TrapeziumRule(domain)
elif scheme == "ImplicitMidpoint":
Expand Down
Loading