Hello,
I’ve been trying to test the convergence of a solver that I wrote based on the post here: https://fenicsproject.org/olddocs/dolfin/1.3.0/python/demo/documented/poisson/python/documentation.html#:~:text=The%20Poisson%20equation%20is%20the,gon%20ΓN.
Im using an exact solution that is polynomial, thus with a sufficiently high degree FEM space I should be able to recover it exactly.
Im posting the code I’m using
from dolfin import *
import numpy as np
def solver_online(A, mesh, degree, f):
# Create mesh and define function space
V = FunctionSpace(mesh, "Lagrange", degree)
def boundary(x):
return (
x[0] < DOLFIN_EPS
or x[0] > 1.0 - DOLFIN_EPS
or x[1] < DOLFIN_EPS
or x[1] > 1.0 - DOLFIN_EPS
)
# Define boundary condition
u0 = Constant(0.0)
bc = DirichletBC(V, u0, boundary)
# Define variational problem
u = TrialFunction(V)
v = TestFunction(V)
df = Expression(f, degree=degree)
a = inner(Constant(A) * grad(u), grad(v)) * dx
L = df * v * dx
# Compute solution
u = Function(V)
solve(a == L, u, bc)
return u, V
def test_primal_convergence(hs, degree, f, p_expression) :
for h in hs:
mesh = UnitSquareMesh(
round(1 / (h * np.sqrt(2))),
round(1 / (h * np.sqrt(2))),
)
print(f"{h = }")
p, V = solver_online(
np.array([[5, 1], [1, 5]]),
mesh,
degree,
f,
)
p_exact = interpolate(
Expression(p_expression, degree=degree),
V,
)
set_log_level(50)
p_err = np.sqrt(assemble((p - p_exact) ** 2 * dx(domain=mesh)))
print(f"{p_err = }\n")
if __name__ == "__main__":
hs = [0.25, 0.125, 0.0625]
p_expression = "x[0]*(1-x[0])*x[1]*(1-x[1])"
degree = 3
f = "2*(1-2*x[0])*(1-2*x[1])-10*x[1]*(1-x[1])-10*x[0]*(1-x[0])"
print("running primal formulation convergence test\n\n")
test_primal_convergence(hs, degree, f, p_expression)
This is what I’m getting printed on the terminal:
running primal formulation convergence test
h = 0.25
Solving linear variational problem.
p_err = 0.06668253828972745
h = 0.125
p_err = 0.06666780805961044
h = 0.0625
p_err = 0.06666677073449483`