Simple transient diffusion case#
This is a simple transient MMS example. We will only consider diffusion of hydrogen in a unit square domain \(\Omega\) at steady state with an homogeneous diffusion coefficient \(D\). Moreover, a Dirichlet boundary condition will be assumed on the boundaries \(\partial \Omega \).
The problem is therefore:
The exact solution for mobile concentration is:
Note
We use a manufactured solution that varies linearly with time (\(t^1\)), as the backward Euler scheme provides an exact solution in this case.
Injecting (6) in (5), we obtain the expressions of \(S\), \(c_0\), and \(c_\mathrm{initial}\):
We can then run a FESTIM model with these values and compare the numerical solution with \(c_\mathrm{exact}\).
FESTIM code#
Show code cell content
import festim as F
import sympy as sp
import fenics as f
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
# Create and mark the mesh
nx = ny = 100
fenics_mesh = f.UnitSquareMesh(nx, ny)
volume_markers = f.MeshFunction("size_t", fenics_mesh, fenics_mesh.topology().dim())
volume_markers.set_all(1)
surface_markers = f.MeshFunction(
"size_t", fenics_mesh, fenics_mesh.topology().dim() - 1
)
surface_markers.set_all(0)
class Boundary(f.SubDomain):
def inside(self, x, on_boundary):
return on_boundary
boundary = Boundary()
boundary.mark(surface_markers, 1)
# Create the FESTIM model
my_model = F.Simulation()
my_model.mesh = F.Mesh(
fenics_mesh, volume_markers=volume_markers, surface_markers=surface_markers
)
# Variational formulation
exact_solution = 1 + 2 * F.x**2 + 3 * F.t * F.y**2 + 2 * F.t # exact solution
exact_solution_copy = exact_solution.subs(F.x, F.x)
D = 2
my_model.sources = [
F.Source(2 + 3 * F.y**2 - (4 + 6 * F.t) * D, volume=1, field="solute"),
]
my_model.boundary_conditions = [
F.DirichletBC(surfaces=[1], value=exact_solution, field="solute"),
]
my_model.materials = F.Material(id=1, D_0=D, E_D=0)
my_model.T = F.Temperature(500) # ignored in this problem
xdmf_file_name = "simple_transient_mobile.xdmf"
my_model.exports = [
F.XDMFExport(field="solute", filename=xdmf_file_name, checkpoint=True)
]
final_time = 17
slices = 4
slice_size = final_time / slices
milestones = list(np.linspace(slice_size, final_time, slices))
my_model.dt = F.Stepsize(initial_value=1, milestones=milestones)
my_model.settings = F.Settings(
absolute_tolerance=1e-10,
relative_tolerance=1e-10,
final_time=final_time,
)
my_model.initialise()
my_model.run()
Defining initial values
Defining variational problem
Defining source terms
Defining boundary conditions
Time stepping...
Calling FFC just-in-time (JIT) compiler, this may take some time.
Calling FFC just-in-time (JIT) compiler, this may take some time.
5.9 % 1.0e+00 s Elapsed time so far: 2.1 s
11.8 % 2.0e+00 s Elapsed time so far: 2.5 s
17.6 % 3.0e+00 s Elapsed time so far: 2.8 s
23.5 % 4.0e+00 s Elapsed time so far: 3.2 s
25.0 % 4.2e+00 s Elapsed time so far: 3.4 s
26.5 % 4.5e+00 s Elapsed time so far: 3.7 s
27.9 % 4.8e+00 s Elapsed time so far: 4.1 s
29.4 % 5.0e+00 s Elapsed time so far: 4.5 s
30.9 % 5.2e+00 s Elapsed time so far: 4.8 s
32.4 % 5.5e+00 s Elapsed time so far: 5.2 s
33.8 % 5.8e+00 s Elapsed time so far: 5.4 s
35.3 % 6.0e+00 s Elapsed time so far: 5.8 s
36.8 % 6.2e+00 s Elapsed time so far: 6.1 s
38.2 % 6.5e+00 s Elapsed time so far: 6.5 s
39.7 % 6.8e+00 s Elapsed time so far: 6.8 s
41.2 % 7.0e+00 s Elapsed time so far: 7.2 s
42.6 % 7.2e+00 s Elapsed time so far: 7.4 s
44.1 % 7.5e+00 s Elapsed time so far: 7.8 s
45.6 % 7.8e+00 s Elapsed time so far: 8.1 s
47.1 % 8.0e+00 s Elapsed time so far: 8.5 s
48.5 % 8.2e+00 s Elapsed time so far: 8.8 s
50.0 % 8.5e+00 s Elapsed time so far: 9.2 s
51.5 % 8.8e+00 s Elapsed time so far: 9.4 s
52.9 % 9.0e+00 s Elapsed time so far: 9.7 s
54.4 % 9.2e+00 s Elapsed time so far: 10.1 s
55.9 % 9.5e+00 s Elapsed time so far: 10.4 s
57.4 % 9.8e+00 s Elapsed time so far: 10.8 s
58.8 % 1.0e+01 s Elapsed time so far: 11.1 s
60.3 % 1.0e+01 s Elapsed time so far: 11.4 s
61.8 % 1.0e+01 s Elapsed time so far: 11.8 s
63.2 % 1.1e+01 s Elapsed time so far: 12.1 s
64.7 % 1.1e+01 s Elapsed time so far: 12.5 s
66.2 % 1.1e+01 s Elapsed time so far: 12.8 s
67.7 % 1.2e+01 s Elapsed time so far: 13.2 s
69.1 % 1.2e+01 s Elapsed time so far: 13.4 s
70.6 % 1.2e+01 s Elapsed time so far: 13.7 s
72.1 % 1.2e+01 s Elapsed time so far: 14.0 s
73.5 % 1.2e+01 s Elapsed time so far: 14.4 s
75.0 % 1.3e+01 s Elapsed time so far: 14.7 s
76.5 % 1.3e+01 s Elapsed time so far: 15.1 s
77.9 % 1.3e+01 s Elapsed time so far: 15.4 s
79.4 % 1.4e+01 s Elapsed time so far: 15.8 s
80.9 % 1.4e+01 s Elapsed time so far: 16.1 s
82.3 % 1.4e+01 s Elapsed time so far: 16.5 s
83.8 % 1.4e+01 s Elapsed time so far: 16.8 s
85.3 % 1.4e+01 s Elapsed time so far: 17.2 s
86.8 % 1.5e+01 s Elapsed time so far: 17.4 s
88.2 % 1.5e+01 s Elapsed time so far: 17.8 s
89.7 % 1.5e+01 s Elapsed time so far: 18.2 s
91.2 % 1.6e+01 s Elapsed time so far: 18.5 s
92.7 % 1.6e+01 s Elapsed time so far: 18.9 s
94.1 % 1.6e+01 s Elapsed time so far: 19.2 s
95.6 % 1.6e+01 s Elapsed time so far: 19.5 s
97.1 % 1.6e+01 s Elapsed time so far: 19.9 s
98.5 % 1.7e+01 s Elapsed time so far: 20.2 s
100.0 % 1.7e+01 s Elapsed time so far: 20.6 s
Comparison with exact solution#
Show code cell source
from fenics import XDMFFile, FunctionSpace, Function, plot
def load_xdmf(mesh, filename, field, element="CG", counter=-1):
"""Loads a XDMF file and store its content to a fenics.Function
Args:
mesh (fenics.mesh): the mesh of the function
filename (str): the XDMF filename
field (str): the name of the field in the XDMF file
element (str, optional): Finite element of the function.
Defaults to "CG".
counter (int, optional): timestep in the file, -1 is the
last timestep. Defaults to -1.
Returns:
fenics.Function: the content of the XDMF file as a Function
"""
V = FunctionSpace(mesh, element, 1)
u = Function(V)
XDMFFile(filename).read_checkpoint(u, field, counter)
return u
fig, axs = plt.subplots(
slices, 3, figsize=(slices * 2.3, slices * 2.5 + 1)
) # tweak figsize if needed
fig.tight_layout()
def compute_arc_length(xs, ys):
"""Computes the arc length of x,y points based
on x and y arrays
"""
points = np.vstack((xs, ys)).T
distance = np.linalg.norm(points[1:] - points[:-1], axis=1)
arc_length = np.insert(np.cumsum(distance), 0, [0.0])
return arc_length
def exists_close(x, list):
return any(np.isclose(x, t) for t in list)
xdmf_times = F.extract_xdmf_times(xdmf_file_name)
counters = [i for (i, time) in enumerate(xdmf_times) if exists_close(time, milestones)]
for i, counter in enumerate(counters):
time = xdmf_times[counter]
c_exact = f.Expression(
sp.printing.ccode(exact_solution_copy.subs(F.t, time)), degree=4
)
c_exact = f.project(c_exact, f.FunctionSpace(my_model.mesh.mesh, "CG", 1))
computed_solution = load_xdmf(
fenics_mesh, xdmf_file_name, "mobile_concentration", "CG", counter
)
E = f.errornorm(computed_solution, c_exact, "L2")
# plot exact solution and computed solution
plt.sca(axs[i, 0])
if i == 0:
plt.title(f"Exact")
plt.annotate(
f"t={time}s",
xy=(0.5, 1),
xytext=(-axs[i, 0].yaxis.labelpad - 3, 0),
xycoords=axs[i, 0].yaxis.label,
textcoords="offset points",
size="large",
ha="right",
va="center",
)
CS1 = f.plot(c_exact, cmap="inferno")
plt.sca(axs[i, 1])
if i == 0:
plt.title(f"Computed")
CS2 = f.plot(computed_solution, cmap="inferno")
plt.colorbar(CS1, ax=[axs[i, 0]], shrink=0.8)
plt.colorbar(CS2, ax=[axs[i, 1]], shrink=0.8)
axs[i, 0].sharey(axs[i, 1])
plt.setp(axs[i, 1].get_yticklabels(), visible=False)
for CS in [CS1, CS2]:
CS.set_edgecolor("face")
# define the profiles
profiles = [
{"start": (0.0, 0.0), "end": (1.0, 1.0)},
{"start": (0.2, 0.8), "end": (0.7, 0.2)},
{"start": (0.2, 0.6), "end": (0.8, 0.8)},
]
# plot the profiles on the right subplot
for profile in profiles:
start_x, start_y = profile["start"]
end_x, end_y = profile["end"]
plt.sca(axs[i, 1])
(l,) = plt.plot([start_x, end_x], [start_y, end_y])
plt.sca(axs[i, 2])
points_x_exact = np.linspace(start_x, end_x, num=30)
points_y_exact = np.linspace(start_y, end_y, num=30)
arc_length_exact = compute_arc_length(points_x_exact, points_y_exact)
u_values = [c_exact(x, y) for x, y in zip(points_x_exact, points_y_exact)]
points_x = np.linspace(start_x, end_x, num=100)
points_y = np.linspace(start_y, end_y, num=100)
arc_lengths = sorted(compute_arc_length(points_x, points_y))
computed_values = [computed_solution(x, y) for x, y in zip(points_x, points_y)]
(exact_line,) = plt.plot(
arc_length_exact,
u_values,
color=l.get_color(),
marker="o",
linestyle="None",
alpha=0.3,
)
(computed_line,) = plt.plot(arc_lengths, computed_values, color=l.get_color())
plt.sca(axs[i, 2])
plt.xlabel("Arc length")
if i == 0:
legend_marker = mpl.lines.Line2D(
[],
[],
color="black",
marker=exact_line.get_marker(),
linestyle="None",
label="Exact",
)
legend_line = mpl.lines.Line2D([], [], color="black", label="Computed")
plt.legend(
[legend_marker, legend_line],
[legend_marker.get_label(), legend_line.get_label()],
)
plt.grid(alpha=0.3)
plt.gca().spines[["right", "top"]].set_visible(False)
plt.show()
Compute convergence rates#
It is also possible to compute how the numerical error decreases as we increase the number of cells. By iteratively refining the mesh, we find that the error exhibits a second order convergence rate. This is expected for this particular problem as first order finite elements are used.
Show code cell content
def make_unit_square_mesh(n):
"""
Makes a festim Mesh with sides n x n for a total of n^2 cells.
Sets surface markers on the boundary to 1, otherwise 0.
"""
fenics_mesh = f.UnitSquareMesh(n, n)
volume_markers = f.MeshFunction("size_t", fenics_mesh, fenics_mesh.topology().dim())
volume_markers.set_all(1)
surface_markers = f.MeshFunction(
"size_t", fenics_mesh, fenics_mesh.topology().dim() - 1
)
surface_markers.set_all(0)
class Boundary(f.SubDomain):
def inside(self, x, on_boundary):
return on_boundary
boundary = Boundary()
boundary.mark(surface_markers, 1)
return F.Mesh(fenics_mesh, volume_markers, surface_markers)
errors = []
ns = [5, 10, 20, 30, 50, 100, 150]
for n in ns:
my_model.mesh = make_unit_square_mesh(n)
my_model.initialise()
my_model.run()
computed_solution = my_model.h_transport_problem.mobile.post_processing_solution
errors.append(f.errornorm(computed_solution, c_exact, "L2"))
Defining initial values
Defining variational problem
Defining source terms
Defining boundary conditions
Time stepping...
5.9 % 1.0e+00 s Elapsed time so far: 0.0 s
11.8 % 2.0e+00 s Elapsed time so far: 0.0 s
17.6 % 3.0e+00 s Elapsed time so far: 0.0 s
23.5 % 4.0e+00 s Elapsed time so far: 0.0 s
25.0 % 4.2e+00 s Elapsed time so far: 0.0 s
26.5 % 4.5e+00 s Elapsed time so far: 0.0 s
27.9 % 4.8e+00 s Elapsed time so far: 0.0 s
29.4 % 5.0e+00 s Elapsed time so far: 0.0 s
30.9 % 5.2e+00 s Elapsed time so far: 0.1 s
32.4 % 5.5e+00 s Elapsed time so far: 0.1 s
33.8 % 5.8e+00 s Elapsed time so far: 0.1 s
35.3 % 6.0e+00 s Elapsed time so far: 0.1 s
36.8 % 6.2e+00 s Elapsed time so far: 0.1 s
38.2 % 6.5e+00 s Elapsed time so far: 0.1 s
39.7 % 6.8e+00 s Elapsed time so far: 0.1 s
41.2 % 7.0e+00 s Elapsed time so far: 0.1 s
42.6 % 7.2e+00 s Elapsed time so far: 0.1 s
44.1 % 7.5e+00 s Elapsed time so far: 0.1 s
45.6 % 7.8e+00 s Elapsed time so far: 0.1 s
47.1 % 8.0e+00 s Elapsed time so far: 0.1 s
48.5 % 8.2e+00 s Elapsed time so far: 0.1 s
50.0 % 8.5e+00 s Elapsed time so far: 0.1 s
51.5 % 8.8e+00 s Elapsed time so far: 0.1 s
52.9 % 9.0e+00 s Elapsed time so far: 0.1 s
54.4 % 9.2e+00 s Elapsed time so far: 0.1 s
55.9 % 9.5e+00 s Elapsed time so far: 0.1 s
57.4 % 9.8e+00 s Elapsed time so far: 0.1 s
58.8 % 1.0e+01 s Elapsed time so far: 0.2 s
60.3 % 1.0e+01 s Elapsed time so far: 0.2 s
61.8 % 1.0e+01 s Elapsed time so far: 0.2 s
63.2 % 1.1e+01 s Elapsed time so far: 0.2 s
64.7 % 1.1e+01 s Elapsed time so far: 0.2 s
66.2 % 1.1e+01 s Elapsed time so far: 0.2 s
67.7 % 1.2e+01 s Elapsed time so far: 0.2 s
69.1 % 1.2e+01 s Elapsed time so far: 0.2 s
70.6 % 1.2e+01 s Elapsed time so far: 0.2 s
72.1 % 1.2e+01 s Elapsed time so far: 0.2 s
73.5 % 1.2e+01 s Elapsed time so far: 0.2 s
75.0 % 1.3e+01 s Elapsed time so far: 0.2 s
76.5 % 1.3e+01 s Elapsed time so far: 0.2 s
77.9 % 1.3e+01 s Elapsed time so far: 0.2 s
79.4 % 1.4e+01 s Elapsed time so far: 0.2 s
80.9 % 1.4e+01 s Elapsed time so far: 0.2 s
82.3 % 1.4e+01 s Elapsed time so far: 0.2 s
83.8 % 1.4e+01 s Elapsed time so far: 0.3 s
85.3 % 1.4e+01 s Elapsed time so far: 0.3 s
86.8 % 1.5e+01 s Elapsed time so far: 0.3 s
88.2 % 1.5e+01 s Elapsed time so far: 0.3 s
89.7 % 1.5e+01 s Elapsed time so far: 0.3 s
91.2 % 1.6e+01 s Elapsed time so far: 0.3 s
92.7 % 1.6e+01 s Elapsed time so far: 0.3 s
94.1 % 1.6e+01 s Elapsed time so far: 0.3 s
95.6 % 1.6e+01 s Elapsed time so far: 0.3 s
97.1 % 1.6e+01 s Elapsed time so far: 0.3 s
98.5 % 1.7e+01 s Elapsed time so far: 0.3 s
100.0 % 1.7e+01 s Elapsed time so far: 0.3 s
Defining initial values
Defining variational problem
Defining source terms
Defining boundary conditions
Time stepping...
5.9 % 1.0e+00 s Elapsed time so far: 0.0 s
11.8 % 2.0e+00 s Elapsed time so far: 0.0 s
17.6 % 3.0e+00 s Elapsed time so far: 0.0 s
23.5 % 4.0e+00 s Elapsed time so far: 0.0 s
25.0 % 4.2e+00 s Elapsed time so far: 0.0 s
26.5 % 4.5e+00 s Elapsed time so far: 0.1 s
27.9 % 4.8e+00 s Elapsed time so far: 0.1 s
29.4 % 5.0e+00 s Elapsed time so far: 0.1 s
30.9 % 5.2e+00 s Elapsed time so far: 0.1 s
32.4 % 5.5e+00 s Elapsed time so far: 0.1 s
33.8 % 5.8e+00 s Elapsed time so far: 0.1 s
35.3 % 6.0e+00 s Elapsed time so far: 0.1 s
36.8 % 6.2e+00 s Elapsed time so far: 0.1 s
38.2 % 6.5e+00 s Elapsed time so far: 0.1 s
39.7 % 6.8e+00 s Elapsed time so far: 0.1 s
41.2 % 7.0e+00 s Elapsed time so far: 0.1 s
42.6 % 7.2e+00 s Elapsed time so far: 0.1 s
44.1 % 7.5e+00 s Elapsed time so far: 0.1 s
45.6 % 7.8e+00 s Elapsed time so far: 0.1 s
47.1 % 8.0e+00 s Elapsed time so far: 0.1 s
48.5 % 8.2e+00 s Elapsed time so far: 0.1 s
50.0 % 8.5e+00 s Elapsed time so far: 0.1 s
51.5 % 8.8e+00 s Elapsed time so far: 0.2 s
52.9 % 9.0e+00 s Elapsed time so far: 0.2 s
54.4 % 9.2e+00 s Elapsed time so far: 0.2 s
55.9 % 9.5e+00 s Elapsed time so far: 0.2 s
57.4 % 9.8e+00 s Elapsed time so far: 0.2 s
58.8 % 1.0e+01 s Elapsed time so far: 0.2 s
60.3 % 1.0e+01 s Elapsed time so far: 0.2 s
61.8 % 1.0e+01 s Elapsed time so far: 0.2 s
63.2 % 1.1e+01 s Elapsed time so far: 0.2 s
64.7 % 1.1e+01 s Elapsed time so far: 0.2 s
66.2 % 1.1e+01 s Elapsed time so far: 0.2 s
67.7 % 1.2e+01 s Elapsed time so far: 0.2 s
69.1 % 1.2e+01 s Elapsed time so far: 0.2 s
70.6 % 1.2e+01 s Elapsed time so far: 0.2 s
72.1 % 1.2e+01 s Elapsed time so far: 0.2 s
73.5 % 1.2e+01 s Elapsed time so far: 0.2 s
75.0 % 1.3e+01 s Elapsed time so far: 0.2 s
76.5 % 1.3e+01 s Elapsed time so far: 0.2 s
77.9 % 1.3e+01 s Elapsed time so far: 0.3 s
79.4 % 1.4e+01 s Elapsed time so far: 0.3 s
80.9 % 1.4e+01 s Elapsed time so far: 0.3 s
82.3 % 1.4e+01 s Elapsed time so far: 0.3 s
83.8 % 1.4e+01 s Elapsed time so far: 0.3 s
85.3 % 1.4e+01 s Elapsed time so far: 0.3 s
86.8 % 1.5e+01 s Elapsed time so far: 0.3 s
88.2 % 1.5e+01 s Elapsed time so far: 0.3 s
89.7 % 1.5e+01 s Elapsed time so far: 0.3 s
91.2 % 1.6e+01 s Elapsed time so far: 0.3 s
92.7 % 1.6e+01 s Elapsed time so far: 0.3 s
94.1 % 1.6e+01 s Elapsed time so far: 0.3 s
95.6 % 1.6e+01 s Elapsed time so far: 0.3 s
97.1 % 1.6e+01 s Elapsed time so far: 0.3 s
98.5 % 1.7e+01 s Elapsed time so far: 0.4 s
100.0 % 1.7e+01 s Elapsed time so far: 0.4 s
Defining initial values
Defining variational problem
Defining source terms
Defining boundary conditions
Time stepping...
5.9 % 1.0e+00 s Elapsed time so far: 0.0 s
11.8 % 2.0e+00 s Elapsed time so far: 0.0 s
17.6 % 3.0e+00 s Elapsed time so far: 0.0 s
23.5 % 4.0e+00 s Elapsed time so far: 0.0 s
25.0 % 4.2e+00 s Elapsed time so far: 0.1 s
26.5 % 4.5e+00 s Elapsed time so far: 0.1 s
27.9 % 4.8e+00 s Elapsed time so far: 0.1 s
29.4 % 5.0e+00 s Elapsed time so far: 0.1 s
30.9 % 5.2e+00 s Elapsed time so far: 0.1 s
32.4 % 5.5e+00 s Elapsed time so far: 0.1 s
33.8 % 5.8e+00 s Elapsed time so far: 0.1 s
35.3 % 6.0e+00 s Elapsed time so far: 0.1 s
36.8 % 6.2e+00 s Elapsed time so far: 0.1 s
38.2 % 6.5e+00 s Elapsed time so far: 0.1 s
39.7 % 6.8e+00 s Elapsed time so far: 0.1 s
41.2 % 7.0e+00 s Elapsed time so far: 0.2 s
42.6 % 7.2e+00 s Elapsed time so far: 0.2 s
44.1 % 7.5e+00 s Elapsed time so far: 0.2 s
45.6 % 7.8e+00 s Elapsed time so far: 0.2 s
47.1 % 8.0e+00 s Elapsed time so far: 0.2 s
48.5 % 8.2e+00 s Elapsed time so far: 0.2 s
50.0 % 8.5e+00 s Elapsed time so far: 0.2 s
51.5 % 8.8e+00 s Elapsed time so far: 0.2 s
52.9 % 9.0e+00 s Elapsed time so far: 0.2 s
54.4 % 9.2e+00 s Elapsed time so far: 0.2 s
55.9 % 9.5e+00 s Elapsed time so far: 0.2 s
57.4 % 9.8e+00 s Elapsed time so far: 0.2 s
58.8 % 1.0e+01 s Elapsed time so far: 0.3 s
60.3 % 1.0e+01 s Elapsed time so far: 0.3 s
61.8 % 1.0e+01 s Elapsed time so far: 0.3 s
63.2 % 1.1e+01 s Elapsed time so far: 0.3 s
64.7 % 1.1e+01 s Elapsed time so far: 0.3 s
66.2 % 1.1e+01 s Elapsed time so far: 0.3 s
67.7 % 1.2e+01 s Elapsed time so far: 0.3 s
69.1 % 1.2e+01 s Elapsed time so far: 0.3 s
70.6 % 1.2e+01 s Elapsed time so far: 0.3 s
72.1 % 1.2e+01 s Elapsed time so far: 0.3 s
73.5 % 1.2e+01 s Elapsed time so far: 0.4 s
75.0 % 1.3e+01 s Elapsed time so far: 0.4 s
76.5 % 1.3e+01 s Elapsed time so far: 0.4 s
77.9 % 1.3e+01 s Elapsed time so far: 0.4 s
79.4 % 1.4e+01 s Elapsed time so far: 0.4 s
80.9 % 1.4e+01 s Elapsed time so far: 0.4 s
82.3 % 1.4e+01 s Elapsed time so far: 0.4 s
83.8 % 1.4e+01 s Elapsed time so far: 0.4 s
85.3 % 1.4e+01 s Elapsed time so far: 0.4 s
86.8 % 1.5e+01 s Elapsed time so far: 0.4 s
88.2 % 1.5e+01 s Elapsed time so far: 0.5 s
89.7 % 1.5e+01 s Elapsed time so far: 0.5 s
91.2 % 1.6e+01 s Elapsed time so far: 0.5 s
92.7 % 1.6e+01 s Elapsed time so far: 0.5 s
94.1 % 1.6e+01 s Elapsed time so far: 0.5 s
95.6 % 1.6e+01 s Elapsed time so far: 0.5 s
97.1 % 1.6e+01 s Elapsed time so far: 0.5 s
98.5 % 1.7e+01 s Elapsed time so far: 0.5 s
100.0 % 1.7e+01 s Elapsed time so far: 0.5 s
Defining initial values
Defining variational problem
Defining source terms
Defining boundary conditions
Time stepping...
5.9 % 1.0e+00 s Elapsed time so far: 0.0 s
11.8 % 2.0e+00 s Elapsed time so far: 0.0 s
17.6 % 3.0e+00 s Elapsed time so far: 0.1 s
23.5 % 4.0e+00 s Elapsed time so far: 0.1 s
25.0 % 4.2e+00 s Elapsed time so far: 0.1 s
26.5 % 4.5e+00 s Elapsed time so far: 0.1 s
27.9 % 4.8e+00 s Elapsed time so far: 0.1 s
29.4 % 5.0e+00 s Elapsed time so far: 0.1 s
30.9 % 5.2e+00 s Elapsed time so far: 0.1 s
32.4 % 5.5e+00 s Elapsed time so far: 0.2 s
33.8 % 5.8e+00 s Elapsed time so far: 0.2 s
35.3 % 6.0e+00 s Elapsed time so far: 0.2 s
36.8 % 6.2e+00 s Elapsed time so far: 0.2 s
38.2 % 6.5e+00 s Elapsed time so far: 0.2 s
39.7 % 6.8e+00 s Elapsed time so far: 0.2 s
41.2 % 7.0e+00 s Elapsed time so far: 0.2 s
42.6 % 7.2e+00 s Elapsed time so far: 0.2 s
44.1 % 7.5e+00 s Elapsed time so far: 0.3 s
45.6 % 7.8e+00 s Elapsed time so far: 0.3 s
47.1 % 8.0e+00 s Elapsed time so far: 0.3 s
48.5 % 8.2e+00 s Elapsed time so far: 0.3 s
50.0 % 8.5e+00 s Elapsed time so far: 0.3 s
51.5 % 8.8e+00 s Elapsed time so far: 0.3 s
52.9 % 9.0e+00 s Elapsed time so far: 0.3 s
54.4 % 9.2e+00 s Elapsed time so far: 0.4 s
55.9 % 9.5e+00 s Elapsed time so far: 0.4 s
57.4 % 9.8e+00 s Elapsed time so far: 0.4 s
58.8 % 1.0e+01 s Elapsed time so far: 0.4 s
60.3 % 1.0e+01 s Elapsed time so far: 0.4 s
61.8 % 1.0e+01 s Elapsed time so far: 0.4 s
63.2 % 1.1e+01 s Elapsed time so far: 0.4 s
64.7 % 1.1e+01 s Elapsed time so far: 0.5 s
66.2 % 1.1e+01 s Elapsed time so far: 0.5 s
67.7 % 1.2e+01 s Elapsed time so far: 0.5 s
69.1 % 1.2e+01 s Elapsed time so far: 0.5 s
70.6 % 1.2e+01 s Elapsed time so far: 0.5 s
72.1 % 1.2e+01 s Elapsed time so far: 0.5 s
73.5 % 1.2e+01 s Elapsed time so far: 0.5 s
75.0 % 1.3e+01 s Elapsed time so far: 0.5 s
76.5 % 1.3e+01 s Elapsed time so far: 0.6 s
77.9 % 1.3e+01 s Elapsed time so far: 0.6 s
79.4 % 1.4e+01 s Elapsed time so far: 0.6 s
80.9 % 1.4e+01 s Elapsed time so far: 0.6 s
82.3 % 1.4e+01 s Elapsed time so far: 0.6 s
83.8 % 1.4e+01 s Elapsed time so far: 0.6 s
85.3 % 1.4e+01 s Elapsed time so far: 0.6 s
86.8 % 1.5e+01 s Elapsed time so far: 0.7 s
88.2 % 1.5e+01 s Elapsed time so far: 0.7 s
89.7 % 1.5e+01 s Elapsed time so far: 0.7 s
91.2 % 1.6e+01 s Elapsed time so far: 0.7 s
92.7 % 1.6e+01 s Elapsed time so far: 0.7 s
94.1 % 1.6e+01 s Elapsed time so far: 0.7 s
95.6 % 1.6e+01 s Elapsed time so far: 0.7 s
97.1 % 1.6e+01 s Elapsed time so far: 0.8 s
98.5 % 1.7e+01 s Elapsed time so far: 0.8 s
100.0 % 1.7e+01 s Elapsed time so far: 0.8 s
Defining initial values
Defining variational problem
Defining source terms
Defining boundary conditions
Time stepping...
5.9 % 1.0e+00 s Elapsed time so far: 0.0 s
11.8 % 2.0e+00 s Elapsed time so far: 0.1 s
17.6 % 3.0e+00 s Elapsed time so far: 0.2 s
23.5 % 4.0e+00 s Elapsed time so far: 0.2 s
25.0 % 4.2e+00 s Elapsed time so far: 0.3 s
26.5 % 4.5e+00 s Elapsed time so far: 0.4 s
27.9 % 4.8e+00 s Elapsed time so far: 0.4 s
29.4 % 5.0e+00 s Elapsed time so far: 0.5 s
30.9 % 5.2e+00 s Elapsed time so far: 0.6 s
32.4 % 5.5e+00 s Elapsed time so far: 0.7 s
33.8 % 5.8e+00 s Elapsed time so far: 0.7 s
35.3 % 6.0e+00 s Elapsed time so far: 0.8 s
36.8 % 6.2e+00 s Elapsed time so far: 0.9 s
38.2 % 6.5e+00 s Elapsed time so far: 0.9 s
39.7 % 6.8e+00 s Elapsed time so far: 1.0 s
41.2 % 7.0e+00 s Elapsed time so far: 1.1 s
42.6 % 7.2e+00 s Elapsed time so far: 1.2 s
44.1 % 7.5e+00 s Elapsed time so far: 1.2 s
45.6 % 7.8e+00 s Elapsed time so far: 1.3 s
47.1 % 8.0e+00 s Elapsed time so far: 1.4 s
48.5 % 8.2e+00 s Elapsed time so far: 1.4 s
50.0 % 8.5e+00 s Elapsed time so far: 1.5 s
51.5 % 8.8e+00 s Elapsed time so far: 1.6 s
52.9 % 9.0e+00 s Elapsed time so far: 1.7 s
54.4 % 9.2e+00 s Elapsed time so far: 1.7 s
55.9 % 9.5e+00 s Elapsed time so far: 1.8 s
57.4 % 9.8e+00 s Elapsed time so far: 1.9 s
58.8 % 1.0e+01 s Elapsed time so far: 2.0 s
60.3 % 1.0e+01 s Elapsed time so far: 2.0 s
61.8 % 1.0e+01 s Elapsed time so far: 2.1 s
63.2 % 1.1e+01 s Elapsed time so far: 2.2 s
64.7 % 1.1e+01 s Elapsed time so far: 2.2 s
66.2 % 1.1e+01 s Elapsed time so far: 2.3 s
67.7 % 1.2e+01 s Elapsed time so far: 2.4 s
69.1 % 1.2e+01 s Elapsed time so far: 2.5 s
70.6 % 1.2e+01 s Elapsed time so far: 2.5 s
72.1 % 1.2e+01 s Elapsed time so far: 2.6 s
73.5 % 1.2e+01 s Elapsed time so far: 2.7 s
75.0 % 1.3e+01 s Elapsed time so far: 2.8 s
76.5 % 1.3e+01 s Elapsed time so far: 2.8 s
77.9 % 1.3e+01 s Elapsed time so far: 2.9 s
79.4 % 1.4e+01 s Elapsed time so far: 3.0 s
80.9 % 1.4e+01 s Elapsed time so far: 3.0 s
82.3 % 1.4e+01 s Elapsed time so far: 3.1 s
83.8 % 1.4e+01 s Elapsed time so far: 3.2 s
85.3 % 1.4e+01 s Elapsed time so far: 3.2 s
86.8 % 1.5e+01 s Elapsed time so far: 3.3 s
88.2 % 1.5e+01 s Elapsed time so far: 3.4 s
89.7 % 1.5e+01 s Elapsed time so far: 3.5 s
91.2 % 1.6e+01 s Elapsed time so far: 3.5 s
92.7 % 1.6e+01 s Elapsed time so far: 3.6 s
94.1 % 1.6e+01 s Elapsed time so far: 3.7 s
95.6 % 1.6e+01 s Elapsed time so far: 3.8 s
97.1 % 1.6e+01 s Elapsed time so far: 3.8 s
98.5 % 1.7e+01 s Elapsed time so far: 3.9 s
100.0 % 1.7e+01 s Elapsed time so far: 4.0 s
Defining initial values
Defining variational problem
Defining source terms
Defining boundary conditions
Time stepping...
5.9 % 1.0e+00 s Elapsed time so far: 0.3 s
11.8 % 2.0e+00 s Elapsed time so far: 0.6 s
17.6 % 3.0e+00 s Elapsed time so far: 1.0 s
23.5 % 4.0e+00 s Elapsed time so far: 1.1 s
25.0 % 4.2e+00 s Elapsed time so far: 1.4 s
26.5 % 4.5e+00 s Elapsed time so far: 1.8 s
27.9 % 4.8e+00 s Elapsed time so far: 2.1 s
29.4 % 5.0e+00 s Elapsed time so far: 2.5 s
30.9 % 5.2e+00 s Elapsed time so far: 2.9 s
32.4 % 5.5e+00 s Elapsed time so far: 3.1 s
33.8 % 5.8e+00 s Elapsed time so far: 3.3 s
35.3 % 6.0e+00 s Elapsed time so far: 3.5 s
36.8 % 6.2e+00 s Elapsed time so far: 3.9 s
38.2 % 6.5e+00 s Elapsed time so far: 4.2 s
39.7 % 6.8e+00 s Elapsed time so far: 4.6 s
41.2 % 7.0e+00 s Elapsed time so far: 4.9 s
42.6 % 7.2e+00 s Elapsed time so far: 5.2 s
44.1 % 7.5e+00 s Elapsed time so far: 5.5 s
45.6 % 7.8e+00 s Elapsed time so far: 5.8 s
47.1 % 8.0e+00 s Elapsed time so far: 6.2 s
48.5 % 8.2e+00 s Elapsed time so far: 6.5 s
50.0 % 8.5e+00 s Elapsed time so far: 6.9 s
51.5 % 8.8e+00 s Elapsed time so far: 7.2 s
52.9 % 9.0e+00 s Elapsed time so far: 7.6 s
54.4 % 9.2e+00 s Elapsed time so far: 7.9 s
55.9 % 9.5e+00 s Elapsed time so far: 8.2 s
57.4 % 9.8e+00 s Elapsed time so far: 8.6 s
58.8 % 1.0e+01 s Elapsed time so far: 9.0 s
60.3 % 1.0e+01 s Elapsed time so far: 9.2 s
61.8 % 1.0e+01 s Elapsed time so far: 9.6 s
63.2 % 1.1e+01 s Elapsed time so far: 9.9 s
64.7 % 1.1e+01 s Elapsed time so far: 10.3 s
66.2 % 1.1e+01 s Elapsed time so far: 10.6 s
67.7 % 1.2e+01 s Elapsed time so far: 11.0 s
69.1 % 1.2e+01 s Elapsed time so far: 11.2 s
70.6 % 1.2e+01 s Elapsed time so far: 11.5 s
72.1 % 1.2e+01 s Elapsed time so far: 11.9 s
73.5 % 1.2e+01 s Elapsed time so far: 12.3 s
75.0 % 1.3e+01 s Elapsed time so far: 12.6 s
76.5 % 1.3e+01 s Elapsed time so far: 13.0 s
77.9 % 1.3e+01 s Elapsed time so far: 13.2 s
79.4 % 1.4e+01 s Elapsed time so far: 13.3 s
80.9 % 1.4e+01 s Elapsed time so far: 13.7 s
82.3 % 1.4e+01 s Elapsed time so far: 14.0 s
83.8 % 1.4e+01 s Elapsed time so far: 14.4 s
85.3 % 1.4e+01 s Elapsed time so far: 14.7 s
86.8 % 1.5e+01 s Elapsed time so far: 15.1 s
88.2 % 1.5e+01 s Elapsed time so far: 15.3 s
89.7 % 1.5e+01 s Elapsed time so far: 15.7 s
91.2 % 1.6e+01 s Elapsed time so far: 15.9 s
92.7 % 1.6e+01 s Elapsed time so far: 16.2 s
94.1 % 1.6e+01 s Elapsed time so far: 16.6 s
95.6 % 1.6e+01 s Elapsed time so far: 16.9 s
97.1 % 1.6e+01 s Elapsed time so far: 17.2 s
98.5 % 1.7e+01 s Elapsed time so far: 17.4 s
100.0 % 1.7e+01 s Elapsed time so far: 17.7 s
Defining initial values
Defining variational problem
Defining source terms
Defining boundary conditions
Time stepping...
5.9 % 1.0e+00 s Elapsed time so far: 0.4 s
11.8 % 2.0e+00 s Elapsed time so far: 1.4 s
17.6 % 3.0e+00 s Elapsed time so far: 1.9 s
23.5 % 4.0e+00 s Elapsed time so far: 2.1 s
25.0 % 4.2e+00 s Elapsed time so far: 2.3 s
26.5 % 4.5e+00 s Elapsed time so far: 3.2 s
27.9 % 4.8e+00 s Elapsed time so far: 4.0 s
29.4 % 5.0e+00 s Elapsed time so far: 4.3 s
30.9 % 5.2e+00 s Elapsed time so far: 5.2 s
32.4 % 5.5e+00 s Elapsed time so far: 6.1 s
33.8 % 5.8e+00 s Elapsed time so far: 6.4 s
35.3 % 6.0e+00 s Elapsed time so far: 7.3 s
36.8 % 6.2e+00 s Elapsed time so far: 8.0 s
38.2 % 6.5e+00 s Elapsed time so far: 8.5 s
39.7 % 6.8e+00 s Elapsed time so far: 9.5 s
41.2 % 7.0e+00 s Elapsed time so far: 10.2 s
42.6 % 7.2e+00 s Elapsed time so far: 11.0 s
44.1 % 7.5e+00 s Elapsed time so far: 11.9 s
45.6 % 7.8e+00 s Elapsed time so far: 12.3 s
47.1 % 8.0e+00 s Elapsed time so far: 13.2 s
48.5 % 8.2e+00 s Elapsed time so far: 14.1 s
50.0 % 8.5e+00 s Elapsed time so far: 15.0 s
51.5 % 8.8e+00 s Elapsed time so far: 15.9 s
52.9 % 9.0e+00 s Elapsed time so far: 16.5 s
54.4 % 9.2e+00 s Elapsed time so far: 17.4 s
55.9 % 9.5e+00 s Elapsed time so far: 18.1 s
57.4 % 9.8e+00 s Elapsed time so far: 18.9 s
58.8 % 1.0e+01 s Elapsed time so far: 19.8 s
60.3 % 1.0e+01 s Elapsed time so far: 20.5 s
61.8 % 1.0e+01 s Elapsed time so far: 21.4 s
63.2 % 1.1e+01 s Elapsed time so far: 22.1 s
64.7 % 1.1e+01 s Elapsed time so far: 23.0 s
66.2 % 1.1e+01 s Elapsed time so far: 23.9 s
67.7 % 1.2e+01 s Elapsed time so far: 24.5 s
69.1 % 1.2e+01 s Elapsed time so far: 25.4 s
70.6 % 1.2e+01 s Elapsed time so far: 26.1 s
72.1 % 1.2e+01 s Elapsed time so far: 26.7 s
73.5 % 1.2e+01 s Elapsed time so far: 27.6 s
75.0 % 1.3e+01 s Elapsed time so far: 28.2 s
76.5 % 1.3e+01 s Elapsed time so far: 29.1 s
77.9 % 1.3e+01 s Elapsed time so far: 30.0 s
79.4 % 1.4e+01 s Elapsed time so far: 30.6 s
80.9 % 1.4e+01 s Elapsed time so far: 31.5 s
82.3 % 1.4e+01 s Elapsed time so far: 32.2 s
83.8 % 1.4e+01 s Elapsed time so far: 32.6 s
85.3 % 1.4e+01 s Elapsed time so far: 32.8 s
86.8 % 1.5e+01 s Elapsed time so far: 33.0 s
88.2 % 1.5e+01 s Elapsed time so far: 33.2 s
89.7 % 1.5e+01 s Elapsed time so far: 33.4 s
91.2 % 1.6e+01 s Elapsed time so far: 33.6 s
92.7 % 1.6e+01 s Elapsed time so far: 34.2 s
94.1 % 1.6e+01 s Elapsed time so far: 35.1 s
95.6 % 1.6e+01 s Elapsed time so far: 35.4 s
97.1 % 1.6e+01 s Elapsed time so far: 36.2 s
98.5 % 1.7e+01 s Elapsed time so far: 36.8 s
100.0 % 1.7e+01 s Elapsed time so far: 37.0 s
Show code cell source
h = 1 / np.array(ns)
plt.loglog(h, errors, marker="o")
plt.xlabel("Element size")
plt.ylabel("L2 error")
plt.loglog(h, 2 * h**2, linestyle="--", color="black")
plt.annotate(
"2nd order", (h[0], 2 * h[0] ** 2), textcoords="offset points", xytext=(10, 0)
)
plt.grid(alpha=0.3)
plt.gca().spines[["right", "top"]].set_visible(False)