# Poisson equationΒΆ

It is what it is, a conforming discretization on a regular mesh using piecewise quadratic elements.

As usual we start by importing firedrake and setting up the problem.:

```
from firedrake import *
N = 128
mesh = UnitSquareMesh(N, N)
V = FunctionSpace(mesh, "CG", 2)
u = TrialFunction(V)
v = TestFunction(V)
a = inner(grad(u), grad(v)) * dx
x = SpatialCoordinate(mesh)
F = Function(V)
F.interpolate(sin(x[0]*pi)*sin(2*x[1]*pi))
L = F*v*dx
bcs = [DirichletBC(V, Constant(2.0), (1,))]
uu = Function(V)
```

With the setup out of the way, we now demonstrate various ways of configuring the solver. First, a direct solve with an assembled operator.:

```
solve(a == L, uu, bcs=bcs, solver_parameters={"ksp_type": "preonly",
"pc_type": "lu"})
```

Next, we use unpreconditioned conjugate gradients using matrix-free
actions. This is not very efficient due to the \(h^{-2}\)
conditioning of the Laplacian, but demonstrates how to request an
unassembled operator using the `"mat_type"`

solver parameter.:

```
uu.assign(0)
solve(a == L, uu, bcs=bcs, solver_parameters={"mat_type": "matfree",
"ksp_type": "cg",
"pc_type": "none",
"ksp_monitor": None})
```

Finally, we demonstrate the use of a `AssembledPC`

preconditioner. This uses matrix-free actions but preconditions the
Krylov iterations with an incomplete LU factorisation of the assembled
operator.:

```
uu.assign(0)
solve(a == L, uu, bcs=bcs, solver_parameters={"mat_type": "matfree",
"ksp_type": "cg",
"ksp_monitor": None,
```

To use the assembled matrix for the preconditioner we select a
`"python"`

type:

```
"pc_type": "python",
```

and set its type, by providing the name of the class constructor to PETSc.:

```
"pc_python_type": "firedrake.AssembledPC",
```

Finally, we set the preconditioner type for the assembled operator:

```
"assembled_pc_type": "ilu"})
```

This demo is available as a runnable python file here.