Documentation for Release 2024.2

# Solving Nonlinear Pdes

This tutorial is automatically generated from TestSolvingNonlinearPdesTutorial.hpp at revision 71ac325b969f. Note that the code is given in full at the bottom of the page.

## An example showing how to solve a nonlinear elliptic PDE. Also includes function-based boundary conditions.

In this tutorial we show how Chaste can be used to solve nonlinear elliptic PDEs. We will solve the PDE $\nabla .(u \nabla u) + 1 = 0$, on a square domain, with boundary conditions $u=0$ on $y=0$, and Neumann boundary conditions: $(u \nabla u).\mathbf{n} = 0$ on $x=0$ and $x=1$; and $(u \nabla u).\mathbf{n} = y$ on $y=1$.

For nonlinear PDEs, the finite element equations are of the form $\mathbf{F}(\mathbf{U})=0$, where $\mathbf{U}=(U_1 , \dots , U_N)$ is a vector of the unknowns at each node, and $\mathbf{F}$ is some non-linear vector valued function. To solve this, a nonlinear solver is required. Chaste can solve this with Newton’s method, or (default) use PETSc’s nonlinear solvers. Solvers of such nonlinear problems usually require the Jacobian of the problem, i.e. the matrix $A = \partial F/ \partial U$, or at least an approximation of the Jacobian.

The following header files need to be included, as in the linear PDEs tutorial.

This is the solver for nonlinear elliptic PDEs.

In this test we also show how to define Neumman boundary conditions which depend on spatial location, for which the following class is needed.

We will choose to use the Chaste Newton solver rather than PETSc’s nonlinear solver.

As in the linear PDEs tutorial, we have to define the PDE class we want to
solve (assuming one has not already been created). Nonlinear elliptic PDEs
should inherit from `AbstractNonlinearEllipticPde`

, which has five pure
methods which have to be implemented in this concrete class. Here, we define
the PDE $\nabla .(u \nabla u) + 1 = 0$.

The first is the part of the source term that is independent of $u$.

The second is the part of the source term that is dependent on $u$.

The third is the diffusion tensor, which unlike in the linear case can be dependent on $u$. The diffusion tensor should be symmetric and positive definite.

We also need to provide the derivatives with respect to $u$ of the last two methods, so that the Jacobian matrix can be assembled. The derivative of the nonlinear source term is

And the derivative of the diffusion tensor is just the identity matrix.

We also need to define a (global) function that will become the Neumman boundary
conditions, via the `FunctionalBoundaryCondition`

class (see below). This
function is $f(x,y) = y$.

Next, we define the test suite, as before.

Define a particular test.

As usual, first create a mesh.

Next, instantiate the PDE to be solved.

Then we have to define the boundary conditions. First, the Dirichlet boundary condition, $u=0$ on $x=0$, using the boundary node iterator.

And then the Neumman conditions. Neumann boundary condition are defined on
surface elements, and for this problem, the Neumman boundary value depends
on the position in space, so we make use of the `FunctionalBoundaryCondition`

object, which contains a pointer to a function, and just returns the value
of that function for the required point when the `GetValue`

method is called.

Loop over surface elements.

Get the $y$ value of any node (here, the zero-th).

If y=1…

… then associate the functional boundary condition, $(D \nabla u).n = y$, with the surface element…

…else associate the zero boundary condition (i.e. zero flux) with this element.

Note that in the above loop, the zero Neumman boundary condition was applied to all surface elements for which $y \neq 1$, which included the Dirichlet surface $y=0$. This is OK, as Dirichlet boundary conditions are applied to the finite element matrix after Neumman boundary conditions, where the appropriate rows in the matrix are overwritten.

This is the solver for solving nonlinear problems, which, as usual, takes in the mesh, the PDE, and the boundary conditions.

The solver also needs to be given an initial guess, which will be a PETSc vector. We can make use of a helper method to create it.

**Optional:** To use Chaste’s Newton solver to solve nonlinear vector equations that are
assembled, rather than the default PETSc nonlinear solvers, we can
do the following:

**Optional:** We can also manually set tolerances, and whether to print statistics, with
this nonlinear vector equation solver

Now call `Solve`

, passing in the initial guess

Note that we could have got the solver to not use an analytical Jacobian and use a numerically-calculated Jacobian instead, by passing in false as a second parameter:

Once solved, we can check the obtained solution against the analytical solution.

Finally, we have to remember to destroy the PETSc `Vec`

s.