This example demonstrates the solution of a three-dimensional
elasticity problem. In addition to illustrating how to use
FunctionSpaces, Expressions and how to apply Dirichlet boundary
conditions, it focuses on how to:

* Minimise a non-quadratic functional
* Use automatic computation of the directional derivative
* Solve a nonlinear variational problem
* Define compiled sub-domains
* Use specific form compiler optimization options

Equation and problem definition
-------------------------------

By definition, boundary value problems for hyperelastic media can be
expressed as minimisation problems, and the minimization approach is
adopted in this example. For a domain :math:`\Omega \subset
\mathbb{R}^{d}`, where :math:`d` denotes the spatial dimension, the
task is to find the displacement field :math:`u: \Omega \rightarrow
\mathbb{R}^{d}` that minimises the total potential energy :math:`\Pi`:

.. math::
   \min_{u \in V} \Pi

where :math:`V` is a suitable function space that satisfies boundary
conditions on :math:`u`.  The total potential energy is given by

.. math::
   \Pi = \int_{\Omega} \psi(u) \, {\rm d} x
   - \int_{\Omega} B \cdot u \, {\rm d} x
   - \int_{\partial\Omega} T \cdot u \, {\rm d} s

where :math:`\psi` is the elastic stored energy density, :math:`B` is a
body force (per unit reference volume) and :math:`T` is a traction force
(per unit reference area).

At minimum points of :math:`\Pi`, the directional derivative of :math:`\Pi`
with respect to change in :math:`u`

.. math::
   :label: first_variation

   L(u; v) = D_{v} \Pi = \left. \frac{d \Pi(u + \epsilon v)}{d\epsilon} \right|_{\epsilon = 0}

is equal to zero for all :math:`v \in V`:

.. math::
   L(u; v) = 0 \quad \forall \ v \in V.

To minimise the potential energy, a solution to the variational
equation above is sought. Depending on the potential energy
:math:`\psi`, :math:`L(u; v)` can be nonlinear in :math:`u`. In such a
case, the Jacobian of :math:`L` is required in order to solve this
problem using Newton's method. The Jacobian of :math:`L` is defined as

.. math::
   :label: second_variation

   a(u; du, v) = D_{du} L = \left. \frac{d L(u + \epsilon du; v)}{d\epsilon} \right|_{\epsilon = 0} .



Elastic stored energy density
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

To define the elastic stored energy density, consider the deformation
gradient :math:`F`

.. math::

   F = I + \nabla u,

the right Cauchy-Green tensor :math:`C`

.. math::

   C = F^{T} F,

and the scalars  :math:`J` and :math:`I_{c}`

.. math::
   J     &= \det(F), \\
   I_{c} &= {\rm trace}(C).

This demo considers a common neo-Hookean stored energy model of the form

.. math::
   \psi =  \frac{\mu}{2} (I_{c} - 3) - \mu \ln(J) + \frac{\lambda}{2}\ln(J)^{2}

where :math:`\mu` and :math:`\lambda` are the Lame parameters. These
can be expressed in terms of the more common Young's modulus :math:`E`
and Poisson ratio :math:`\nu` by:

.. math::
    \lambda = \frac{E \nu}{(1 + \nu)(1 - 2\nu)}, \quad  \quad
    \mu     =  \frac{E}{2(1 + \nu)} .


Demo parameters
^^^^^^^^^^^^^^^

We consider a unit cube domain:

* :math:`\Omega = (0, 1) \times (0, 1) \times (0, 1)` (unit cube)

We use the following definitions of the boundary and boundary conditions:

* :math:`\Gamma_{D_{0}} = 0 \times (0, 1) \times (0, 1)` (Dirichlet boundary)

* :math:`\Gamma_{D_{1}} = 1 \times (0, 1) \times (0, 1)` (Dirichlet boundary)

* :math:`\Gamma_{N} = \partial \Omega \backslash \Gamma_{D}` (Neumann boundary)

* On  :math:`\Gamma_{D_{0}}`
    .. math::
        u = (&0, \\
             &(0.5 + (y - 0.5)\cos(\pi/3) - (z - 0.5)\sin(\pi/3) - y)/2, \\
             &(0.5 + (y - 0.5)\sin(\pi/3) + (z - 0.5)\cos(\pi/3) - x))/2)
* On :math:`\Gamma_{D_{1}}`:  :math:`u = (0, 0, 0)`

* On :math:`\Gamma_{N}`: :math:`T = (0.1, 0, 0)`

These are the body forces and material parameters used:

* :math:`B = (0, -0.5, 0)`

* :math:`E    = 10.0`

* :math:`\nu  = 0.3`

With the above input the solution for :math:`u` will look as follows:

.. image:: ../hyperelasticity_u0.png
    :scale: 75
    :align: center

.. image:: ../hyperelasticity_u1.png
    :scale: 75
    :align: center

