The solution blows up to infinity at every point, so I’m guessing this variational-form is unstable. Are Galerkins/variational-forms of 1st-order differential equations generally unstable? How should they be handled?
You can use Least Squares Finite element methods, i.e.
Reformulate your problem as \min_u \frac{1}{2}\int_\Omega (u' - f)^2~\mathrm{d}x
which ends up solving \int_\Omega (u' - f) v' ~\mathrm{d}x
import numpy as np
import ufl
from mpi4py import MPI
from dolfinx import mesh, fem, default_scalar_type
from dolfinx.fem.petsc import LinearProblem
# 1. Create mesh and function space
L = 1.0
nx = 50
domain = mesh.create_interval(MPI.COMM_WORLD, nx, [0.0, L])
# Using degree=2 since the exact solution x(1-x) is quadratic.
# This will capture the solution exactly up to machine precision.
V = fem.functionspace(domain, ("CG", 2))
u = ufl.TrialFunction(V)
v = ufl.TestFunction(V)
x = ufl.SpatialCoordinate(domain)
# 2. Define the source term
u_exact = x[0] * (1.0 - x[0])
f = u_exact.dx(0)
# 3. The Least Squares Weak Form (notice the dx(0) on the test function)
# dx(0) is the derivative with respect to the spatial coordinate x
a = u.dx(0) * v.dx(0) * ufl.dx
L_form = f * v.dx(0) * ufl.dx
# 4. Define Dirichlet Boundary Condition at x = L
def boundary_L(x):
return np.isclose(x[0], L)
# Locate boundary facets and DOFs
fdim = domain.topology.dim - 1
boundary_facets = mesh.locate_entities_boundary(domain, fdim, boundary_L)
bc_dofs = fem.locate_dofs_topological(V, fdim, boundary_facets)
compiled_expr = fem.Expression(u_exact, V.element.interpolation_points)
u_bc = fem.Function(V)
u_bc.interpolate(compiled_expr)
bc = fem.dirichletbc(u_bc, bc_dofs)
# 5. Solve the linear problem
problem = LinearProblem(
a,
L_form,
bcs=[bc],
petsc_options={"ksp_type": "preonly", "pc_type": "lu"},
petsc_options_prefix="ls_test_",
)
uh = problem.solve()
error_loc = fem.assemble_scalar(fem.form((uh - u_exact) ** 2 * ufl.dx))
error_glob = np.sqrt(domain.comm.allreduce(error_loc, op=MPI.SUM))
print(f"{nx} Error in L2 norm: {error_glob:.3e}")
Ah that worked! Thank you! The code comments are also appreciated! So, rather than convoluting with a test function like with a Poisson Equation, you’re minimizing the square of the L2-norm.
Do you know if this method is handled in standard introductory texts on Finite Element Methods, or if this is a more advanced technique?