Skip to content

Commit

Permalink
Add BC treatment for explicit plus a test
Browse files Browse the repository at this point in the history
  • Loading branch information
ScottMacLachlan committed Nov 17, 2024
1 parent f1fdf62 commit 9e276dc
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 0 deletions.
13 changes: 13 additions & 0 deletions irksome/explicit_stepper.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,16 @@ def __init__(self, F, butcher_tableau, t, dt, u0, bcs=None,
F, butcher_tableau, t, dt, u0, bcs=bcs,
solver_parameters=solver_parameters, appctx=appctx,
nullspace=None)

# DAE treatment of the boundary conditions in this case says that
# we should impose the BCs so that they are satisfied for the next
# stage for all but that last stage, and that they are satisfied
# for the next timestep for the last stage.
def update_bc_constants(self, AAb, CCone, i, a_vals, d_val, c):
ns = AAb.shape[1]
for j in range(i):
a_vals[j].assign(AAb[i+1, j])
for j in range(i, ns):
a_vals[j].assign(0)
d_val.assign(AAb[i+1, i])
c.assign(CCone[i+1])
69 changes: 69 additions & 0 deletions tests/test_explicit.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
from math import isclose

import pytest
from firedrake import *
from irksome import PEPRK, Dt, MeshConstant, TimeStepper
from ufl.algorithms.ad import expand_derivatives

peprks = [PEPRK(*x) for x in ((4, 2, 5), (5, 2, 6))]


@pytest.mark.parametrize("butcher_tableau", peprks)
def test_1d_heat_dirichletbc(butcher_tableau):
# Boundary values
u_0 = Constant(2.0)
u_1 = Constant(3.0)

N = 10
x0 = 0.0
x1 = 10.0
msh = IntervalMesh(N, x1)
V = FunctionSpace(msh, "CG", 1)
MC = MeshConstant(msh)
dt = MC.Constant(1.0 / N)
t = MC.Constant(0.0)
(x,) = SpatialCoordinate(msh)

# Method of manufactured solutions copied from Heat equation demo.
S = Constant(2.0)
C = Constant(1000.0)
B = (x - Constant(x0)) * (x - Constant(x1)) / C
R = (x * x) ** 0.5
# Note end linear contribution
uexact = (
B * atan(t) * (pi / 2.0 - atan(S * (R - t)))
+ u_0
+ ((x - x0) / x1) * (u_1 - u_0)
)
rhs = expand_derivatives(diff(uexact, t)) - div(grad(uexact))
u = Function(V)
u.interpolate(uexact)
v = TestFunction(V)
F = (
inner(Dt(u), v) * dx
+ inner(grad(u), grad(v)) * dx
- inner(rhs, v) * dx
)
bc = [
DirichletBC(V, u_1, 2),
DirichletBC(V, u_0, 1),
]

luparams = {"mat_type": "aij", "ksp_type": "preonly", "pc_type": "lu"}

stepper = TimeStepper(
F, butcher_tableau, t, dt, u, bcs=bc,
solver_parameters=luparams,
stage_type="explicit"
)

t_end = 2.0
while float(t) < t_end:
if float(t) + float(dt) > t_end:
dt.assign(t_end - float(t))
stepper.advance()
t.assign(float(t) + float(dt))
# Check solution and boundary values
assert errornorm(uexact, u) / norm(uexact) < 10.0 ** -3
assert isclose(u.at(x0), u_0)
assert isclose(u.at(x1), u_1)

0 comments on commit 9e276dc

Please sign in to comment.