← Back to team overview

ffc team mailing list archive

Re: evaluate_integrand

 

On Tue, Apr 13, 2010 at 12:51:29PM +0200, Mehdi Nikbakht wrote:
> On Tue, 2010-04-13 at 11:59 +0200, Anders Logg wrote:
> > On Tue, Apr 13, 2010 at 11:31:38AM +0200, Mehdi Nikbakht wrote:
> > > On Tue, 2010-04-13 at 10:43 +0200, Anders Logg wrote:
> > > > On Tue, Apr 13, 2010 at 10:31:51AM +0200, Mehdi Nikbakht wrote:
> > > > > On Tue, 2010-04-13 at 09:45 +0200, Anders Logg wrote:
> > > > > > On Tue, Apr 13, 2010 at 07:17:28AM +0800, Garth N. Wells wrote:
> > > > > > >
> > > > > > >
> > > > > > > On 12/04/10 23:35, Anders Logg wrote:
> > > > > > > >On Mon, Apr 12, 2010 at 10:20:13PM +0800, Garth N. Wells wrote:
> > > > > > > >>
> > > > > > > >>
> > > > > > > >>On 12/04/10 21:49, Anders Logg wrote:
> > > > > > > >>>On Mon, Apr 12, 2010 at 09:34:38PM +0800, Garth N. Wells wrote:
> > > > > > > >>>>
> > > > > > > >>>>
> > > > > > > >>>>On 12/04/10 21:29, Anders Logg wrote:
> > > > > > > >>>>>On Mon, Apr 12, 2010 at 09:21:32PM +0800, Garth N. Wells wrote:
> > > > > > > >>>>>>
> > > > > > > >>>>>>
> > > > > > > >>>>>>On 12/04/10 21:19, Garth N. Wells wrote:
> > > > > > > >>>>>>>
> > > > > > > >>>>>>>
> > > > > > > >>>>>>>On 12/04/10 20:47, Anders Logg wrote:
> > > > > > > >>>>>>>>We are doing some work where we need to do run-time quadrature over
> > > > > > > >>>>>>>>arbitrary polyhedra.
> > > > > > > >>>>>>>
> > > > > > > >>>>>>>We (Mehdi and I) do this already (using UFC), so I don't see why a new
> > > > > > > >>>>>>>function is required. Can you explain why evaluate_tensor is not enough?
> > > > > > > >>>>>>>
> > > > > > > >>>>>>
> > > > > > > >>>>>>I meant 'tabulate_tensor'.
> > > > > > > >>>>>
> > > > > > > >>>>>Which function do you call for evaluating the integrand?
> > > > > > > >>>>>
> > > > > > > >>>>
> > > > > > > >>>>We evaluate it inside ufc::tabulate_tensor. We construct our forms
> > > > > > > >>>>with an extra argument, say an object "CutCellIntegrator", which can
> > > > > > > >>>>provide quadrature schemes which depend on the considered cell.
> > > > > > > >>>
> > > > > > > >>>That would require a special purpose code generator.
> > > > > > > >>
> > > > > > > >>What's wrong with that? FFC won't (and shouldn't) be able to do
> > > > > > > >>everything. Just adding a function to UFC won't make FFC do what we
> > > > > > > >>do now. We reuse FFC (import modules) and add special purpose
> > > > > > > >>extensions.
> > > > > > > >
> > > > > > > >Exactly, it won't make FFC do what we need, but we could *use* FFC to
> > > > > > > >do what we need (without adding a special-purpose code generator).
> > > > > > > >
> > > > > > > >>>Having
> > > > > > > >>>evaluate_integrand would allow more flexibility for users to implement
> > > > > > > >>>their own special quadrature scheme.
> > > > > > > >>>
> > > > > > > >>
> > > > > > > >>We make "CutCellIntegrator" an abstract base class, so the user has
> > > > > > > >>*complete* freedom to define the quadrature scheme and the generated
> > > > > > > >>code does not depend on the scheme, since the scheme may depend on
> > > > > > > >>things like how the cell 'cut' is represented.
> > > > > > > >
> > > > > > > >Then it sounds to me like that generated code is not at all special,
> > > > > > > >but instead general purpose and should be added to UFC/FFC.
> > > > > > > >
> > > > > > > >And the most general interface would (I think) be an interface for
> > > > > > > >evaluating the integrand at a given point. We already have the same
> > > > > > > >for basis functions (evaluate_basis_function) so it is a natural
> > > > > > > >extension.
> > > > > > > >
> > > > > > >
> > > > > > > I still don't see the need for 'evaluate_integrand' unless you plan
> > > > > > > to call it directly from the assembler side (i.e. DOLFIN). Is that
> > > > > > > the case? Perhaps you can give me a concrete example of how you plan
> > > > > > > to use it.
> > > > > >
> > > > > > Yes, that's the plan. In pseudo-code, this is what we want to do:
> > > > > >
> > > > > >   for polyhedron in intersection.cut_cells:
> > > > > >
> > > > > >     quadrature_rule = QuadratureRule(polyhedron)
> > > > > >     AK = 0
> > > > > >
> > > > > >     for (x, w) in quadrature_rule:
> > > > > >
> > > > > >       AK += w * evaluate_integrand(x)
> > > > > >
> > > > > >     A += AK
> > > > > >
> > > > > > All data representing the geometry, the polyhedra, mappings from those
> > > > > > polyhedra to the original cells etc is in the Intersection class (in
> > > > > > the sandbox):
> > > > > >
> > > > > >   intersection = Intersection(mesh0, mesh1)
> > > > > >
> > > > > > Eventually, we might want to move part of the functionality into
> > > > > > either DOLFIN or FFC, but having access to and evaluate_integrand
> > > > > > function makes it possible to experiment (from the C++ side) without
> > > > > > the need for building complex abstractions at this point.
> > > > >
> > > > > As far as I understood you want to compute the integration points for
> > > > > polyhedrons inside Dolfin and evaluate_integrands will just compute that
> > > > > integrand in that specific integration points. If it is the case how
> > > > > would you determine what is the order of quadrature rule that you want
> > > > > to use?
> > > >
> > > > The quadrature rule would be a simple option for the user to
> > > > set. Currently we only have one general rule implemented which is
> > > > barycentric quadrature.
> > >
> > > Then if you use higher order elements, you need to update your
> > > quadrature rule manually. I think it would be nice to compute your own
> > > quadrature rule inside tabualte_tensor by using the standard quadrature
> > > rule.
> >
> > Yes, but the problem is that the computation of the quadrature rule is
> > nontrivial and it might be better to do it from C++ than as part of
> > the generated code, especially when the code depends on external
> > libraries like CGAL. See BarycenterQuadrature.cpp.
>
> Where can I find this file?

In the directory dolfin/quadrature/ in DOLFIN.

> > > > > Since to evaluate integrands you need to tabulate basis functions and
> > > > > their derivatives on arbitrary points. How do you want to tabulate basis
> > > > > functions and their derivatives inside evaluate_integrands?
> > > >
> > > > That's a good point. We would need to evaluate the basis functions and
> > > > their derivatives at a given arbitrary point which is not known at
> > > > compile-time.
> > >
> > > Yes, you need to use the tabulate_basis* functions implemented by
> > > Kristian. Then I am not the only one who is using them. Good for
> > > Kristian. ;)
> >
> > ok, good. Then there is no principal problem of generating code for
> > evaluate_integrand (if it is allowed to call tabaulate_basis).
> >
> > I don't see what the problem is of adding evaluate_integrand. It is a
> > natural extension (we have evaluate_basis already), it would be
> > "simple" to implement (Kristian can correct me if I'm wrong) and it
> > makes generated code useful for assembly over cut meshes (without the
> > need for writing a special-purpose code generator).
>
> I don't think it would be straightforward in the current ffc modules.
> You need to tabulate basis functions and their derivatives in the
> compile time which differs from what is already in the place. You should
> have your own quadrature transformer to generates entries required for
> this case. It is similar to what we have done for XFEM.

What is so complicated? The current quadrature code does this:

  1. Tabulate basis functions at quadrature points (precomputed values)

  2. Iterate over quadrature points

  3. Evaluate integrand at each quadrature points

The new function would need to

  1. Evaluate basis functions at given quadrature point

  2. Evaluate integrand at each quadrature points

> Please have a look on the tabulate_Tensor function inside generated code
> for Poisson demo in the attached files.

It looks too complex for me. What I propose is a very simple extension
of UFC (a function that is simpler than what we have now) which would
allow users (such as myself) to handle the complexity elsewhere.

--
Anders


> // This code conforms with the UFC specification version 1.4
> // and was automatically generated by FFC version 0.9.2+.
> //
> // This code was generated with the option '-l dolfin' and
> // contains DOLFIN-specific wrappers that depend on DOLFIN.
> //
> // This code was generated with the following parameters:
> //
> //   cache_dir:                      ''
> //   convert_exceptions_to_warnings: False
> //   cpp_optimize:                   False
> //   epsilon:                        1e-14
> //   form_postfix:                   True
> //   format:                         'dolfin'
> //   log_level:                      20
> //   log_prefix:                     ''
> //   optimize:                       False
> //   output_dir:                     '.'
> //   precision:                      15
> //   quadrature_degree:              'auto'
> //   quadrature_rule:                'auto'
> //   representation:                 'quadrature'
> //   split:                          False
>
> #ifndef __POISSON_H
> #define __POISSON_H
>
> #include <cmath>
> #include <algorithm>
> #include <stdexcept>
> #include <fstream>
> #include <boost/assign/list_of.hpp>
> #include <ufc.h>
> #include <pum/GenericPUM.h>
>
> /// This class defines the interface for a finite element.
>
> class poisson_finite_element_0: public ufc::finite_element
> {
> public:
>
>   /// Constructor
>   poisson_finite_element_0() : ufc::finite_element()
>   {
>     // Do nothing
>   }
>
>   /// Destructor
>   virtual ~poisson_finite_element_0()
>   {
>     // Do nothing
>   }
>
>   /// Return a string identifying the finite element
>   virtual const char* signature() const
>   {
>     return "FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)";
>   }
>
>   /// Return the cell shape
>   virtual ufc::shape cell_shape() const
>   {
>     return ufc::triangle;
>   }
>
>   /// Return the dimension of the finite element function space
>   virtual unsigned int space_dimension() const
>   {
>     return 3;
>   }
>
>   /// Return the rank of the value space
>   virtual unsigned int value_rank() const
>   {
>     return 0;
>   }
>
>   /// Return the dimension of the value space for axis i
>   virtual unsigned int value_dimension(unsigned int i) const
>   {
>     return 1;
>   }
>
>   /// Evaluate basis function i at given point in cell
>   virtual void evaluate_basis(unsigned int i,
>                               double* values,
>                               const double* coordinates,
>                               const ufc::cell& c) const
>   {
>     // Extract vertex coordinates
>     const double * const * x = c.coordinates;
>
>     // Compute Jacobian of affine map from reference cell
>     const double J_00 = x[1][0] - x[0][0];
>     const double J_01 = x[2][0] - x[0][0];
>     const double J_10 = x[1][1] - x[0][1];
>     const double J_11 = x[2][1] - x[0][1];
>
>     // Compute determinant of Jacobian
>     double detJ = J_00*J_11 - J_01*J_10;
>
>     // Compute inverse of Jacobian
>
>     // Compute constants
>     const double C0 = x[1][0] + x[2][0];
>     const double C1 = x[1][1] + x[2][1];
>
>     // Get coordinates and map to the reference (FIAT) element
>     double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ;
>     double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ;
>
>     // Reset values.
>     *values = 0.000000000000000;
>
>     // Map degree of freedom to element degree of freedom
>     const unsigned int dof = i;
>
>     // Array of basisvalues.
>     double basisvalues[3] = {0.000000000000000, 0.000000000000000, 0.000000000000000};
>
>     // Declare helper variables.
>     unsigned int rr = 0;
>     unsigned int ss = 0;
>     double tmp0 = (1.000000000000000 + Y + 2.000000000000000*X)/2.000000000000000;
>
>     // Compute basisvalues.
>     basisvalues[0] = 1.000000000000000;
>     basisvalues[1] = tmp0;
>     for (unsigned int r = 0; r < 1; r++)
>     {
>       rr = (r + 1)*(r + 1 + 1)/2 + 1;
>       ss = r*(r + 1)/2;
>       basisvalues[rr] = basisvalues[ss]*(0.500000000000000 + r + Y*(1.500000000000000 + r));
>     }// end loop over 'r'
>     for (unsigned int r = 0; r < 2; r++)
>     {
>       for (unsigned int s = 0; s < 2 - r; s++)
>       {
>         rr = (r + s)*(r + s + 1)/2 + s;
>         basisvalues[rr] *= std::sqrt((0.500000000000000 + r)*(1.000000000000000 + r + s));
>       }// end loop over 's'
>     }// end loop over 'r'
>
>     // Table(s) of coefficients.
>     static const double coefficients0[3][3] = \
>     {{0.471404520791032, -0.288675134594813, -0.166666666666667},
>     {0.471404520791032, 0.288675134594813, -0.166666666666667},
>     {0.471404520791032, 0.000000000000000, 0.333333333333333}};
>
>     // Compute value(s).
>     for (unsigned int r = 0; r < 3; r++)
>     {
>       *values += coefficients0[dof][r]*basisvalues[r];
>     }// end loop over 'r'
>   }
>
>   /// Evaluate all basis functions at given point in cell
>   virtual void evaluate_basis_all(double* values,
>                                   const double* coordinates,
>                                   const ufc::cell& c) const
>   {
>     // Helper variable to hold values of a single dof.
>     double dof_values = 0.000000000000000;
>
>     // Loop dofs and call evaluate_basis.
>     for (unsigned int r = 0; r < 3; r++)
>     {
>       evaluate_basis(r, &dof_values, coordinates, c);
>       values[r] = dof_values;
>     }// end loop over 'r'
>   }
>
>   /// Evaluate order n derivatives of basis function i at given point in cell
>   virtual void evaluate_basis_derivatives(unsigned int i,
>                                           unsigned int n,
>                                           double* values,
>                                           const double* coordinates,
>                                           const ufc::cell& c) const
>   {
>     // Extract vertex coordinates
>     const double * const * x = c.coordinates;
>
>     // Compute Jacobian of affine map from reference cell
>     const double J_00 = x[1][0] - x[0][0];
>     const double J_01 = x[2][0] - x[0][0];
>     const double J_10 = x[1][1] - x[0][1];
>     const double J_11 = x[2][1] - x[0][1];
>
>     // Compute determinant of Jacobian
>     double detJ = J_00*J_11 - J_01*J_10;
>
>     // Compute inverse of Jacobian
>     const double K_00 =  J_11 / detJ;
>     const double K_01 = -J_01 / detJ;
>     const double K_10 = -J_10 / detJ;
>     const double K_11 =  J_00 / detJ;
>
>     // Compute constants
>     const double C0 = x[1][0] + x[2][0];
>     const double C1 = x[1][1] + x[2][1];
>
>     // Get coordinates and map to the reference (FIAT) element
>     double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ;
>     double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ;
>
>     // Compute number of derivatives.
>     unsigned int num_derivatives = 1;
>     for (unsigned int r = 0; r < n; r++)
>     {
>       num_derivatives *= 2;
>     }// end loop over 'r'
>
>     // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
>     unsigned int **combinations = new unsigned int *[num_derivatives];
>     for (unsigned int row = 0; row < num_derivatives; row++)
>     {
>       combinations[row] = new unsigned int [n];
>       for (unsigned int col = 0; col < n; col++)
>         combinations[row][col] = 0;
>     }
>
>     // Generate combinations of derivatives
>     for (unsigned int row = 1; row < num_derivatives; row++)
>     {
>       for (unsigned int num = 0; num < row; num++)
>       {
>         for (unsigned int col = n-1; col+1 > 0; col--)
>         {
>           if (combinations[row][col] + 1 > 1)
>             combinations[row][col] = 0;
>           else
>           {
>             combinations[row][col] += 1;
>             break;
>           }
>         }
>       }
>     }
>
>     // Compute inverse of Jacobian
>     const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}};
>
>     // Declare transformation matrix
>     // Declare pointer to two dimensional array and initialise
>     double **transform = new double *[num_derivatives];
>
>     for (unsigned int j = 0; j < num_derivatives; j++)
>     {
>       transform[j] = new double [num_derivatives];
>       for (unsigned int k = 0; k < num_derivatives; k++)
>         transform[j][k] = 1;
>     }
>
>     // Construct transformation matrix
>     for (unsigned int row = 0; row < num_derivatives; row++)
>     {
>       for (unsigned int col = 0; col < num_derivatives; col++)
>       {
>         for (unsigned int k = 0; k < n; k++)
>           transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
>       }
>     }
>
>     // Reset values. Assuming that values is always an array.
>     for (unsigned int r = 0; r < num_derivatives; r++)
>     {
>       values[r] = 0.000000000000000;
>     }// end loop over 'r'
>
>     // Map degree of freedom to element degree of freedom
>     const unsigned int dof = i;
>
>     // Array of basisvalues.
>     double basisvalues[3] = {0.000000000000000, 0.000000000000000, 0.000000000000000};
>
>     // Declare helper variables.
>     unsigned int rr = 0;
>     unsigned int ss = 0;
>     double tmp0 = (1.000000000000000 + Y + 2.000000000000000*X)/2.000000000000000;
>
>     // Compute basisvalues.
>     basisvalues[0] = 1.000000000000000;
>     basisvalues[1] = tmp0;
>     for (unsigned int r = 0; r < 1; r++)
>     {
>       rr = (r + 1)*(r + 1 + 1)/2 + 1;
>       ss = r*(r + 1)/2;
>       basisvalues[rr] = basisvalues[ss]*(0.500000000000000 + r + Y*(1.500000000000000 + r));
>     }// end loop over 'r'
>     for (unsigned int r = 0; r < 2; r++)
>     {
>       for (unsigned int s = 0; s < 2 - r; s++)
>       {
>         rr = (r + s)*(r + s + 1)/2 + s;
>         basisvalues[rr] *= std::sqrt((0.500000000000000 + r)*(1.000000000000000 + r + s));
>       }// end loop over 's'
>     }// end loop over 'r'
>
>     // Table(s) of coefficients.
>     static const double coefficients0[3][3] = \
>     {{0.471404520791032, -0.288675134594813, -0.166666666666667},
>     {0.471404520791032, 0.288675134594813, -0.166666666666667},
>     {0.471404520791032, 0.000000000000000, 0.333333333333333}};
>
>     // Tables of derivatives of the polynomial base (transpose).
>     static const double dmats0[3][3] = \
>     {{0.000000000000000, 0.000000000000000, 0.000000000000000},
>     {4.898979485566356, 0.000000000000000, 0.000000000000000},
>     {0.000000000000000, 0.000000000000000, 0.000000000000000}};
>
>     static const double dmats1[3][3] = \
>     {{0.000000000000000, 0.000000000000000, 0.000000000000000},
>     {2.449489742783178, 0.000000000000000, 0.000000000000000},
>     {4.242640687119285, 0.000000000000000, 0.000000000000000}};
>
>     // Compute reference derivatives.
>     // Declare pointer to array of derivatives on FIAT element.
>     double *derivatives = new double[num_derivatives];
>     for (unsigned int r = 0; r < num_derivatives; r++)
>     {
>       derivatives[r] = 0.000000000000000;
>     }// end loop over 'r'
>
>     // Declare derivative matrix (of polynomial basis).
>     double dmats[3][3] = \
>     {{1.000000000000000, 0.000000000000000, 0.000000000000000},
>     {0.000000000000000, 1.000000000000000, 0.000000000000000},
>     {0.000000000000000, 0.000000000000000, 1.000000000000000}};
>
>     // Declare (auxiliary) derivative matrix (of polynomial basis).
>     double dmats_old[3][3] = \
>     {{1.000000000000000, 0.000000000000000, 0.000000000000000},
>     {0.000000000000000, 1.000000000000000, 0.000000000000000},
>     {0.000000000000000, 0.000000000000000, 1.000000000000000}};
>
>     // Loop possible derivatives.
>     for (unsigned int r = 0; r < num_derivatives; r++)
>     {
>       // Resetting dmats values to compute next derivative.
>       for (unsigned int t = 0; t < 3; t++)
>       {
>         for (unsigned int u = 0; u < 3; u++)
>         {
>           dmats[t][u] = 0.000000000000000;
>           if (t == u)
>           {
>           dmats[t][u] = 1.000000000000000;
>           }
>
>         }// end loop over 'u'
>       }// end loop over 't'
>
>       // Looping derivative order to generate dmats.
>       for (unsigned int s = 0; s < n; s++)
>       {
>         // Updating dmats_old with new values and resetting dmats.
>         for (unsigned int t = 0; t < 3; t++)
>         {
>           for (unsigned int u = 0; u < 3; u++)
>           {
>             dmats_old[t][u] = dmats[t][u];
>             dmats[t][u] = 0.000000000000000;
>           }// end loop over 'u'
>         }// end loop over 't'
>
>         // Update dmats using an inner product.
>         if (combinations[r][s] == 0)
>         {
>         for (unsigned int t = 0; t < 3; t++)
>         {
>           for (unsigned int u = 0; u < 3; u++)
>           {
>             for (unsigned int tu = 0; tu < 3; tu++)
>             {
>               dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
>             }// end loop over 'tu'
>           }// end loop over 'u'
>         }// end loop over 't'
>         }
>
>         if (combinations[r][s] == 1)
>         {
>         for (unsigned int t = 0; t < 3; t++)
>         {
>           for (unsigned int u = 0; u < 3; u++)
>           {
>             for (unsigned int tu = 0; tu < 3; tu++)
>             {
>               dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
>             }// end loop over 'tu'
>           }// end loop over 'u'
>         }// end loop over 't'
>         }
>
>       }// end loop over 's'
>       for (unsigned int s = 0; s < 3; s++)
>       {
>         for (unsigned int t = 0; t < 3; t++)
>         {
>           derivatives[r] += coefficients0[dof][s]*dmats[s][t]*basisvalues[t];
>         }// end loop over 't'
>       }// end loop over 's'
>     }// end loop over 'r'
>
>     // Transform derivatives back to physical element
>     for (unsigned int r = 0; r < num_derivatives; r++)
>     {
>       for (unsigned int s = 0; s < num_derivatives; s++)
>       {
>         values[r] += transform[r][s]*derivatives[s];
>       }// end loop over 's'
>     }// end loop over 'r'
>
>     // Delete pointer to array of derivatives on FIAT element
>     delete [] derivatives;
>
>     // Delete pointer to array of combinations of derivatives and transform
>     for (unsigned int r = 0; r < num_derivatives; r++)
>     {
>       delete [] combinations[r];
>     }// end loop over 'r'
>     delete [] combinations;
>     for (unsigned int r = 0; r < num_derivatives; r++)
>     {
>       delete [] transform[r];
>     }// end loop over 'r'
>     delete [] transform;
>   }
>
>   /// Evaluate order n derivatives of all basis functions at given point in cell
>   virtual void evaluate_basis_derivatives_all(unsigned int n,
>                                               double* values,
>                                               const double* coordinates,
>                                               const ufc::cell& c) const
>   {
>     // Compute number of derivatives.
>     unsigned int num_derivatives = 1;
>     for (unsigned int r = 0; r < n; r++)
>     {
>       num_derivatives *= 2;
>     }// end loop over 'r'
>
>     // Helper variable to hold values of a single dof.
>     double *dof_values = new double[num_derivatives];
>     for (unsigned int r = 0; r < num_derivatives; r++)
>     {
>       dof_values[r] = 0.000000000000000;
>     }// end loop over 'r'
>
>     // Loop dofs and call evaluate_basis_derivatives.
>     for (unsigned int r = 0; r < 3; r++)
>     {
>       evaluate_basis_derivatives(r, n, dof_values, coordinates, c);
>       for (unsigned int s = 0; s < num_derivatives; s++)
>       {
>         values[r*num_derivatives + s] = dof_values[s];
>       }// end loop over 's'
>     }// end loop over 'r'
>
>     // Delete pointer.
>     delete [] dof_values;
>   }
>
>   /// Evaluate linear functional for dof i on the function f
>   virtual double evaluate_dof(unsigned int i,
>                               const ufc::function& f,
>                               const ufc::cell& c) const
>   {
>     // Declare variables for result of evaluation.
>     double vals[1];
>
>     // Declare variable for physical coordinates.
>     double y[2];
>     const double * const * x = c.coordinates;
>     switch (i)
>     {
>     case 0:
>       {
>         y[0] = x[0][0];
>       y[1] = x[0][1];
>       f.evaluate(vals, y, c);
>       return vals[0];
>         break;
>       }
>     case 1:
>       {
>         y[0] = x[1][0];
>       y[1] = x[1][1];
>       f.evaluate(vals, y, c);
>       return vals[0];
>         break;
>       }
>     case 2:
>       {
>         y[0] = x[2][0];
>       y[1] = x[2][1];
>       f.evaluate(vals, y, c);
>       return vals[0];
>         break;
>       }
>     }
>
>     return 0.000000000000000;
>   }
>
>   /// Evaluate linear functionals for all dofs on the function f
>   virtual void evaluate_dofs(double* values,
>                              const ufc::function& f,
>                              const ufc::cell& c) const
>   {
>     // Declare variables for result of evaluation.
>     double vals[1];
>
>     // Declare variable for physical coordinates.
>     double y[2];
>     const double * const * x = c.coordinates;
>     y[0] = x[0][0];
>     y[1] = x[0][1];
>     f.evaluate(vals, y, c);
>     values[0] = vals[0];
>     y[0] = x[1][0];
>     y[1] = x[1][1];
>     f.evaluate(vals, y, c);
>     values[1] = vals[0];
>     y[0] = x[2][0];
>     y[1] = x[2][1];
>     f.evaluate(vals, y, c);
>     values[2] = vals[0];
>   }
>
>   /// Interpolate vertex values from dof values
>   virtual void interpolate_vertex_values(double* vertex_values,
>                                          const double* dof_values,
>                                          const ufc::cell& c) const
>   {
>     // Evaluate function and change variables
>     vertex_values[0] = dof_values[0];
>     vertex_values[1] = dof_values[1];
>     vertex_values[2] = dof_values[2];
>   }
>
>   /// Return the number of sub elements (for a mixed element)
>   virtual unsigned int num_sub_elements() const
>   {
>     return 0;
>   }
>
>   /// Create a new finite element for sub element i (for a mixed element)
>   virtual ufc::finite_element* create_sub_element(unsigned int i) const
>   {
>     return 0;
>   }
>
> };
>
> /// This class defines the interface for a finite element.
>
> class poisson_finite_element_1: public ufc::finite_element
> {
> public:
>
>   /// Constructor
>   poisson_finite_element_1() : ufc::finite_element()
>   {
>     // Do nothing
>   }
>
>   /// Destructor
>   virtual ~poisson_finite_element_1()
>   {
>     // Do nothing
>   }
>
>   /// Return a string identifying the finite element
>   virtual const char* signature() const
>   {
>     return "EnrichedElement(FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), ElementRestriction(FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), Measure('surface', 0, None)))";
>   }
>
>   /// Return the cell shape
>   virtual ufc::shape cell_shape() const
>   {
>     return ufc::triangle;
>   }
>
>   /// Return the dimension of the finite element function space
>   virtual unsigned int space_dimension() const
>   {
>     return 6;
>   }
>
>   /// Return the rank of the value space
>   virtual unsigned int value_rank() const
>   {
>     return 0;
>   }
>
>   /// Return the dimension of the value space for axis i
>   virtual unsigned int value_dimension(unsigned int i) const
>   {
>     return 1;
>   }
>
>   /// Evaluate basis function i at given point in cell
>   virtual void evaluate_basis(unsigned int i,
>                               double* values,
>                               const double* coordinates,
>                               const ufc::cell& c) const
>   {
>     // Extract vertex coordinates
>     const double * const * x = c.coordinates;
>
>     // Compute Jacobian of affine map from reference cell
>     const double J_00 = x[1][0] - x[0][0];
>     const double J_01 = x[2][0] - x[0][0];
>     const double J_10 = x[1][1] - x[0][1];
>     const double J_11 = x[2][1] - x[0][1];
>
>     // Compute determinant of Jacobian
>     double detJ = J_00*J_11 - J_01*J_10;
>
>     // Compute inverse of Jacobian
>
>     // Compute constants
>     const double C0 = x[1][0] + x[2][0];
>     const double C1 = x[1][1] + x[2][1];
>
>     // Get coordinates and map to the reference (FIAT) element
>     double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ;
>     double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ;
>
>     // Reset values.
>     values[0] = 0.000000000000000;
>     values[1] = 0.000000000000000;
>     if (0 <= i && i <= 2)
>     {
>       // Map degree of freedom to element degree of freedom
>       const unsigned int dof = i;
>
>       // Array of basisvalues.
>       double basisvalues[3] = {0.000000000000000, 0.000000000000000, 0.000000000000000};
>
>       // Declare helper variables.
>       unsigned int rr = 0;
>       unsigned int ss = 0;
>       double tmp0 = (1.000000000000000 + Y + 2.000000000000000*X)/2.000000000000000;
>
>       // Compute basisvalues.
>       basisvalues[0] = 1.000000000000000;
>       basisvalues[1] = tmp0;
>       for (unsigned int r = 0; r < 1; r++)
>       {
>         rr = (r + 1)*(r + 1 + 1)/2 + 1;
>         ss = r*(r + 1)/2;
>         basisvalues[rr] = basisvalues[ss]*(0.500000000000000 + r + Y*(1.500000000000000 + r));
>       }// end loop over 'r'
>       for (unsigned int r = 0; r < 2; r++)
>       {
>         for (unsigned int s = 0; s < 2 - r; s++)
>         {
>           rr = (r + s)*(r + s + 1)/2 + s;
>           basisvalues[rr] *= std::sqrt((0.500000000000000 + r)*(1.000000000000000 + r + s));
>         }// end loop over 's'
>       }// end loop over 'r'
>
>       // Table(s) of coefficients.
>       static const double coefficients0[3][3] = \
>       {{0.471404520791032, -0.288675134594813, -0.166666666666667},
>       {0.471404520791032, 0.288675134594813, -0.166666666666667},
>       {0.471404520791032, 0.000000000000000, 0.333333333333333}};
>
>       // Compute value(s).
>       for (unsigned int r = 0; r < 3; r++)
>       {
>         values[0] += coefficients0[dof][r]*basisvalues[r];
>       }// end loop over 'r'
>     }
>
>     if (3 <= i && i <= 5)
>     {
>       // Map degree of freedom to element degree of freedom
>       const unsigned int dof = i - 3;
>
>       // Array of basisvalues.
>       double basisvalues[3] = {0.000000000000000, 0.000000000000000, 0.000000000000000};
>
>       // Declare helper variables.
>       unsigned int rr = 0;
>       unsigned int ss = 0;
>       double tmp0 = (1.000000000000000 + Y + 2.000000000000000*X)/2.000000000000000;
>
>       // Compute basisvalues.
>       basisvalues[0] = 1.000000000000000;
>       basisvalues[1] = tmp0;
>       for (unsigned int r = 0; r < 1; r++)
>       {
>         rr = (r + 1)*(r + 1 + 1)/2 + 1;
>         ss = r*(r + 1)/2;
>         basisvalues[rr] = basisvalues[ss]*(0.500000000000000 + r + Y*(1.500000000000000 + r));
>       }// end loop over 'r'
>       for (unsigned int r = 0; r < 2; r++)
>       {
>         for (unsigned int s = 0; s < 2 - r; s++)
>         {
>           rr = (r + s)*(r + s + 1)/2 + s;
>           basisvalues[rr] *= std::sqrt((0.500000000000000 + r)*(1.000000000000000 + r + s));
>         }// end loop over 's'
>       }// end loop over 'r'
>
>       // Table(s) of coefficients.
>       static const double coefficients0[3][3] = \
>       {{0.471404520791032, -0.288675134594813, -0.166666666666667},
>       {0.471404520791032, 0.288675134594813, -0.166666666666667},
>       {0.471404520791032, 0.000000000000000, 0.333333333333333}};
>
>       // Compute value(s).
>       for (unsigned int r = 0; r < 3; r++)
>       {
>         values[1] += coefficients0[dof][r]*basisvalues[r];
>       }// end loop over 'r'
>     }
>
>   }
>
>   /// Evaluate all basis functions at given point in cell
>   virtual void evaluate_basis_all(double* values,
>                                   const double* coordinates,
>                                   const ufc::cell& c) const
>   {
>     // Helper variable to hold values of a single dof.
>     double dof_values[2] = {0.000000000000000, 0.000000000000000};
>
>     // Loop dofs and call evaluate_basis.
>     for (unsigned int r = 0; r < 6; r++)
>     {
>       evaluate_basis(r, dof_values, coordinates, c);
>       for (unsigned int s = 0; s < 2; s++)
>       {
>         values[r*2 + s] = dof_values[s];
>       }// end loop over 's'
>     }// end loop over 'r'
>   }
>
>   /// Evaluate order n derivatives of basis function i at given point in cell
>   virtual void evaluate_basis_derivatives(unsigned int i,
>                                           unsigned int n,
>                                           double* values,
>                                           const double* coordinates,
>                                           const ufc::cell& c) const
>   {
>     // Extract vertex coordinates
>     const double * const * x = c.coordinates;
>
>     // Compute Jacobian of affine map from reference cell
>     const double J_00 = x[1][0] - x[0][0];
>     const double J_01 = x[2][0] - x[0][0];
>     const double J_10 = x[1][1] - x[0][1];
>     const double J_11 = x[2][1] - x[0][1];
>
>     // Compute determinant of Jacobian
>     double detJ = J_00*J_11 - J_01*J_10;
>
>     // Compute inverse of Jacobian
>     const double K_00 =  J_11 / detJ;
>     const double K_01 = -J_01 / detJ;
>     const double K_10 = -J_10 / detJ;
>     const double K_11 =  J_00 / detJ;
>
>     // Compute constants
>     const double C0 = x[1][0] + x[2][0];
>     const double C1 = x[1][1] + x[2][1];
>
>     // Get coordinates and map to the reference (FIAT) element
>     double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ;
>     double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ;
>
>     // Compute number of derivatives.
>     unsigned int num_derivatives = 1;
>     for (unsigned int r = 0; r < n; r++)
>     {
>       num_derivatives *= 2;
>     }// end loop over 'r'
>
>     // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
>     unsigned int **combinations = new unsigned int *[num_derivatives];
>     for (unsigned int row = 0; row < num_derivatives; row++)
>     {
>       combinations[row] = new unsigned int [n];
>       for (unsigned int col = 0; col < n; col++)
>         combinations[row][col] = 0;
>     }
>
>     // Generate combinations of derivatives
>     for (unsigned int row = 1; row < num_derivatives; row++)
>     {
>       for (unsigned int num = 0; num < row; num++)
>       {
>         for (unsigned int col = n-1; col+1 > 0; col--)
>         {
>           if (combinations[row][col] + 1 > 1)
>             combinations[row][col] = 0;
>           else
>           {
>             combinations[row][col] += 1;
>             break;
>           }
>         }
>       }
>     }
>
>     // Compute inverse of Jacobian
>     const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}};
>
>     // Declare transformation matrix
>     // Declare pointer to two dimensional array and initialise
>     double **transform = new double *[num_derivatives];
>
>     for (unsigned int j = 0; j < num_derivatives; j++)
>     {
>       transform[j] = new double [num_derivatives];
>       for (unsigned int k = 0; k < num_derivatives; k++)
>         transform[j][k] = 1;
>     }
>
>     // Construct transformation matrix
>     for (unsigned int row = 0; row < num_derivatives; row++)
>     {
>       for (unsigned int col = 0; col < num_derivatives; col++)
>       {
>         for (unsigned int k = 0; k < n; k++)
>           transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
>       }
>     }
>
>     // Reset values. Assuming that values is always an array.
>     for (unsigned int r = 0; r < 2*num_derivatives; r++)
>     {
>       values[r] = 0.000000000000000;
>     }// end loop over 'r'
>
>     if (0 <= i && i <= 2)
>     {
>       // Map degree of freedom to element degree of freedom
>       const unsigned int dof = i;
>
>       // Array of basisvalues.
>       double basisvalues[3] = {0.000000000000000, 0.000000000000000, 0.000000000000000};
>
>       // Declare helper variables.
>       unsigned int rr = 0;
>       unsigned int ss = 0;
>       double tmp0 = (1.000000000000000 + Y + 2.000000000000000*X)/2.000000000000000;
>
>       // Compute basisvalues.
>       basisvalues[0] = 1.000000000000000;
>       basisvalues[1] = tmp0;
>       for (unsigned int r = 0; r < 1; r++)
>       {
>         rr = (r + 1)*(r + 1 + 1)/2 + 1;
>         ss = r*(r + 1)/2;
>         basisvalues[rr] = basisvalues[ss]*(0.500000000000000 + r + Y*(1.500000000000000 + r));
>       }// end loop over 'r'
>       for (unsigned int r = 0; r < 2; r++)
>       {
>         for (unsigned int s = 0; s < 2 - r; s++)
>         {
>           rr = (r + s)*(r + s + 1)/2 + s;
>           basisvalues[rr] *= std::sqrt((0.500000000000000 + r)*(1.000000000000000 + r + s));
>         }// end loop over 's'
>       }// end loop over 'r'
>
>       // Table(s) of coefficients.
>       static const double coefficients0[3][3] = \
>       {{0.471404520791032, -0.288675134594813, -0.166666666666667},
>       {0.471404520791032, 0.288675134594813, -0.166666666666667},
>       {0.471404520791032, 0.000000000000000, 0.333333333333333}};
>
>       // Tables of derivatives of the polynomial base (transpose).
>       static const double dmats0[3][3] = \
>       {{0.000000000000000, 0.000000000000000, 0.000000000000000},
>       {4.898979485566356, 0.000000000000000, 0.000000000000000},
>       {0.000000000000000, 0.000000000000000, 0.000000000000000}};
>
>       static const double dmats1[3][3] = \
>       {{0.000000000000000, 0.000000000000000, 0.000000000000000},
>       {2.449489742783178, 0.000000000000000, 0.000000000000000},
>       {4.242640687119285, 0.000000000000000, 0.000000000000000}};
>
>       // Compute reference derivatives.
>       // Declare pointer to array of derivatives on FIAT element.
>       double *derivatives = new double[num_derivatives];
>       for (unsigned int r = 0; r < num_derivatives; r++)
>       {
>         derivatives[r] = 0.000000000000000;
>       }// end loop over 'r'
>
>       // Declare derivative matrix (of polynomial basis).
>       double dmats[3][3] = \
>       {{1.000000000000000, 0.000000000000000, 0.000000000000000},
>       {0.000000000000000, 1.000000000000000, 0.000000000000000},
>       {0.000000000000000, 0.000000000000000, 1.000000000000000}};
>
>       // Declare (auxiliary) derivative matrix (of polynomial basis).
>       double dmats_old[3][3] = \
>       {{1.000000000000000, 0.000000000000000, 0.000000000000000},
>       {0.000000000000000, 1.000000000000000, 0.000000000000000},
>       {0.000000000000000, 0.000000000000000, 1.000000000000000}};
>
>       // Loop possible derivatives.
>       for (unsigned int r = 0; r < num_derivatives; r++)
>       {
>         // Resetting dmats values to compute next derivative.
>         for (unsigned int t = 0; t < 3; t++)
>         {
>           for (unsigned int u = 0; u < 3; u++)
>           {
>             dmats[t][u] = 0.000000000000000;
>             if (t == u)
>             {
>             dmats[t][u] = 1.000000000000000;
>             }
>
>           }// end loop over 'u'
>         }// end loop over 't'
>
>         // Looping derivative order to generate dmats.
>         for (unsigned int s = 0; s < n; s++)
>         {
>           // Updating dmats_old with new values and resetting dmats.
>           for (unsigned int t = 0; t < 3; t++)
>           {
>             for (unsigned int u = 0; u < 3; u++)
>             {
>               dmats_old[t][u] = dmats[t][u];
>               dmats[t][u] = 0.000000000000000;
>             }// end loop over 'u'
>           }// end loop over 't'
>
>           // Update dmats using an inner product.
>           if (combinations[r][s] == 0)
>           {
>           for (unsigned int t = 0; t < 3; t++)
>           {
>             for (unsigned int u = 0; u < 3; u++)
>             {
>               for (unsigned int tu = 0; tu < 3; tu++)
>               {
>                 dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
>               }// end loop over 'tu'
>             }// end loop over 'u'
>           }// end loop over 't'
>           }
>
>           if (combinations[r][s] == 1)
>           {
>           for (unsigned int t = 0; t < 3; t++)
>           {
>             for (unsigned int u = 0; u < 3; u++)
>             {
>               for (unsigned int tu = 0; tu < 3; tu++)
>               {
>                 dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
>               }// end loop over 'tu'
>             }// end loop over 'u'
>           }// end loop over 't'
>           }
>
>         }// end loop over 's'
>         for (unsigned int s = 0; s < 3; s++)
>         {
>           for (unsigned int t = 0; t < 3; t++)
>           {
>             derivatives[r] += coefficients0[dof][s]*dmats[s][t]*basisvalues[t];
>           }// end loop over 't'
>         }// end loop over 's'
>       }// end loop over 'r'
>
>       // Transform derivatives back to physical element
>       for (unsigned int r = 0; r < num_derivatives; r++)
>       {
>         for (unsigned int s = 0; s < num_derivatives; s++)
>         {
>           values[r] += transform[r][s]*derivatives[s];
>         }// end loop over 's'
>       }// end loop over 'r'
>
>       // Delete pointer to array of derivatives on FIAT element
>       delete [] derivatives;
>
>       // Delete pointer to array of combinations of derivatives and transform
>       for (unsigned int r = 0; r < num_derivatives; r++)
>       {
>         delete [] combinations[r];
>       }// end loop over 'r'
>       delete [] combinations;
>       for (unsigned int r = 0; r < num_derivatives; r++)
>       {
>         delete [] transform[r];
>       }// end loop over 'r'
>       delete [] transform;
>     }
>
>     if (3 <= i && i <= 5)
>     {
>       // Map degree of freedom to element degree of freedom
>       const unsigned int dof = i - 3;
>
>       // Array of basisvalues.
>       double basisvalues[3] = {0.000000000000000, 0.000000000000000, 0.000000000000000};
>
>       // Declare helper variables.
>       unsigned int rr = 0;
>       unsigned int ss = 0;
>       double tmp0 = (1.000000000000000 + Y + 2.000000000000000*X)/2.000000000000000;
>
>       // Compute basisvalues.
>       basisvalues[0] = 1.000000000000000;
>       basisvalues[1] = tmp0;
>       for (unsigned int r = 0; r < 1; r++)
>       {
>         rr = (r + 1)*(r + 1 + 1)/2 + 1;
>         ss = r*(r + 1)/2;
>         basisvalues[rr] = basisvalues[ss]*(0.500000000000000 + r + Y*(1.500000000000000 + r));
>       }// end loop over 'r'
>       for (unsigned int r = 0; r < 2; r++)
>       {
>         for (unsigned int s = 0; s < 2 - r; s++)
>         {
>           rr = (r + s)*(r + s + 1)/2 + s;
>           basisvalues[rr] *= std::sqrt((0.500000000000000 + r)*(1.000000000000000 + r + s));
>         }// end loop over 's'
>       }// end loop over 'r'
>
>       // Table(s) of coefficients.
>       static const double coefficients0[3][3] = \
>       {{0.471404520791032, -0.288675134594813, -0.166666666666667},
>       {0.471404520791032, 0.288675134594813, -0.166666666666667},
>       {0.471404520791032, 0.000000000000000, 0.333333333333333}};
>
>       // Tables of derivatives of the polynomial base (transpose).
>       static const double dmats0[3][3] = \
>       {{0.000000000000000, 0.000000000000000, 0.000000000000000},
>       {4.898979485566356, 0.000000000000000, 0.000000000000000},
>       {0.000000000000000, 0.000000000000000, 0.000000000000000}};
>
>       static const double dmats1[3][3] = \
>       {{0.000000000000000, 0.000000000000000, 0.000000000000000},
>       {2.449489742783178, 0.000000000000000, 0.000000000000000},
>       {4.242640687119285, 0.000000000000000, 0.000000000000000}};
>
>       // Compute reference derivatives.
>       // Declare pointer to array of derivatives on FIAT element.
>       double *derivatives = new double[num_derivatives];
>       for (unsigned int r = 0; r < num_derivatives; r++)
>       {
>         derivatives[r] = 0.000000000000000;
>       }// end loop over 'r'
>
>       // Declare derivative matrix (of polynomial basis).
>       double dmats[3][3] = \
>       {{1.000000000000000, 0.000000000000000, 0.000000000000000},
>       {0.000000000000000, 1.000000000000000, 0.000000000000000},
>       {0.000000000000000, 0.000000000000000, 1.000000000000000}};
>
>       // Declare (auxiliary) derivative matrix (of polynomial basis).
>       double dmats_old[3][3] = \
>       {{1.000000000000000, 0.000000000000000, 0.000000000000000},
>       {0.000000000000000, 1.000000000000000, 0.000000000000000},
>       {0.000000000000000, 0.000000000000000, 1.000000000000000}};
>
>       // Loop possible derivatives.
>       for (unsigned int r = 0; r < num_derivatives; r++)
>       {
>         // Resetting dmats values to compute next derivative.
>         for (unsigned int t = 0; t < 3; t++)
>         {
>           for (unsigned int u = 0; u < 3; u++)
>           {
>             dmats[t][u] = 0.000000000000000;
>             if (t == u)
>             {
>             dmats[t][u] = 1.000000000000000;
>             }
>
>           }// end loop over 'u'
>         }// end loop over 't'
>
>         // Looping derivative order to generate dmats.
>         for (unsigned int s = 0; s < n; s++)
>         {
>           // Updating dmats_old with new values and resetting dmats.
>           for (unsigned int t = 0; t < 3; t++)
>           {
>             for (unsigned int u = 0; u < 3; u++)
>             {
>               dmats_old[t][u] = dmats[t][u];
>               dmats[t][u] = 0.000000000000000;
>             }// end loop over 'u'
>           }// end loop over 't'
>
>           // Update dmats using an inner product.
>           if (combinations[r][s] == 0)
>           {
>           for (unsigned int t = 0; t < 3; t++)
>           {
>             for (unsigned int u = 0; u < 3; u++)
>             {
>               for (unsigned int tu = 0; tu < 3; tu++)
>               {
>                 dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
>               }// end loop over 'tu'
>             }// end loop over 'u'
>           }// end loop over 't'
>           }
>
>           if (combinations[r][s] == 1)
>           {
>           for (unsigned int t = 0; t < 3; t++)
>           {
>             for (unsigned int u = 0; u < 3; u++)
>             {
>               for (unsigned int tu = 0; tu < 3; tu++)
>               {
>                 dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
>               }// end loop over 'tu'
>             }// end loop over 'u'
>           }// end loop over 't'
>           }
>
>         }// end loop over 's'
>         for (unsigned int s = 0; s < 3; s++)
>         {
>           for (unsigned int t = 0; t < 3; t++)
>           {
>             derivatives[r] += coefficients0[dof][s]*dmats[s][t]*basisvalues[t];
>           }// end loop over 't'
>         }// end loop over 's'
>       }// end loop over 'r'
>
>       // Transform derivatives back to physical element
>       for (unsigned int r = 0; r < num_derivatives; r++)
>       {
>         for (unsigned int s = 0; s < num_derivatives; s++)
>         {
>           values[num_derivatives + r] += transform[r][s]*derivatives[s];
>         }// end loop over 's'
>       }// end loop over 'r'
>
>       // Delete pointer to array of derivatives on FIAT element
>       delete [] derivatives;
>
>       // Delete pointer to array of combinations of derivatives and transform
>       for (unsigned int r = 0; r < num_derivatives; r++)
>       {
>         delete [] combinations[r];
>       }// end loop over 'r'
>       delete [] combinations;
>       for (unsigned int r = 0; r < num_derivatives; r++)
>       {
>         delete [] transform[r];
>       }// end loop over 'r'
>       delete [] transform;
>     }
>
>   }
>
>   /// Evaluate order n derivatives of all basis functions at given point in cell
>   virtual void evaluate_basis_derivatives_all(unsigned int n,
>                                               double* values,
>                                               const double* coordinates,
>                                               const ufc::cell& c) const
>   {
>     // Compute number of derivatives.
>     unsigned int num_derivatives = 1;
>     for (unsigned int r = 0; r < n; r++)
>     {
>       num_derivatives *= 2;
>     }// end loop over 'r'
>
>     // Helper variable to hold values of a single dof.
>     double *dof_values = new double[2*num_derivatives];
>     for (unsigned int r = 0; r < 2*num_derivatives; r++)
>     {
>       dof_values[r] = 0.000000000000000;
>     }// end loop over 'r'
>
>     // Loop dofs and call evaluate_basis_derivatives.
>     for (unsigned int r = 0; r < 6; r++)
>     {
>       evaluate_basis_derivatives(r, n, dof_values, coordinates, c);
>       for (unsigned int s = 0; s < 2*num_derivatives; s++)
>       {
>         values[r*2*num_derivatives + s] = dof_values[s];
>       }// end loop over 's'
>     }// end loop over 'r'
>
>     // Delete pointer.
>     delete [] dof_values;
>   }
>
>   /// Evaluate linear functional for dof i on the function f
>   virtual double evaluate_dof(unsigned int i,
>                               const ufc::function& f,
>                               const ufc::cell& c) const
>   {
>     // Declare variables for result of evaluation.
>     double vals[1];
>
>     // Declare variable for physical coordinates.
>     double y[2];
>     const double * const * x = c.coordinates;
>     switch (i)
>     {
>     case 0:
>       {
>         y[0] = x[0][0];
>       y[1] = x[0][1];
>       f.evaluate(vals, y, c);
>       return vals[0];
>         break;
>       }
>     case 1:
>       {
>         y[0] = x[1][0];
>       y[1] = x[1][1];
>       f.evaluate(vals, y, c);
>       return vals[0];
>         break;
>       }
>     case 2:
>       {
>         y[0] = x[2][0];
>       y[1] = x[2][1];
>       f.evaluate(vals, y, c);
>       return vals[0];
>         break;
>       }
>     case 3:
>       {
>         y[0] = x[0][0];
>       y[1] = x[0][1];
>       f.evaluate(vals, y, c);
>       return vals[0];
>         break;
>       }
>     case 4:
>       {
>         y[0] = x[1][0];
>       y[1] = x[1][1];
>       f.evaluate(vals, y, c);
>       return vals[0];
>         break;
>       }
>     case 5:
>       {
>         y[0] = x[2][0];
>       y[1] = x[2][1];
>       f.evaluate(vals, y, c);
>       return vals[0];
>         break;
>       }
>     }
>
>     return 0.000000000000000;
>   }
>
>   /// Evaluate linear functionals for all dofs on the function f
>   virtual void evaluate_dofs(double* values,
>                              const ufc::function& f,
>                              const ufc::cell& c) const
>   {
>     // Declare variables for result of evaluation.
>     double vals[1];
>
>     // Declare variable for physical coordinates.
>     double y[2];
>     const double * const * x = c.coordinates;
>     y[0] = x[0][0];
>     y[1] = x[0][1];
>     f.evaluate(vals, y, c);
>     values[0] = vals[0];
>     y[0] = x[1][0];
>     y[1] = x[1][1];
>     f.evaluate(vals, y, c);
>     values[1] = vals[0];
>     y[0] = x[2][0];
>     y[1] = x[2][1];
>     f.evaluate(vals, y, c);
>     values[2] = vals[0];
>     y[0] = x[0][0];
>     y[1] = x[0][1];
>     f.evaluate(vals, y, c);
>     values[3] = vals[0];
>     y[0] = x[1][0];
>     y[1] = x[1][1];
>     f.evaluate(vals, y, c);
>     values[4] = vals[0];
>     y[0] = x[2][0];
>     y[1] = x[2][1];
>     f.evaluate(vals, y, c);
>     values[5] = vals[0];
>   }
>
>   /// Interpolate vertex values from dof values
>   virtual void interpolate_vertex_values(double* vertex_values,
>                                          const double* dof_values,
>                                          const ufc::cell& c) const
>   {
>     // Evaluate function and change variables
>     vertex_values[0] = dof_values[0] + dof_values[3];
>     vertex_values[1] = dof_values[1] + dof_values[4];
>     vertex_values[2] = dof_values[2] + dof_values[5];
>   }
>
>   /// Return the number of sub elements (for a mixed element)
>   virtual unsigned int num_sub_elements() const
>   {
>     return 0;
>   }
>
>   /// Create a new finite element for sub element i (for a mixed element)
>   virtual ufc::finite_element* create_sub_element(unsigned int i) const
>   {
>     return 0;
>   }
>
> };
>
> /// This class defines the interface for a local-to-global mapping of
> /// degrees of freedom (dofs).
>
>
> class poisson_dof_map_0: public ufc::dof_map
> {
> private:
>
>   unsigned int _global_dimension;
>
> public:
>
>   /// Constructor
>   poisson_dof_map_0(    ) :ufc::dof_map()
>   {
>     _global_dimension = 0;
>   }
>   /// Destructor
>   virtual ~poisson_dof_map_0()
>   {
>     // Do nothing
>   }
>
>   /// Return a string identifying the dof map
>   virtual const char* signature() const
>   {
>     return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)";
>   }
>
>   /// Return true iff mesh entities of topological dimension d are needed
>   virtual bool needs_mesh_entities(unsigned int d) const
>   {
>     switch (d)
>     {
>     case 0:
>       {
>         return true;
>         break;
>       }
>     case 1:
>       {
>         return false;
>         break;
>       }
>     case 2:
>       {
>         return false;
>         break;
>       }
>     }
>
>     return false;
>   }
>
>   /// Initialize dof map for mesh (return true iff init_cell() is needed)
>   virtual bool init_mesh(const ufc::mesh& m)
>   {
>     _global_dimension = m.num_entities[0];
>     return false;
>   }
>
>   /// Initialize dof map for given cell
>   virtual void init_cell(const ufc::mesh& m,
>                          const ufc::cell& c)
>   {
>     // Do nothing
>   }
>
>   /// Finish initialization of dof map for cells
>   virtual void init_cell_finalize()
>   {
>     // Do nothing
>   }
>
>   /// Return the dimension of the global finite element function space
>   virtual unsigned int global_dimension() const
>   {
>     return _global_dimension;
>   }
>
>   /// Return the dimension of the local finite element function space for a cell
>   virtual unsigned int local_dimension(const ufc::cell& c) const
>   {
>     return 3;
>   }
>
>   /// Return the maximum dimension of the local finite element function space
>   virtual unsigned int max_local_dimension() const
>   {
>     return 3;
>   }
>
>
>   // Return the geometric dimension of the coordinates this dof map provides
>   virtual unsigned int geometric_dimension() const
>   {
>     return 2;
>   }
>
>   /// Return the number of dofs on each cell facet
>   virtual unsigned int num_facet_dofs() const
>   {
>     return 2;
>   }
>
>   /// Return the number of dofs associated with each cell entity of dimension d
>   virtual unsigned int num_entity_dofs(unsigned int d) const
>   {
>     switch (d)
>     {
>     case 0:
>       {
>         return 1;
>         break;
>       }
>     case 1:
>       {
>         return 0;
>         break;
>       }
>     case 2:
>       {
>         return 0;
>         break;
>       }
>     }
>
>     return 0;
>   }
>
>   /// Tabulate the local-to-global mapping of dofs on a cell
>   virtual void tabulate_dofs(unsigned int* dofs,
>                              const ufc::mesh& m,
>                              const ufc::cell& c) const
>   {
>     dofs[0] = c.entity_indices[0][0];
>     dofs[1] = c.entity_indices[0][1];
>     dofs[2] = c.entity_indices[0][2];
>   }
>
>   /// Tabulate the local-to-local mapping from facet dofs to cell dofs
>   virtual void tabulate_facet_dofs(unsigned int* dofs,
>                                    unsigned int facet) const
>   {
>     switch (facet)
>     {
>     case 0:
>       {
>         dofs[0] = 1;
>       dofs[1] = 2;
>         break;
>       }
>     case 1:
>       {
>         dofs[0] = 0;
>       dofs[1] = 2;
>         break;
>       }
>     case 2:
>       {
>         dofs[0] = 0;
>       dofs[1] = 1;
>         break;
>       }
>     }
>
>   }
>
>   /// Tabulate the local-to-local mapping of dofs on entity (d, i)
>   virtual void tabulate_entity_dofs(unsigned int* dofs,
>                                     unsigned int d, unsigned int i) const
>   {
>     if (d > 2)
>     {
>     throw std::runtime_error("d is larger than dimension (2)");
>     }
>
>     switch (d)
>     {
>     case 0:
>       {
>         if (i > 2)
>       {
>       throw std::runtime_error("i is larger than number of entities (2)");
>       }
>
>       switch (i)
>       {
>       case 0:
>         {
>           dofs[0] = 0;
>           break;
>         }
>       case 1:
>         {
>           dofs[0] = 1;
>           break;
>         }
>       case 2:
>         {
>           dofs[0] = 2;
>           break;
>         }
>       }
>
>         break;
>       }
>     case 1:
>       {
>
>         break;
>       }
>     case 2:
>       {
>
>         break;
>       }
>     }
>
>   }
>
>   /// Tabulate the coordinates of all dofs on a cell
>   virtual void tabulate_coordinates(double** coordinates,
>                                     const ufc::cell& c) const
>   {
>     const double * const * x = c.coordinates;
>
>     coordinates[0][0] = x[0][0];
>     coordinates[0][1] = x[0][1];
>     coordinates[1][0] = x[1][0];
>     coordinates[1][1] = x[1][1];
>     coordinates[2][0] = x[2][0];
>     coordinates[2][1] = x[2][1];
>   }
>
>   /// Return the number of sub dof maps (for a mixed element)
>   virtual unsigned int num_sub_dof_maps() const
>   {
>     return 0;
>   }
>
>   /// Create a new dof_map for sub dof map i (for a mixed element)
>   virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
>   {
>     return 0;
>   }
>
> };
>
> /// This class defines the interface for a local-to-global mapping of
> /// degrees of freedom (dofs).
>
>
> class poisson_dof_map_1: public ufc::dof_map
> {
> private:
>
>   unsigned int _global_dimension;
>   const std::vector<const pum::GenericPUM*>& pums;
> public:
>
>   /// Constructor
>   poisson_dof_map_1(    const std::vector<const pum::GenericPUM*>& pums) :ufc::dof_map()    , pums(pums)
>   {
>     _global_dimension = 0;
>   }
>   /// Destructor
>   virtual ~poisson_dof_map_1()
>   {
>     // Do nothing
>   }
>
>   /// Return a string identifying the dof map
>   virtual const char* signature() const
>   {
>     return "FFC dofmap for EnrichedElement(FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), ElementRestriction(FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), Measure('surface', 0, None)))";
>   }
>
>   /// Return true iff mesh entities of topological dimension d are needed
>   virtual bool needs_mesh_entities(unsigned int d) const
>   {
>     switch (d)
>     {
>     case 0:
>       {
>         return true;
>         break;
>       }
>     case 1:
>       {
>         return false;
>         break;
>       }
>     case 2:
>       {
>         return false;
>         break;
>       }
>     }
>
>     return false;
>   }
>
>   /// Initialize dof map for mesh (return true iff init_cell() is needed)
>   virtual bool init_mesh(const ufc::mesh& m)
>   {
>     _global_dimension = m.num_entities[0];
>     return false;
>   }
>
>   /// Initialize dof map for given cell
>   virtual void init_cell(const ufc::mesh& m,
>                          const ufc::cell& c)
>   {
>     // Do nothing
>   }
>
>   /// Finish initialization of dof map for cells
>   virtual void init_cell_finalize()
>   {
>     // Do nothing
>   }
>
>   /// Return the dimension of the global finite element function space
>   virtual unsigned int global_dimension() const
>   {
>     return _global_dimension + pums[0]->enriched_global_dimension();
>   }
>
>   /// Return the dimension of the local finite element function space for a cell
>   virtual unsigned int local_dimension(const ufc::cell& c) const
>   {
>     return 3 + pums[0]->enriched_local_dimension(c);
>   }
>
>   /// Return the maximum dimension of the local finite element function space
>   virtual unsigned int max_local_dimension() const
>   {
>     return 3 + pums[0]->enriched_max_local_dimension();
>   }
>
>
>   // Return the geometric dimension of the coordinates this dof map provides
>   virtual unsigned int geometric_dimension() const
>   {
>     return 2;
>   }
>
>   /// Return the number of dofs on each cell facet
>   virtual unsigned int num_facet_dofs() const
>   {
>     return 2;
>   }
>
>   /// Return the number of dofs associated with each cell entity of dimension d
>   virtual unsigned int num_entity_dofs(unsigned int d) const
>   {
>     switch (d)
>     {
>     case 0:
>       {
>         return 1;
>         break;
>       }
>     case 1:
>       {
>         return 0;
>         break;
>       }
>     case 2:
>       {
>         return 0;
>         break;
>       }
>     }
>
>     return 0;
>   }
>
>   /// Tabulate the local-to-global mapping of dofs on a cell
>   virtual void tabulate_dofs(unsigned int* dofs,
>                              const ufc::mesh& m,
>                              const ufc::cell& c) const
>   {
>     dofs[0] = c.entity_indices[0][0];
>     dofs[1] = c.entity_indices[0][1];
>     dofs[2] = c.entity_indices[0][2];
>     \
>
>     // Generate code for tabulating extra degrees of freedom.
>     unsigned int local_offset = 3;
>     unsigned int global_offset = m.num_entities[0];
>
>     // Calculate local-to-global mapping for the enriched dofs related to the discontinuous field 0
>     pums[0]->tabulate_enriched_dofs(dofs, c, local_offset, global_offset);
>   }
>
>   /// Tabulate the local-to-local mapping from facet dofs to cell dofs
>   virtual void tabulate_facet_dofs(unsigned int* dofs,
>                                    unsigned int facet) const
>   {
>     switch (facet)
>     {
>     case 0:
>       {
>         dofs[0] = 1;
>       dofs[1] = 2;
>         break;
>       }
>     case 1:
>       {
>         dofs[0] = 0;
>       dofs[1] = 2;
>         break;
>       }
>     case 2:
>       {
>         dofs[0] = 0;
>       dofs[1] = 1;
>         break;
>       }
>     }
>
>   }
>
>   /// Tabulate the local-to-local mapping of dofs on entity (d, i)
>   virtual void tabulate_entity_dofs(unsigned int* dofs,
>                                     unsigned int d, unsigned int i) const
>   {
>     if (d > 2)
>     {
>     throw std::runtime_error("d is larger than dimension (2)");
>     }
>
>     switch (d)
>     {
>     case 0:
>       {
>         if (i > 2)
>       {
>       throw std::runtime_error("i is larger than number of entities (2)");
>       }
>
>       switch (i)
>       {
>       case 0:
>         {
>           dofs[0] = 0;
>           break;
>         }
>       case 1:
>         {
>           dofs[0] = 1;
>           break;
>         }
>       case 2:
>         {
>           dofs[0] = 2;
>           break;
>         }
>       }
>
>         break;
>       }
>     case 1:
>       {
>
>         break;
>       }
>     case 2:
>       {
>
>         break;
>       }
>     }
>
>   }
>
>   /// Tabulate the coordinates of all dofs on a cell
>   virtual void tabulate_coordinates(double** coordinates,
>                                     const ufc::cell& c) const
>   {
>     const double * const * x = c.coordinates;
>
>     coordinates[0][0] = x[0][0];
>     coordinates[0][1] = x[0][1];
>     coordinates[1][0] = x[1][0];
>     coordinates[1][1] = x[1][1];
>     coordinates[2][0] = x[2][0];
>     coordinates[2][1] = x[2][1];
>   }
>
>   /// Return the number of sub dof maps (for a mixed element)
>   virtual unsigned int num_sub_dof_maps() const
>   {
>     return 0;
>   }
>
>   /// Create a new dof_map for sub dof map i (for a mixed element)
>   virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
>   {
>     return 0;
>   }
>
> };
>
> /// This class defines the interface for the tabulation of the cell
> /// tensor corresponding to the local contribution to a form from
> /// the integral over a cell.
>
> class poisson_cell_integral_0_0: public ufc::cell_integral
> {
>   const std::vector<const pum::GenericPUM*>& pums;
>   mutable std::vector <double> Aa;
>
>   /// Tabulate the regular entities of tensor for the contribution from a local cell
>   virtual void tabulate_regular_tensor(double* A,
>                                        const double * const * w,
>                                        const ufc::cell& c) const
>   {
>     // Extract vertex coordinates
>     const double * const * x = c.coordinates;
>
>     // Compute Jacobian of affine map from reference cell
>     const double J_00 = x[1][0] - x[0][0];
>     const double J_01 = x[2][0] - x[0][0];
>     const double J_10 = x[1][1] - x[0][1];
>     const double J_11 = x[2][1] - x[0][1];
>
>     // Compute determinant of Jacobian
>     double detJ = J_00*J_11 - J_01*J_10;
>
>     // Compute inverse of Jacobian
>     const double K_00 =  J_11 / detJ;
>     const double K_01 = -J_01 / detJ;
>     const double K_10 = -J_10 / detJ;
>     const double K_11 =  J_00 / detJ;
>
>     // Set scale factor
>     const double det = std::abs(detJ);
>
>     // Array of quadrature weights.
>     static const double W1 = 0.500000000000000;
>     // Quadrature points on the UFC reference element: (0.333333333333333, 0.333333333333333)
>
>     // Value of basis functions at quadrature points.
>     static const double FE0_D01[1][6] = \
>     {{-1.000000000000000, 0.000000000000000, 1.000000000000000, -1.000000000000000, 0.000000000000000, 1.000000000000000}};
>
>     static const double FE0_D10[1][6] = \
>     {{-1.000000000000000, 1.000000000000000, 0.000000000000000, -1.000000000000000, 1.000000000000000, 0.000000000000000}};
>
>     static const double FE1[1][3] = \
>     {{0.333333333333333, 0.333333333333333, 0.333333333333333}};
>
>
>     // enriched local dimension of the current cell
>     unsigned int offset = pums[0]->enriched_local_dimension(c);
>
>     // Reset values in the element tensor.
>     const unsigned int num_entries = (3 + offset)*(3 + offset);
>
>     for (unsigned int r = 0; r < num_entries; r++)
>     {
>       A[r] = 0.000000000000000;
>     }// end loop over 'r'
>
>     // Compute element tensor using UFL quadrature representation
>     // Optimisations: ('optimisation', False), ('non zero columns', False), ('remove zero terms', False), ('ignore ones', False), ('ignore zero tables', False)
>
>     // Loop quadrature points for integral.
>     // Number of operations to compute element tensor for following IP loop = 25
>     // Only 1 integration point, omitting IP loop.
>     // Coefficient declarations.
>     double F0 = 0.000000000000000;
>
>     // Total number of operations to compute function values = 6
>     for (unsigned int r = 0; r < 3; r++)
>     {
>       F0 += FE1[0][r]*w[0][r];
>     }// end loop over 'r'
>     unsigned int m = 0;
>
>     // Number of operations for primary indices = 19
>     for (unsigned int j = 0; j < 6; j++)
>     {
>       for (unsigned int k = 0; k < 6; k++)
>       {
>         // Number of operations to compute entry: 19
>         if (((((0 <= j && j < 3)) && ((0 <= k && k < 3)))))
>         {
>           A[m] += ((((K_00*FE0_D10[0][j] + K_10*FE0_D01[0][j]))*((K_00*FE0_D10[0][k] + K_10*FE0_D01[0][k])) + ((K_01*FE0_D10[0][j] + K_11*FE0_D01[0][j]))*((K_01*FE0_D10[0][k] + K_11*FE0_D01[0][k]))))*F0*W1*det;
>         ++m;
>         }
>
>       }// end loop over 'k'
>
>       // Offset the entries corresponding to enriched terms
>       if  ((((0 <= j && j < 3))))
>         m += offset;
>       }// end loop over 'j'
>   }
>
> public:
>
>   /// Constructor
>   poisson_cell_integral_0_0(    const std::vector<const pum::GenericPUM*>& pums) : ufc::cell_integral()    , pums(pums)
>   {
>     // Do nothing
>   }
>
>   /// Destructor
>   virtual ~poisson_cell_integral_0_0()
>   {
>     // Do nothing
>   }
>
>
>   /// Tabulate the tensor for the contribution from a local cell
>   virtual void tabulate_tensor(double* A,
>                                const double * const * w,
>                                const ufc::cell& c) const
>   {
>     // Tabulate regular entires of element tensor
>     tabulate_regular_tensor(A, w, c);
>
>
>     // enriched local dimension of the current cell(s)
>     unsigned int offset = pums[0]->enriched_local_dimension(c);
>
>     if (offset == 0)
>     {
>       return;
>     }
>
>
>     // Extract vertex coordinates
>     const double * const * x = c.coordinates;
>
>     // Compute Jacobian of affine map from reference cell
>     const double J_00 = x[1][0] - x[0][0];
>     const double J_01 = x[2][0] - x[0][0];
>     const double J_10 = x[1][1] - x[0][1];
>     const double J_11 = x[2][1] - x[0][1];
>
>     // Compute determinant of Jacobian
>     double detJ = J_00*J_11 - J_01*J_10;
>
>
>     // Set scale factor
>     const double det = std::abs(detJ);
>
>     // FIXME: It will crash for multiple discontinuities, if we don't have at least one cell which all dofs are enriched
>     const unsigned int min_entries = 36;
>     const unsigned int num_entries = std::max((offset + 3)*(offset + 3), min_entries);
>
>     // Resizing and reseting auxiliary tensors
>     Aa.resize(num_entries);
>     std::fill(Aa.begin(), Aa.end(), 0.0);
>
>     // Define an array to save current quadrature point
>     double coordinate[2];
>
>     // Define ufc::finite_element object(s) to evalaute shape functions or their derivatives on runtime
>     poisson_finite_element_0  element_0;
>     poisson_finite_element_1  element_1;
>
>     // Array of quadrature weights.
>     static const double W1[1] = {0.500000000000000};
>     // Quadrature points on the UFC reference element: (0.333333333333333, 0.333333333333333)
>
>
>     // Array of quadrature points.
>     static const double P1[2] = \
>     {0.333333333333333, 0.333333333333333};
>
>     // Define vectors for quadrature points and weights(note that the sizes are determined in compile time)
>     std::vector<double> Wn1;
>     std::vector<double> Pn1;
>
>
>     // Check whether there is any need to use modified integration scheme
>     if (pums[0]->modified_quadrature(c))
>     {
>
>       const std::vector<double> weight1(W1, W1 + 1);
>       const std::vector<double> point1(P1, P1 + 2);
>
>       ConstQuadratureRule standard_gauss = std::make_pair(point1, weight1);
>       QuadratureRule modified_gauss;
>
>       pums[0]->cell_quadrature_rule(modified_gauss, standard_gauss, c);
>
>       Pn1 = modified_gauss.first;
>       Wn1 = modified_gauss.second;
>
>     }
>     else
>     {
>       // Map quadrature points from the reference cell to the physical cell
>       Wn1.resize(1);
>       Pn1.resize(2);
>
>
>       for (unsigned int i = 0; i < 1; i++)
>       {
>         Wn1[i] = W1[i];
>         for (unsigned int j = 0; j < 2; j++)
>           Pn1[2*i + j] = x[0][j]*(1.0 - P1[2*i] - P1[2*i + 1]) + x[1][j]*P1[2*i + 1] + x[2][j]*P1[2*i];
>       }
>     }
>
>
>     // Return the values of enriched function at the quadrature points
>     std::vector<double>  enriched_values_1;
>     pums[0]->tabulate_enriched_basis(enriched_values_1, Pn1, c);
>
>     // Define auxilary indices: m, n
>     unsigned int m = 0;
>     unsigned int n = 0;
>
>
>     // Loop quadrature points for integral.
>     for (unsigned int ip = 0; ip < Wn1.size(); ip++)
>     {
>       // Evalaute tables and entries in the element tensor, if the enhanced value at this quadrature point is non-zero
>       if (enriched_values_1[ip] != 0)
>       {
>         // Pick up the coordinates of the current quadrature point
>         coordinate[0] = Pn1[2*ip];
>         coordinate[1] = Pn1[2*ip + 1];
>
>
>         // Creating a table to save the values of derivatives order 1 at the current guass point for <<CG1 on a <triangle of degree 1>> + <<CG1 on a <triangle of degree 1>>>|_{dc0}>
>         double value_0[2];
>         double table_1_D1[6][2];
>         for (unsigned int j = 0; j < 6; j++)
>         {
>           element_1.evaluate_basis_derivatives(j, 1, value_0, coordinate, c);
>           for (unsigned int k = 0; k < 2; k++)
>             table_1_D1[j][k] = value_0[k];
>         }
>
>
>         // Creating a table to save the values of shape functions at the current guass point for <CG1 on a <triangle of degree 1>>
>         double value_1[1];
>         double table_0_D0[3][1];
>         for (unsigned int j = 0; j < 3; j++)
>         {
>           element_0.evaluate_basis(j, value_1, coordinate, c);
>           for (unsigned int k = 0; k < 1; k++)
>             table_0_D0[j][k] = value_1[k];
>         }
>
>
>         // Creating a table to save the values of shape functions at the current guass point for <<CG1 on a <triangle of degree 1>> + <<CG1 on a <triangle of degree 1>>>|_{dc0}>
>         double value_2[1];
>         double table_1_D0[6][1];
>         for (unsigned int j = 0; j < 6; j++)
>         {
>           element_1.evaluate_basis(j, value_2, coordinate, c);
>           for (unsigned int k = 0; k < 1; k++)
>             table_1_D0[j][k] = value_2[k];
>         }
>         // Coefficient declarations.
>         double F0 = 0.000000000000000;
>
>         // Total number of operations to compute function values = 6
>       for (unsigned int r = 0; r < 3; r++)
>       {
>         F0 += table_0_D0[r][0]*w[0][r];
>       }// end loop over 'r'
>
>         // Number of operations for primary indices: 7
>         for (unsigned int j = 0; j < 6; j++)
>         {
>           for (unsigned int k = 0; k < 6; k++)
>           {
>             if (!(((0 <= j && j < 3)) && ((0 <= k && k < 3))))
>             {
>               // Move the indices of discontinuous spaces to the end of mixed space
>               if ((0 <= j && j < 3) && (3 <= k && k < 6))
>               {
>                 m = j;
>                 n = k;
>               }
>               else if ((3 <= j && j < 6) && (0 <= k && k < 3))
>               {
>                 m = j;
>                 n = k;
>               }
>               else if ((3 <= j && j < 6) && (3 <= k && k < 6))
>               {
>                 m = j;
>                 n = k;
>               }
>
>               // Number of operations to compute entry: 7
>               Aa[m*6 + n] += ((table_1_D1[j][1]*table_1_D1[k][1] + table_1_D1[j][0]*table_1_D1[k][0]))*F0*Wn1[ip]*det;
>             }// end check for enriched entiries
>           }// end loop over 'k'
>         }// end loop over 'j'
>       }
>     }// end loop over 'ip'
>
>
>     // Pick up entries from the total element tensor for the nodes active in the enrichment
>
>     // Determine a vector that contains the local numbering of enriched degrees of freedom in ufc::cell c for the field 0
>     std::vector<unsigned int> active_dofs_0;
>     pums[0]->tabulate_enriched_local_dofs(active_dofs_0, c);
>     std::vector<unsigned int>::iterator   it_0_0, it_0_1;
>
>
>     m = 0;
>     for (unsigned int j = 0; j < 6; j++)
>       for (unsigned int k = 0; k < 6; k++)
>         if ((0 <= j && j < 3) && (0 <= k && k < 3))
>           ++m;
>         else
>         {
>           it_0_0 = find(active_dofs_0.begin(), active_dofs_0.end(), j - 3);
>           it_0_1 = find(active_dofs_0.begin(), active_dofs_0.end(), k - 3);
>
>
>           // Check whether the entry is coressponding to the active enriched node
>           if  (it_0_0 != active_dofs_0.end() || it_0_1 != active_dofs_0.end())
>             if (((0 <= j && j < 3)) || ((0 <= k && k < 3)) || (it_0_0 != active_dofs_0.end() && it_0_1 != active_dofs_0.end()))
>             {
>               A[m] = Aa[j*6 + k];
>               ++m;
>             }
>         }
>   }
>
> };
>
> /// This class defines the interface for the tabulation of the cell
> /// tensor corresponding to the local contribution to a form from
> /// the integral over a cell.
>
> class poisson_cell_integral_1_0: public ufc::cell_integral
> {
>   const std::vector<const pum::GenericPUM*>& pums;
>   mutable std::vector <double> Aa;
>
>   /// Tabulate the regular entities of tensor for the contribution from a local cell
>   virtual void tabulate_regular_tensor(double* A,
>                                        const double * const * w,
>                                        const ufc::cell& c) const
>   {
>     // Extract vertex coordinates
>     const double * const * x = c.coordinates;
>
>     // Compute Jacobian of affine map from reference cell
>     const double J_00 = x[1][0] - x[0][0];
>     const double J_01 = x[2][0] - x[0][0];
>     const double J_10 = x[1][1] - x[0][1];
>     const double J_11 = x[2][1] - x[0][1];
>
>     // Compute determinant of Jacobian
>     double detJ = J_00*J_11 - J_01*J_10;
>
>     // Compute inverse of Jacobian
>
>     // Set scale factor
>     const double det = std::abs(detJ);
>
>     // Array of quadrature weights.
>     static const double W4[4] = {0.159020690871988, 0.090979309128011, 0.159020690871988, 0.090979309128011};
>     // Quadrature points on the UFC reference element: (0.178558728263616, 0.155051025721682), (0.075031110222608, 0.644948974278318), (0.666390246014701, 0.155051025721682), (0.280019915499074, 0.644948974278318)
>
>     // Value of basis functions at quadrature points.
>     static const double FE0[4][6] = \
>     {{0.666390246014701, 0.178558728263616, 0.155051025721682, 0.666390246014701, 0.178558728263616, 0.155051025721682},
>     {0.280019915499074, 0.075031110222608, 0.644948974278318, 0.280019915499074, 0.075031110222608, 0.644948974278318},
>     {0.178558728263616, 0.666390246014701, 0.155051025721682, 0.178558728263616, 0.666390246014701, 0.155051025721682},
>     {0.075031110222608, 0.280019915499074, 0.644948974278318, 0.075031110222608, 0.280019915499074, 0.644948974278318}};
>
>     static const double FE1[4][3] = \
>     {{0.666390246014701, 0.178558728263616, 0.155051025721682},
>     {0.280019915499074, 0.075031110222608, 0.644948974278318},
>     {0.178558728263616, 0.666390246014701, 0.155051025721682},
>     {0.075031110222608, 0.280019915499074, 0.644948974278318}};
>
>
>     // enriched local dimension of the current cell
>     unsigned int offset = pums[0]->enriched_local_dimension(c);
>
>     // Reset values in the element tensor.
>     const unsigned int num_entries = (3 + offset);
>
>     for (unsigned int r = 0; r < num_entries; r++)
>     {
>       A[r] = 0.000000000000000;
>     }// end loop over 'r'
>
>     // Compute element tensor using UFL quadrature representation
>     // Optimisations: ('optimisation', False), ('non zero columns', False), ('remove zero terms', False), ('ignore ones', False), ('ignore zero tables', False)
>
>     // Loop quadrature points for integral.
>     // Number of operations to compute element tensor for following IP loop = 40
>     for (unsigned int ip = 0; ip < 4; ip++)
>     {
>       // Coefficient declarations.
>       double F0 = 0.000000000000000;
>
>       // Total number of operations to compute function values = 6
>       for (unsigned int r = 0; r < 3; r++)
>       {
>         F0 += FE1[ip][r]*w[0][r];
>       }// end loop over 'r'
>       unsigned int m = 0;
>
>       // Number of operations for primary indices = 4
>       for (unsigned int j = 0; j < 6; j++)
>       {
>         // Number of operations to compute entry: 4
>         if (((((0 <= j && j < 3)))))
>         {
>           A[m] += FE0[ip][j]*F0*W4[ip]*det;
>         ++m;
>         }
>
>       }// end loop over 'j'
>     }// end loop over 'ip'
>   }
>
> public:
>
>   /// Constructor
>   poisson_cell_integral_1_0(    const std::vector<const pum::GenericPUM*>& pums) : ufc::cell_integral()    , pums(pums)
>   {
>     // Do nothing
>   }
>
>   /// Destructor
>   virtual ~poisson_cell_integral_1_0()
>   {
>     // Do nothing
>   }
>
>
>   /// Tabulate the tensor for the contribution from a local cell
>   virtual void tabulate_tensor(double* A,
>                                const double * const * w,
>                                const ufc::cell& c) const
>   {
>     // Tabulate regular entires of element tensor
>     tabulate_regular_tensor(A, w, c);
>
>
>     // enriched local dimension of the current cell(s)
>     unsigned int offset = pums[0]->enriched_local_dimension(c);
>
>     if (offset == 0)
>     {
>       return;
>     }
>
>
>     // Extract vertex coordinates
>     const double * const * x = c.coordinates;
>
>     // Compute Jacobian of affine map from reference cell
>     const double J_00 = x[1][0] - x[0][0];
>     const double J_01 = x[2][0] - x[0][0];
>     const double J_10 = x[1][1] - x[0][1];
>     const double J_11 = x[2][1] - x[0][1];
>
>     // Compute determinant of Jacobian
>     double detJ = J_00*J_11 - J_01*J_10;
>
>
>     // Set scale factor
>     const double det = std::abs(detJ);
>
>     // FIXME: It will crash for multiple discontinuities, if we don't have at least one cell which all dofs are enriched
>     const unsigned int min_entries = 6;
>     const unsigned int num_entries = std::max((offset + 3), min_entries);
>
>     // Resizing and reseting auxiliary tensors
>     Aa.resize(num_entries);
>     std::fill(Aa.begin(), Aa.end(), 0.0);
>
>     // Define an array to save current quadrature point
>     double coordinate[2];
>
>     // Define ufc::finite_element object(s) to evalaute shape functions or their derivatives on runtime
>     poisson_finite_element_0  element_0;
>     poisson_finite_element_1  element_1;
>
>     // Array of quadrature weights.
>     static const double W4[4] = {0.159020690871988, 0.090979309128011, 0.159020690871988, 0.090979309128011};
>     // Quadrature points on the UFC reference element: (0.178558728263616, 0.155051025721682), (0.075031110222608, 0.644948974278318), (0.666390246014701, 0.155051025721682), (0.280019915499074, 0.644948974278318)
>
>
>     // Array of quadrature points.
>     static const double P4[8] = \
>     {0.178558728263616, 0.155051025721682,
>     0.075031110222608, 0.644948974278318,
>     0.666390246014701, 0.155051025721682,
>     0.280019915499074, 0.644948974278318};
>
>     // Define vectors for quadrature points and weights(note that the sizes are determined in compile time)
>     std::vector<double> Wn4;
>     std::vector<double> Pn4;
>
>
>     // Check whether there is any need to use modified integration scheme
>     if (pums[0]->modified_quadrature(c))
>     {
>
>       const std::vector<double> weight4(W4, W4 + 4);
>       const std::vector<double> point4(P4, P4 + 8);
>
>       ConstQuadratureRule standard_gauss = std::make_pair(point4, weight4);
>       QuadratureRule modified_gauss;
>
>       pums[0]->cell_quadrature_rule(modified_gauss, standard_gauss, c);
>
>       Pn4 = modified_gauss.first;
>       Wn4 = modified_gauss.second;
>
>     }
>     else
>     {
>       // Map quadrature points from the reference cell to the physical cell
>       Wn4.resize(4);
>       Pn4.resize(8);
>
>
>       for (unsigned int i = 0; i < 4; i++)
>       {
>         Wn4[i] = W4[i];
>         for (unsigned int j = 0; j < 2; j++)
>           Pn4[2*i + j] = x[0][j]*(1.0 - P4[2*i] - P4[2*i + 1]) + x[1][j]*P4[2*i + 1] + x[2][j]*P4[2*i];
>       }
>     }
>
>
>     // Return the values of enriched function at the quadrature points
>     std::vector<double>  enriched_values_4;
>     pums[0]->tabulate_enriched_basis(enriched_values_4, Pn4, c);
>
>     // Define an auxilary index: m
>     unsigned int m = 0;
>
>
>     // Loop quadrature points for integral.
>     for (unsigned int ip = 0; ip < Wn4.size(); ip++)
>     {
>       // Evalaute tables and entries in the element tensor, if the enhanced value at this quadrature point is non-zero
>       if (enriched_values_4[ip] != 0)
>       {
>         // Pick up the coordinates of the current quadrature point
>         coordinate[0] = Pn4[2*ip];
>         coordinate[1] = Pn4[2*ip + 1];
>
>
>         // Creating a table to save the values of shape functions at the current guass point for <CG1 on a <triangle of degree 1>>
>         double value_0[1];
>         double table_0_D0[3][1];
>         for (unsigned int j = 0; j < 3; j++)
>         {
>           element_0.evaluate_basis(j, value_0, coordinate, c);
>           for (unsigned int k = 0; k < 1; k++)
>             table_0_D0[j][k] = value_0[k];
>         }
>
>
>         // Creating a table to save the values of shape functions at the current guass point for <<CG1 on a <triangle of degree 1>> + <<CG1 on a <triangle of degree 1>>>|_{dc0}>
>         double value_1[1];
>         double table_1_D0[6][1];
>         for (unsigned int j = 0; j < 6; j++)
>         {
>           element_1.evaluate_basis(j, value_1, coordinate, c);
>           for (unsigned int k = 0; k < 1; k++)
>             table_1_D0[j][k] = value_1[k];
>         }
>         // Coefficient declarations.
>         double F0 = 0.000000000000000;
>
>         // Total number of operations to compute function values = 6
>       for (unsigned int r = 0; r < 3; r++)
>       {
>         F0 += table_0_D0[r][0]*w[0][r];
>       }// end loop over 'r'
>
>         // Number of operations for primary indices: 4
>         for (unsigned int j = 0; j < 6; j++)
>         {
>           if (!(((0 <= j && j < 3))))
>           {
>             // Move the indices of discontinuous spaces to the end of mixed space
>             if ((3 <= j && j < 6))
>             {
>               m = j;
>             }
>
>             // Number of operations to compute entry: 4
>             Aa[m] += table_1_D0[j][0]*F0*Wn4[ip]*det;
>           }// end check for enriched entiries
>         }// end loop over 'j'
>       }
>     }// end loop over 'ip'
>
>
>     // Pick up entries from the total element tensor for the nodes active in the enrichment
>
>     // Determine a vector that contains the local numbering of enriched degrees of freedom in ufc::cell c for the field 0
>     std::vector<unsigned int> active_dofs_0;
>     pums[0]->tabulate_enriched_local_dofs(active_dofs_0, c);
>     std::vector<unsigned int>::iterator   it_0_0;
>
>
>     m = 0;
>     for (unsigned int j = 0; j < 6; j++)
>       if ((0 <= j && j < 3))
>         ++m;
>       else
>       {
>         it_0_0 = find(active_dofs_0.begin(), active_dofs_0.end(), j - 3);
>
>
>         // Check whether the entry is coressponding to the active enriched node
>         if  (it_0_0 != active_dofs_0.end())
>         {
>           A[m] = Aa[j];
>           ++m;
>         }
>       }
>   }
>
> };
>
> /// This class defines the interface for the tabulation of the
> /// exterior facet tensor corresponding to the local contribution to
> /// a form from the integral over an exterior facet.
>
> class poisson_exterior_facet_integral_1_0: public ufc::exterior_facet_integral
> {
>   const std::vector<const pum::GenericPUM*>& pums;
>   mutable std::vector <double> Aa;
>
>   /// Tabulate the regular entities of the tensor for the contribution from a local exterior facet
>   virtual void tabulate_regular_tensor(double* A,
>                                        const double * const * w,
>                                        const ufc::cell& c,
>                                        unsigned int facet) const
>   {
>     // Extract vertex coordinates
>     const double * const * x = c.coordinates;
>
>     // Compute Jacobian of affine map from reference cell
>
>     // Compute determinant of Jacobian
>
>     // Compute inverse of Jacobian
>
>     // Get vertices on edge
>     static unsigned int edge_vertices[3][2] = {{1, 2}, {0, 2}, {0, 1}};
>     const unsigned int v0 = edge_vertices[facet][0];
>     const unsigned int v1 = edge_vertices[facet][1];
>
>     // Compute scale factor (length of edge scaled by length of reference interval)
>     const double dx0 = x[v1][0] - x[v0][0];
>     const double dx1 = x[v1][1] - x[v0][1];
>     const double det = std::sqrt(dx0*dx0 + dx1*dx1);
>
>
>     // Array of quadrature weights.
>     static const double W2[2] = {0.500000000000000, 0.500000000000000};
>     // Quadrature points on the UFC reference element: (0.211324865405187), (0.788675134594813)
>
>     // Value of basis functions at quadrature points.
>     static const double FE0_f0[2][6] = \
>     {{0.000000000000000, 0.788675134594813, 0.211324865405187, 0.000000000000000, 0.788675134594813, 0.211324865405187},
>     {0.000000000000000, 0.211324865405187, 0.788675134594813, 0.000000000000000, 0.211324865405187, 0.788675134594813}};
>
>     static const double FE0_f1[2][6] = \
>     {{0.788675134594813, 0.000000000000000, 0.211324865405187, 0.788675134594813, 0.000000000000000, 0.211324865405187},
>     {0.211324865405187, 0.000000000000000, 0.788675134594813, 0.211324865405187, 0.000000000000000, 0.788675134594813}};
>
>     static const double FE0_f2[2][6] = \
>     {{0.788675134594813, 0.211324865405187, 0.000000000000000, 0.788675134594813, 0.211324865405187, 0.000000000000000},
>     {0.211324865405187, 0.788675134594813, 0.000000000000000, 0.211324865405187, 0.788675134594813, 0.000000000000000}};
>
>     static const double FE1_f0[2][3] = \
>     {{0.000000000000000, 0.788675134594813, 0.211324865405187},
>     {0.000000000000000, 0.211324865405187, 0.788675134594813}};
>
>     static const double FE1_f1[2][3] = \
>     {{0.788675134594813, 0.000000000000000, 0.211324865405187},
>     {0.211324865405187, 0.000000000000000, 0.788675134594813}};
>
>     static const double FE1_f2[2][3] = \
>     {{0.788675134594813, 0.211324865405187, 0.000000000000000},
>     {0.211324865405187, 0.788675134594813, 0.000000000000000}};
>
>
>     // enriched local dimension of the current cell
>     unsigned int offset = pums[0]->enriched_local_dimension(c);
>
>     // Reset values in the element tensor.
>     const unsigned int num_entries = (3 + offset);
>
>     for (unsigned int r = 0; r < num_entries; r++)
>     {
>       A[r] = 0.000000000000000;
>     }// end loop over 'r'
>
>     // Compute element tensor using UFL quadrature representation
>     // Optimisations: ('optimisation', False), ('non zero columns', False), ('remove zero terms', False), ('ignore ones', False), ('ignore zero tables', False)
>     switch (facet)
>     {
>     case 0:
>       {
>         // Total number of operations to compute element tensor (from this point): 22
>
>       // Loop quadrature points for integral.
>       // Number of operations to compute element tensor for following IP loop = 22
>       for (unsigned int ip = 0; ip < 2; ip++)
>       {
>         // Coefficient declarations.
>         double F0 = 0.000000000000000;
>
>         // Total number of operations to compute function values = 6
>         for (unsigned int r = 0; r < 3; r++)
>         {
>           F0 += FE1_f0[ip][r]*w[1][r];
>         }// end loop over 'r'
>         unsigned int m = 0;
>
>         // Number of operations for primary indices = 5
>         for (unsigned int j = 0; j < 6; j++)
>         {
>           // Number of operations to compute entry: 5
>           if (((((0 <= j && j < 3)))))
>           {
>             A[m] += FE0_f0[ip][j]*F0*(-1.000000000000000)*W2[ip]*det;
>           ++m;
>           }
>
>         }// end loop over 'j'
>       }// end loop over 'ip'
>         break;
>       }
>     case 1:
>       {
>         // Total number of operations to compute element tensor (from this point): 22
>
>       // Loop quadrature points for integral.
>       // Number of operations to compute element tensor for following IP loop = 22
>       for (unsigned int ip = 0; ip < 2; ip++)
>       {
>         // Coefficient declarations.
>         double F0 = 0.000000000000000;
>
>         // Total number of operations to compute function values = 6
>         for (unsigned int r = 0; r < 3; r++)
>         {
>           F0 += FE1_f1[ip][r]*w[1][r];
>         }// end loop over 'r'
>         unsigned int m = 0;
>
>         // Number of operations for primary indices = 5
>         for (unsigned int j = 0; j < 6; j++)
>         {
>           // Number of operations to compute entry: 5
>           if (((((0 <= j && j < 3)))))
>           {
>             A[m] += FE0_f1[ip][j]*F0*(-1.000000000000000)*W2[ip]*det;
>           ++m;
>           }
>
>         }// end loop over 'j'
>       }// end loop over 'ip'
>         break;
>       }
>     case 2:
>       {
>         // Total number of operations to compute element tensor (from this point): 22
>
>       // Loop quadrature points for integral.
>       // Number of operations to compute element tensor for following IP loop = 22
>       for (unsigned int ip = 0; ip < 2; ip++)
>       {
>         // Coefficient declarations.
>         double F0 = 0.000000000000000;
>
>         // Total number of operations to compute function values = 6
>         for (unsigned int r = 0; r < 3; r++)
>         {
>           F0 += FE1_f2[ip][r]*w[1][r];
>         }// end loop over 'r'
>         unsigned int m = 0;
>
>         // Number of operations for primary indices = 5
>         for (unsigned int j = 0; j < 6; j++)
>         {
>           // Number of operations to compute entry: 5
>           if (((((0 <= j && j < 3)))))
>           {
>             A[m] += FE0_f2[ip][j]*F0*(-1.000000000000000)*W2[ip]*det;
>           ++m;
>           }
>
>         }// end loop over 'j'
>       }// end loop over 'ip'
>         break;
>       }
>     }
>
>   }
>
> public:
>
>   /// Constructor
>   poisson_exterior_facet_integral_1_0(    const std::vector<const pum::GenericPUM*>& pums) : ufc::exterior_facet_integral()    , pums(pums)
>   {
>     // Do nothing
>   }
>
>   /// Destructor
>   virtual ~poisson_exterior_facet_integral_1_0()
>   {
>     // Do nothing
>   }
>
>   /// Tabulate the tensor for the contribution from a local exterior facet
>   virtual void tabulate_tensor(double* A,
>                                const double * const * w,
>                                const ufc::cell& c,
>                                unsigned int facet) const
>   {
>     // Tabulate regular entires of element tensor
>     tabulate_regular_tensor(A, w, c, facet);
>
>
>     // enriched local dimension of the current cell(s)
>     unsigned int offset = pums[0]->enriched_local_dimension(c);
>
>     if (offset == 0)
>     {
>       return;
>     }
>
>
>     // Extract vertex coordinates
>     const double * const * x = c.coordinates;
>
>     // Get vertices on edge
>     static unsigned int edge_vertices[3][2] = {{1, 2}, {0, 2}, {0, 1}};
>     const unsigned int v0 = edge_vertices[facet][0];
>     const unsigned int v1 = edge_vertices[facet][1];
>
>     // Compute scale factor (length of edge scaled by length of reference interval)
>     const double dx0 = x[v1][0] - x[v0][0];
>     const double dx1 = x[v1][1] - x[v0][1];
>     const double det = std::sqrt(dx0*dx0 + dx1*dx1);
>
>     // FIXME: It will crash for multiple discontinuities, if we don't have at least one cell which all dofs are enriched
>     const unsigned int min_entries = 6;
>     const unsigned int num_entries = std::max((offset + 3), min_entries);
>
>     // Resizing and reseting auxiliary tensors
>     Aa.resize(num_entries);
>     std::fill(Aa.begin(), Aa.end(), 0.0);
>
>     // Define an array to save current quadrature point
>     double coordinate[2];
>
>     // Define ufc::finite_element object(s) to evalaute shape functions or their derivatives on runtime
>     poisson_finite_element_0  element_0;
>     poisson_finite_element_1  element_1;
>
>     // Array of quadrature weights.
>     static const double W2[2] = {0.500000000000000, 0.500000000000000};
>     // Quadrature points on the UFC reference element: (0.211324865405187), (0.788675134594813)
>
>
>     // Array of quadrature points.
>     static const double P2[2] = \
>     {0.211324865405187,
>     0.788675134594813};
>
>     // Define vectors for quadrature points and weights(note that the sizes are determined in compile time)
>     std::vector<double> Wn2;
>     std::vector<double> Pn2;
>
>
>     // Check whether there is any need to use modified integration scheme
>     if (pums[0]->modified_quadrature(c, facet))
>     {
>
>       const std::vector<double> weight2(W2, W2 + 2);
>       const std::vector<double> point2(P2, P2 + 2);
>
>       ConstQuadratureRule standard_gauss = std::make_pair(point2, weight2);
>       QuadratureRule modified_gauss;
>
>       pums[0]->facet_quadrature_rule(modified_gauss, standard_gauss, c, facet);
>
>       Pn2 = modified_gauss.first;
>       Wn2 = modified_gauss.second;
>
>     }
>     else
>     {
>       // Map quadrature points from the reference cell to the physical cell
>       Wn2.resize(2);
>       Pn2.resize(4);
>
>
>       for (unsigned int i = 0; i < 2; i++)
>       {
>         Wn2[i] = W2[i];
>         for (unsigned int j = 0; j < 2; j++)
>           Pn2[2*i + j] = x[v0][j]*(1.0 - P2[i]) + x[v1][j]*P2[i];
>       }
>     }
>
>
>     // Return the values of enriched function at the quadrature points
>     std::vector<double>  enriched_values_2;
>     pums[0]->tabulate_enriched_basis(enriched_values_2, Pn2, c);
>
>     // Define an auxilary index: m
>     unsigned int m = 0;
>
>
>     // Loop quadrature points for integral.
>     for (unsigned int ip = 0; ip < Wn2.size(); ip++)
>     {
>       // Evalaute tables and entries in the element tensor, if the enhanced value at this quadrature point is non-zero
>       if (enriched_values_2[ip] != 0)
>       {
>         // Pick up the coordinates of the current quadrature point
>         coordinate[0] = Pn2[2*ip];
>         coordinate[1] = Pn2[2*ip + 1];
>
>
>         // Creating a table to save the values of shape functions at the current guass point for <CG1 on a <triangle of degree 1>>
>         double value_0[1];
>         double table_0_D0[3][1];
>         for (unsigned int j = 0; j < 3; j++)
>         {
>           element_0.evaluate_basis(j, value_0, coordinate, c);
>           for (unsigned int k = 0; k < 1; k++)
>             table_0_D0[j][k] = value_0[k];
>         }
>
>
>         // Creating a table to save the values of shape functions at the current guass point for <<CG1 on a <triangle of degree 1>> + <<CG1 on a <triangle of degree 1>>>|_{dc0}>
>         double value_1[1];
>         double table_1_D0[6][1];
>         for (unsigned int j = 0; j < 6; j++)
>         {
>           element_1.evaluate_basis(j, value_1, coordinate, c);
>           for (unsigned int k = 0; k < 1; k++)
>             table_1_D0[j][k] = value_1[k];
>         }
>         // Coefficient declarations.
>         double F0 = 0.000000000000000;
>
>         // Total number of operations to compute function values = 6
>       for (unsigned int r = 0; r < 3; r++)
>       {
>         F0 += table_0_D0[r][0]*w[1][r];
>       }// end loop over 'r'
>
>         // Number of operations for primary indices: 5
>         for (unsigned int j = 0; j < 6; j++)
>         {
>           if (!(((0 <= j && j < 3))))
>           {
>             // Move the indices of discontinuous spaces to the end of mixed space
>             if ((3 <= j && j < 6))
>             {
>               m = j;
>             }
>
>             // Number of operations to compute entry: 5
>             Aa[m] += table_1_D0[j][0]*F0*(-1.000000000000000)*Wn2[ip]*det;
>           }// end check for enriched entiries
>         }// end loop over 'j'
>       }
>     }// end loop over 'ip'
>
>
>     // Pick up entries from the total element tensor for the nodes active in the enrichment
>
>     // Determine a vector that contains the local numbering of enriched degrees of freedom in ufc::cell c for the field 0
>     std::vector<unsigned int> active_dofs_0;
>     pums[0]->tabulate_enriched_local_dofs(active_dofs_0, c);
>     std::vector<unsigned int>::iterator   it_0_0;
>
>
>     m = 0;
>     for (unsigned int j = 0; j < 6; j++)
>       if ((0 <= j && j < 3))
>         ++m;
>       else
>       {
>         it_0_0 = find(active_dofs_0.begin(), active_dofs_0.end(), j - 3);
>
>
>         // Check whether the entry is coressponding to the active enriched node
>         if  (it_0_0 != active_dofs_0.end())
>         {
>           A[m] = Aa[j];
>           ++m;
>         }
>       }
>   }
>
> };
>
> /// This class defines the interface for the assembly of the global
> /// tensor corresponding to a form with r + n arguments, that is, a
> /// mapping
> ///
> ///     a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R
> ///
> /// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r
> /// global tensor A is defined by
> ///
> ///     A = a(V1, V2, ..., Vr, w1, w2, ..., wn),
> ///
> /// where each argument Vj represents the application to the
> /// sequence of basis functions of Vj and w1, w2, ..., wn are given
> /// fixed functions (coefficients).
>
> class poisson_form_0: public ufc::form
> {
>   const std::vector<const pum::GenericPUM*>& pums;
> public:
>
>   /// Constructor
>   poisson_form_0(    const std::vector<const pum::GenericPUM*>& pums) : ufc::form()    , pums(pums)
>   {
>     // Do nothing
>   }
>
>   /// Destructor
>   virtual ~poisson_form_0()
>   {
>     // Do nothing
>   }
>
>   /// Return a string identifying the form
>   virtual const char* signature() const
>   {
>     return "Form([Integral(Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), 0), IndexSum(Product(Indexed(ComponentTensor(SpatialDerivative(Argument(EnrichedElement(FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), ElementRestriction(FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), Measure('surface', 0, None))), 0), MultiIndex((Index(0),), {Index(0): 2})), MultiIndex((Index(0),), {Index(0): 2})), MultiIndex((Index(1),), {Index(1): 2})), Indexed(ComponentTensor(SpatialDerivative(Argument(EnrichedElement(FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), ElementRestriction(FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), Measure('surface', 0, None))), 1), MultiIndex((Index(2),), {Index(2): 2})), MultiIndex((Index(2),), {Index(2): 2})), MultiIndex((Index(1),), {Index(1): 2}))), MultiIndex((Index(1),), {Index(1): 2}))), Measure('cell', 0, None))])";
>   }
>
>   /// Return the rank of the global tensor (r)
>   virtual unsigned int rank() const
>   {
>     return 2;
>   }
>
>   /// Return the number of coefficients (n)
>   virtual unsigned int num_coefficients() const
>   {
>     return 1;
>   }
>
>   /// Return the number of cell integrals
>   virtual unsigned int num_cell_integrals() const
>   {
>     return 1;
>   }
>
>   /// Return the number of exterior facet integrals
>   virtual unsigned int num_exterior_facet_integrals() const
>   {
>     return 0;
>   }
>
>   /// Return the number of interior facet integrals
>   virtual unsigned int num_interior_facet_integrals() const
>   {
>     return 0;
>   }
>
>   /// Create a new finite element for argument function i
>   virtual ufc::finite_element* create_finite_element(unsigned int i) const
>   {
>     switch (i)
>     {
>     case 0:
>       {
>         return new poisson_finite_element_1();
>         break;
>       }
>     case 1:
>       {
>         return new poisson_finite_element_1();
>         break;
>       }
>     case 2:
>       {
>         return new poisson_finite_element_0();
>         break;
>       }
>     }
>
>     return 0;
>   }
>
>   /// Create a new dof map for argument function i
>   virtual ufc::dof_map* create_dof_map(unsigned int i) const
>   {
>     switch (i)
>     {
>     case 0:
>       {
>         return new poisson_dof_map_1(pums);
>         break;
>       }
>     case 1:
>       {
>         return new poisson_dof_map_1(pums);
>         break;
>       }
>     case 2:
>       {
>         return new poisson_dof_map_0();
>         break;
>       }
>     }
>
>     return 0;
>   }
>
>   /// Create a new cell integral on sub domain i
>   virtual ufc::cell_integral* create_cell_integral(unsigned int i) const
>   {
>     switch (i)
>     {
>     case 0:
>       {
>         return new poisson_cell_integral_0_0(pums);
>         break;
>       }
>     }
>
>     return 0;
>   }
>
>   /// Create a new exterior facet integral on sub domain i
>   virtual ufc::exterior_facet_integral* create_exterior_facet_integral(unsigned int i) const
>   {
>     return 0;
>   }
>
>   /// Create a new interior facet integral on sub domain i
>   virtual ufc::interior_facet_integral* create_interior_facet_integral(unsigned int i) const
>   {
>     return 0;
>   }
>
> };
>
> /// This class defines the interface for the assembly of the global
> /// tensor corresponding to a form with r + n arguments, that is, a
> /// mapping
> ///
> ///     a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R
> ///
> /// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r
> /// global tensor A is defined by
> ///
> ///     A = a(V1, V2, ..., Vr, w1, w2, ..., wn),
> ///
> /// where each argument Vj represents the application to the
> /// sequence of basis functions of Vj and w1, w2, ..., wn are given
> /// fixed functions (coefficients).
>
> class poisson_form_1: public ufc::form
> {
>   const std::vector<const pum::GenericPUM*>& pums;
> public:
>
>   /// Constructor
>   poisson_form_1(    const std::vector<const pum::GenericPUM*>& pums) : ufc::form()    , pums(pums)
>   {
>     // Do nothing
>   }
>
>   /// Destructor
>   virtual ~poisson_form_1()
>   {
>     // Do nothing
>   }
>
>   /// Return a string identifying the form
>   virtual const char* signature() const
>   {
>     return "Form([Integral(Product(Argument(EnrichedElement(FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), ElementRestriction(FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), Measure('surface', 0, None))), 0), Coefficient(FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), 0)), Measure('cell', 0, None)), Integral(Product(IntValue(-1, (), (), {}), Product(Argument(EnrichedElement(FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), ElementRestriction(FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), Measure('surface', 0, None))), 0), Coefficient(FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), 1))), Measure('exterior_facet', 0, None))])";
>   }
>
>   /// Return the rank of the global tensor (r)
>   virtual unsigned int rank() const
>   {
>     return 1;
>   }
>
>   /// Return the number of coefficients (n)
>   virtual unsigned int num_coefficients() const
>   {
>     return 2;
>   }
>
>   /// Return the number of cell integrals
>   virtual unsigned int num_cell_integrals() const
>   {
>     return 1;
>   }
>
>   /// Return the number of exterior facet integrals
>   virtual unsigned int num_exterior_facet_integrals() const
>   {
>     return 1;
>   }
>
>   /// Return the number of interior facet integrals
>   virtual unsigned int num_interior_facet_integrals() const
>   {
>     return 0;
>   }
>
>   /// Create a new finite element for argument function i
>   virtual ufc::finite_element* create_finite_element(unsigned int i) const
>   {
>     switch (i)
>     {
>     case 0:
>       {
>         return new poisson_finite_element_1();
>         break;
>       }
>     case 1:
>       {
>         return new poisson_finite_element_0();
>         break;
>       }
>     case 2:
>       {
>         return new poisson_finite_element_0();
>         break;
>       }
>     }
>
>     return 0;
>   }
>
>   /// Create a new dof map for argument function i
>   virtual ufc::dof_map* create_dof_map(unsigned int i) const
>   {
>     switch (i)
>     {
>     case 0:
>       {
>         return new poisson_dof_map_1(pums);
>         break;
>       }
>     case 1:
>       {
>         return new poisson_dof_map_0();
>         break;
>       }
>     case 2:
>       {
>         return new poisson_dof_map_0();
>         break;
>       }
>     }
>
>     return 0;
>   }
>
>   /// Create a new cell integral on sub domain i
>   virtual ufc::cell_integral* create_cell_integral(unsigned int i) const
>   {
>     switch (i)
>     {
>     case 0:
>       {
>         return new poisson_cell_integral_1_0(pums);
>         break;
>       }
>     }
>
>     return 0;
>   }
>
>   /// Create a new exterior facet integral on sub domain i
>   virtual ufc::exterior_facet_integral* create_exterior_facet_integral(unsigned int i) const
>   {
>     switch (i)
>     {
>     case 0:
>       {
>         return new poisson_exterior_facet_integral_1_0(pums);
>         break;
>       }
>     }
>
>     return 0;
>   }
>
>   /// Create a new interior facet integral on sub domain i
>   virtual ufc::interior_facet_integral* create_interior_facet_integral(unsigned int i) const
>   {
>     return 0;
>   }
>
> };
>
> /// This class defines the interface for a finite element.
>
> class poisson_auxiliary_finite_element_0: public ufc::finite_element
> {
> public:
>
>   /// Constructor
>   poisson_auxiliary_finite_element_0() : ufc::finite_element()
>   {
>     // Do nothing
>   }
>
>   /// Destructor
>   virtual ~poisson_auxiliary_finite_element_0()
>   {
>     // Do nothing
>   }
>
>   /// Return a string identifying the finite element
>   virtual const char* signature() const
>   {
>     return "FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)";
>   }
>
>   /// Return the cell shape
>   virtual ufc::shape cell_shape() const
>   {
>     return ufc::triangle;
>   }
>
>   /// Return the dimension of the finite element function space
>   virtual unsigned int space_dimension() const
>   {
>     return 3;
>   }
>
>   /// Return the rank of the value space
>   virtual unsigned int value_rank() const
>   {
>     return 0;
>   }
>
>   /// Return the dimension of the value space for axis i
>   virtual unsigned int value_dimension(unsigned int i) const
>   {
>     return 1;
>   }
>
>   /// Evaluate basis function i at given point in cell
>   virtual void evaluate_basis(unsigned int i,
>                               double* values,
>                               const double* coordinates,
>                               const ufc::cell& c) const
>   {
>     // Extract vertex coordinates
>     const double * const * x = c.coordinates;
>
>     // Compute Jacobian of affine map from reference cell
>     const double J_00 = x[1][0] - x[0][0];
>     const double J_01 = x[2][0] - x[0][0];
>     const double J_10 = x[1][1] - x[0][1];
>     const double J_11 = x[2][1] - x[0][1];
>
>     // Compute determinant of Jacobian
>     double detJ = J_00*J_11 - J_01*J_10;
>
>     // Compute inverse of Jacobian
>
>     // Compute constants
>     const double C0 = x[1][0] + x[2][0];
>     const double C1 = x[1][1] + x[2][1];
>
>     // Get coordinates and map to the reference (FIAT) element
>     double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ;
>     double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ;
>
>     // Reset values.
>     *values = 0.000000000000000;
>
>     // Map degree of freedom to element degree of freedom
>     const unsigned int dof = i;
>
>     // Array of basisvalues.
>     double basisvalues[3] = {0.000000000000000, 0.000000000000000, 0.000000000000000};
>
>     // Declare helper variables.
>     unsigned int rr = 0;
>     unsigned int ss = 0;
>     double tmp0 = (1.000000000000000 + Y + 2.000000000000000*X)/2.000000000000000;
>
>     // Compute basisvalues.
>     basisvalues[0] = 1.000000000000000;
>     basisvalues[1] = tmp0;
>     for (unsigned int r = 0; r < 1; r++)
>     {
>       rr = (r + 1)*(r + 1 + 1)/2 + 1;
>       ss = r*(r + 1)/2;
>       basisvalues[rr] = basisvalues[ss]*(0.500000000000000 + r + Y*(1.500000000000000 + r));
>     }// end loop over 'r'
>     for (unsigned int r = 0; r < 2; r++)
>     {
>       for (unsigned int s = 0; s < 2 - r; s++)
>       {
>         rr = (r + s)*(r + s + 1)/2 + s;
>         basisvalues[rr] *= std::sqrt((0.500000000000000 + r)*(1.000000000000000 + r + s));
>       }// end loop over 's'
>     }// end loop over 'r'
>
>     // Table(s) of coefficients.
>     static const double coefficients0[3][3] = \
>     {{0.471404520791032, -0.288675134594813, -0.166666666666667},
>     {0.471404520791032, 0.288675134594813, -0.166666666666667},
>     {0.471404520791032, 0.000000000000000, 0.333333333333333}};
>
>     // Compute value(s).
>     for (unsigned int r = 0; r < 3; r++)
>     {
>       *values += coefficients0[dof][r]*basisvalues[r];
>     }// end loop over 'r'
>   }
>
>   /// Evaluate all basis functions at given point in cell
>   virtual void evaluate_basis_all(double* values,
>                                   const double* coordinates,
>                                   const ufc::cell& c) const
>   {
>     // Helper variable to hold values of a single dof.
>     double dof_values = 0.000000000000000;
>
>     // Loop dofs and call evaluate_basis.
>     for (unsigned int r = 0; r < 3; r++)
>     {
>       evaluate_basis(r, &dof_values, coordinates, c);
>       values[r] = dof_values;
>     }// end loop over 'r'
>   }
>
>   /// Evaluate order n derivatives of basis function i at given point in cell
>   virtual void evaluate_basis_derivatives(unsigned int i,
>                                           unsigned int n,
>                                           double* values,
>                                           const double* coordinates,
>                                           const ufc::cell& c) const
>   {
>     // Extract vertex coordinates
>     const double * const * x = c.coordinates;
>
>     // Compute Jacobian of affine map from reference cell
>     const double J_00 = x[1][0] - x[0][0];
>     const double J_01 = x[2][0] - x[0][0];
>     const double J_10 = x[1][1] - x[0][1];
>     const double J_11 = x[2][1] - x[0][1];
>
>     // Compute determinant of Jacobian
>     double detJ = J_00*J_11 - J_01*J_10;
>
>     // Compute inverse of Jacobian
>     const double K_00 =  J_11 / detJ;
>     const double K_01 = -J_01 / detJ;
>     const double K_10 = -J_10 / detJ;
>     const double K_11 =  J_00 / detJ;
>
>     // Compute constants
>     const double C0 = x[1][0] + x[2][0];
>     const double C1 = x[1][1] + x[2][1];
>
>     // Get coordinates and map to the reference (FIAT) element
>     double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ;
>     double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ;
>
>     // Compute number of derivatives.
>     unsigned int num_derivatives = 1;
>     for (unsigned int r = 0; r < n; r++)
>     {
>       num_derivatives *= 2;
>     }// end loop over 'r'
>
>     // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
>     unsigned int **combinations = new unsigned int *[num_derivatives];
>     for (unsigned int row = 0; row < num_derivatives; row++)
>     {
>       combinations[row] = new unsigned int [n];
>       for (unsigned int col = 0; col < n; col++)
>         combinations[row][col] = 0;
>     }
>
>     // Generate combinations of derivatives
>     for (unsigned int row = 1; row < num_derivatives; row++)
>     {
>       for (unsigned int num = 0; num < row; num++)
>       {
>         for (unsigned int col = n-1; col+1 > 0; col--)
>         {
>           if (combinations[row][col] + 1 > 1)
>             combinations[row][col] = 0;
>           else
>           {
>             combinations[row][col] += 1;
>             break;
>           }
>         }
>       }
>     }
>
>     // Compute inverse of Jacobian
>     const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}};
>
>     // Declare transformation matrix
>     // Declare pointer to two dimensional array and initialise
>     double **transform = new double *[num_derivatives];
>
>     for (unsigned int j = 0; j < num_derivatives; j++)
>     {
>       transform[j] = new double [num_derivatives];
>       for (unsigned int k = 0; k < num_derivatives; k++)
>         transform[j][k] = 1;
>     }
>
>     // Construct transformation matrix
>     for (unsigned int row = 0; row < num_derivatives; row++)
>     {
>       for (unsigned int col = 0; col < num_derivatives; col++)
>       {
>         for (unsigned int k = 0; k < n; k++)
>           transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
>       }
>     }
>
>     // Reset values. Assuming that values is always an array.
>     for (unsigned int r = 0; r < num_derivatives; r++)
>     {
>       values[r] = 0.000000000000000;
>     }// end loop over 'r'
>
>     // Map degree of freedom to element degree of freedom
>     const unsigned int dof = i;
>
>     // Array of basisvalues.
>     double basisvalues[3] = {0.000000000000000, 0.000000000000000, 0.000000000000000};
>
>     // Declare helper variables.
>     unsigned int rr = 0;
>     unsigned int ss = 0;
>     double tmp0 = (1.000000000000000 + Y + 2.000000000000000*X)/2.000000000000000;
>
>     // Compute basisvalues.
>     basisvalues[0] = 1.000000000000000;
>     basisvalues[1] = tmp0;
>     for (unsigned int r = 0; r < 1; r++)
>     {
>       rr = (r + 1)*(r + 1 + 1)/2 + 1;
>       ss = r*(r + 1)/2;
>       basisvalues[rr] = basisvalues[ss]*(0.500000000000000 + r + Y*(1.500000000000000 + r));
>     }// end loop over 'r'
>     for (unsigned int r = 0; r < 2; r++)
>     {
>       for (unsigned int s = 0; s < 2 - r; s++)
>       {
>         rr = (r + s)*(r + s + 1)/2 + s;
>         basisvalues[rr] *= std::sqrt((0.500000000000000 + r)*(1.000000000000000 + r + s));
>       }// end loop over 's'
>     }// end loop over 'r'
>
>     // Table(s) of coefficients.
>     static const double coefficients0[3][3] = \
>     {{0.471404520791032, -0.288675134594813, -0.166666666666667},
>     {0.471404520791032, 0.288675134594813, -0.166666666666667},
>     {0.471404520791032, 0.000000000000000, 0.333333333333333}};
>
>     // Tables of derivatives of the polynomial base (transpose).
>     static const double dmats0[3][3] = \
>     {{0.000000000000000, 0.000000000000000, 0.000000000000000},
>     {4.898979485566356, 0.000000000000000, 0.000000000000000},
>     {0.000000000000000, 0.000000000000000, 0.000000000000000}};
>
>     static const double dmats1[3][3] = \
>     {{0.000000000000000, 0.000000000000000, 0.000000000000000},
>     {2.449489742783178, 0.000000000000000, 0.000000000000000},
>     {4.242640687119285, 0.000000000000000, 0.000000000000000}};
>
>     // Compute reference derivatives.
>     // Declare pointer to array of derivatives on FIAT element.
>     double *derivatives = new double[num_derivatives];
>     for (unsigned int r = 0; r < num_derivatives; r++)
>     {
>       derivatives[r] = 0.000000000000000;
>     }// end loop over 'r'
>
>     // Declare derivative matrix (of polynomial basis).
>     double dmats[3][3] = \
>     {{1.000000000000000, 0.000000000000000, 0.000000000000000},
>     {0.000000000000000, 1.000000000000000, 0.000000000000000},
>     {0.000000000000000, 0.000000000000000, 1.000000000000000}};
>
>     // Declare (auxiliary) derivative matrix (of polynomial basis).
>     double dmats_old[3][3] = \
>     {{1.000000000000000, 0.000000000000000, 0.000000000000000},
>     {0.000000000000000, 1.000000000000000, 0.000000000000000},
>     {0.000000000000000, 0.000000000000000, 1.000000000000000}};
>
>     // Loop possible derivatives.
>     for (unsigned int r = 0; r < num_derivatives; r++)
>     {
>       // Resetting dmats values to compute next derivative.
>       for (unsigned int t = 0; t < 3; t++)
>       {
>         for (unsigned int u = 0; u < 3; u++)
>         {
>           dmats[t][u] = 0.000000000000000;
>           if (t == u)
>           {
>           dmats[t][u] = 1.000000000000000;
>           }
>
>         }// end loop over 'u'
>       }// end loop over 't'
>
>       // Looping derivative order to generate dmats.
>       for (unsigned int s = 0; s < n; s++)
>       {
>         // Updating dmats_old with new values and resetting dmats.
>         for (unsigned int t = 0; t < 3; t++)
>         {
>           for (unsigned int u = 0; u < 3; u++)
>           {
>             dmats_old[t][u] = dmats[t][u];
>             dmats[t][u] = 0.000000000000000;
>           }// end loop over 'u'
>         }// end loop over 't'
>
>         // Update dmats using an inner product.
>         if (combinations[r][s] == 0)
>         {
>         for (unsigned int t = 0; t < 3; t++)
>         {
>           for (unsigned int u = 0; u < 3; u++)
>           {
>             for (unsigned int tu = 0; tu < 3; tu++)
>             {
>               dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
>             }// end loop over 'tu'
>           }// end loop over 'u'
>         }// end loop over 't'
>         }
>
>         if (combinations[r][s] == 1)
>         {
>         for (unsigned int t = 0; t < 3; t++)
>         {
>           for (unsigned int u = 0; u < 3; u++)
>           {
>             for (unsigned int tu = 0; tu < 3; tu++)
>             {
>               dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
>             }// end loop over 'tu'
>           }// end loop over 'u'
>         }// end loop over 't'
>         }
>
>       }// end loop over 's'
>       for (unsigned int s = 0; s < 3; s++)
>       {
>         for (unsigned int t = 0; t < 3; t++)
>         {
>           derivatives[r] += coefficients0[dof][s]*dmats[s][t]*basisvalues[t];
>         }// end loop over 't'
>       }// end loop over 's'
>     }// end loop over 'r'
>
>     // Transform derivatives back to physical element
>     for (unsigned int r = 0; r < num_derivatives; r++)
>     {
>       for (unsigned int s = 0; s < num_derivatives; s++)
>       {
>         values[r] += transform[r][s]*derivatives[s];
>       }// end loop over 's'
>     }// end loop over 'r'
>
>     // Delete pointer to array of derivatives on FIAT element
>     delete [] derivatives;
>
>     // Delete pointer to array of combinations of derivatives and transform
>     for (unsigned int r = 0; r < num_derivatives; r++)
>     {
>       delete [] combinations[r];
>     }// end loop over 'r'
>     delete [] combinations;
>     for (unsigned int r = 0; r < num_derivatives; r++)
>     {
>       delete [] transform[r];
>     }// end loop over 'r'
>     delete [] transform;
>   }
>
>   /// Evaluate order n derivatives of all basis functions at given point in cell
>   virtual void evaluate_basis_derivatives_all(unsigned int n,
>                                               double* values,
>                                               const double* coordinates,
>                                               const ufc::cell& c) const
>   {
>     // Compute number of derivatives.
>     unsigned int num_derivatives = 1;
>     for (unsigned int r = 0; r < n; r++)
>     {
>       num_derivatives *= 2;
>     }// end loop over 'r'
>
>     // Helper variable to hold values of a single dof.
>     double *dof_values = new double[num_derivatives];
>     for (unsigned int r = 0; r < num_derivatives; r++)
>     {
>       dof_values[r] = 0.000000000000000;
>     }// end loop over 'r'
>
>     // Loop dofs and call evaluate_basis_derivatives.
>     for (unsigned int r = 0; r < 3; r++)
>     {
>       evaluate_basis_derivatives(r, n, dof_values, coordinates, c);
>       for (unsigned int s = 0; s < num_derivatives; s++)
>       {
>         values[r*num_derivatives + s] = dof_values[s];
>       }// end loop over 's'
>     }// end loop over 'r'
>
>     // Delete pointer.
>     delete [] dof_values;
>   }
>
>   /// Evaluate linear functional for dof i on the function f
>   virtual double evaluate_dof(unsigned int i,
>                               const ufc::function& f,
>                               const ufc::cell& c) const
>   {
>     // Declare variables for result of evaluation.
>     double vals[1];
>
>     // Declare variable for physical coordinates.
>     double y[2];
>     const double * const * x = c.coordinates;
>     switch (i)
>     {
>     case 0:
>       {
>         y[0] = x[0][0];
>       y[1] = x[0][1];
>       f.evaluate(vals, y, c);
>       return vals[0];
>         break;
>       }
>     case 1:
>       {
>         y[0] = x[1][0];
>       y[1] = x[1][1];
>       f.evaluate(vals, y, c);
>       return vals[0];
>         break;
>       }
>     case 2:
>       {
>         y[0] = x[2][0];
>       y[1] = x[2][1];
>       f.evaluate(vals, y, c);
>       return vals[0];
>         break;
>       }
>     }
>
>     return 0.000000000000000;
>   }
>
>   /// Evaluate linear functionals for all dofs on the function f
>   virtual void evaluate_dofs(double* values,
>                              const ufc::function& f,
>                              const ufc::cell& c) const
>   {
>     // Declare variables for result of evaluation.
>     double vals[1];
>
>     // Declare variable for physical coordinates.
>     double y[2];
>     const double * const * x = c.coordinates;
>     y[0] = x[0][0];
>     y[1] = x[0][1];
>     f.evaluate(vals, y, c);
>     values[0] = vals[0];
>     y[0] = x[1][0];
>     y[1] = x[1][1];
>     f.evaluate(vals, y, c);
>     values[1] = vals[0];
>     y[0] = x[2][0];
>     y[1] = x[2][1];
>     f.evaluate(vals, y, c);
>     values[2] = vals[0];
>   }
>
>   /// Interpolate vertex values from dof values
>   virtual void interpolate_vertex_values(double* vertex_values,
>                                          const double* dof_values,
>                                          const ufc::cell& c) const
>   {
>     // Evaluate function and change variables
>     vertex_values[0] = dof_values[0];
>     vertex_values[1] = dof_values[1];
>     vertex_values[2] = dof_values[2];
>   }
>
>   /// Return the number of sub elements (for a mixed element)
>   virtual unsigned int num_sub_elements() const
>   {
>     return 0;
>   }
>
>   /// Create a new finite element for sub element i (for a mixed element)
>   virtual ufc::finite_element* create_sub_element(unsigned int i) const
>   {
> return 0;
>   }
>
> };
>
> /// This class defines the interface for a local-to-global mapping of
> /// degrees of freedom (dofs).
>
>
> class poisson_auxiliary_dof_map_0: public ufc::dof_map
> {
> private:
>
>   unsigned int _global_dimension;
> public:
>
>   /// Constructor
>   poisson_auxiliary_dof_map_0() :ufc::dof_map()
>   {
>     _global_dimension = 0;
>   }
>   /// Destructor
>   virtual ~poisson_auxiliary_dof_map_0()
>   {
>     // Do nothing
>   }
>
>   /// Return a string identifying the dof map
>   virtual const char* signature() const
>   {
>     return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)";
>   }
>
>   /// Return true iff mesh entities of topological dimension d are needed
>   virtual bool needs_mesh_entities(unsigned int d) const
>   {
>     switch (d)
>     {
>     case 0:
>       {
>         return true;
>         break;
>       }
>     case 1:
>       {
>         return false;
>         break;
>       }
>     case 2:
>       {
>         return false;
>         break;
>       }
>     }
>
>     return false;
>   }
>
>   /// Initialize dof map for mesh (return true iff init_cell() is needed)
>   virtual bool init_mesh(const ufc::mesh& m)
>   {
>     _global_dimension = m.num_entities[0];
>     return false;
>   }
>
>   /// Initialize dof map for given cell
>   virtual void init_cell(const ufc::mesh& m,
>                          const ufc::cell& c)
>   {
>     // Do nothing
>   }
>
>   /// Finish initialization of dof map for cells
>   virtual void init_cell_finalize()
>   {
>     // Do nothing
>   }
>
>   /// Return the dimension of the global finite element function space
>   virtual unsigned int global_dimension() const
>   {
>     return _global_dimension;
>   }
>
>   /// Return the dimension of the local finite element function space for a cell
>   virtual unsigned int local_dimension(const ufc::cell& c) const
>   {
>     return 3;
>   }
>
>   /// Return the maximum dimension of the local finite element function space
>   virtual unsigned int max_local_dimension() const
>   {
>     return 3;
>   }
>
>
>   // Return the geometric dimension of the coordinates this dof map provides
>   virtual unsigned int geometric_dimension() const
>   {
>     return 2;
>   }
>
>   /// Return the number of dofs on each cell facet
>   virtual unsigned int num_facet_dofs() const
>   {
>     return 2;
>   }
>
>   /// Return the number of dofs associated with each cell entity of dimension d
>   virtual unsigned int num_entity_dofs(unsigned int d) const
>   {
>     switch (d)
>     {
>     case 0:
>       {
>         return 1;
>         break;
>       }
>     case 1:
>       {
>         return 0;
>         break;
>       }
>     case 2:
>       {
>         return 0;
>         break;
>       }
>     }
>
>     return 0;
>   }
>
>   /// Tabulate the local-to-global mapping of dofs on a cell
>   virtual void tabulate_dofs(unsigned int* dofs,
>                              const ufc::mesh& m,
>                              const ufc::cell& c) const
>   {
>     dofs[0] = c.entity_indices[0][0];
>     dofs[1] = c.entity_indices[0][1];
>     dofs[2] = c.entity_indices[0][2];
>   }
>
>   /// Tabulate the local-to-local mapping from facet dofs to cell dofs
>   virtual void tabulate_facet_dofs(unsigned int* dofs,
>                                    unsigned int facet) const
>   {
>     switch (facet)
>     {
>     case 0:
>       {
>         dofs[0] = 1;
>       dofs[1] = 2;
>         break;
>       }
>     case 1:
>       {
>         dofs[0] = 0;
>       dofs[1] = 2;
>         break;
>       }
>     case 2:
>       {
>         dofs[0] = 0;
>       dofs[1] = 1;
>         break;
>       }
>     }
>
>   }
>
>   /// Tabulate the local-to-local mapping of dofs on entity (d, i)
>   virtual void tabulate_entity_dofs(unsigned int* dofs,
>                                     unsigned int d, unsigned int i) const
>   {
>     if (d > 2)
>     {
>     throw std::runtime_error("d is larger than dimension (2)");
>     }
>
>     switch (d)
>     {
>     case 0:
>       {
>         if (i > 2)
>       {
>       throw std::runtime_error("i is larger than number of entities (2)");
>       }
>
>       switch (i)
>       {
>       case 0:
>         {
>           dofs[0] = 0;
>           break;
>         }
>       case 1:
>         {
>           dofs[0] = 1;
>           break;
>         }
>       case 2:
>         {
>           dofs[0] = 2;
>           break;
>         }
>       }
>
>         break;
>       }
>     case 1:
>       {
>
>         break;
>       }
>     case 2:
>       {
>
>         break;
>       }
>     }
>
>   }
>
>   /// Tabulate the coordinates of all dofs on a cell
>   virtual void tabulate_coordinates(double** coordinates,
>                                     const ufc::cell& c) const
>   {
>     const double * const * x = c.coordinates;
>
>     coordinates[0][0] = x[0][0];
>     coordinates[0][1] = x[0][1];
>     coordinates[1][0] = x[1][0];
>     coordinates[1][1] = x[1][1];
>     coordinates[2][0] = x[2][0];
>     coordinates[2][1] = x[2][1];
>   }
>
>   /// Return the number of sub dof maps (for a mixed element)
>   virtual unsigned int num_sub_dof_maps() const
>   {
>     return 0;
>   }
>
>   /// Create a new dof_map for sub dof map i (for a mixed element)
>   virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
>   {
> return 0;
>   }
>
> };
>
> /// This class defines the interface for the assembly of the global
> /// tensor corresponding to a form with r + n arguments, that is, a
> /// mapping
> ///
> ///     a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R
> ///
> /// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r
> /// global tensor A is defined by
> ///
> ///     A = a(V1, V2, ..., Vr, w1, w2, ..., wn),
> ///
> /// where each argument Vj represents the application to the
> /// sequence of basis functions of Vj and w1, w2, ..., wn are given
> /// fixed functions (coefficients).
>
> class poisson_auxiliary_form_0: public ufc::form
> {
>
> public:
>
>   /// Constructor
>   poisson_auxiliary_form_0() : ufc::form()
>   {
>     // Do nothing
>   }
>
>   /// Destructor
>   virtual ~poisson_auxiliary_form_0()
>   {
>     // Do nothing
>   }
>
>   /// Return a string identifying the form
>   virtual const char* signature() const
>   {
>     return "auxiliary form";
>   }
>
>   /// Return the rank of the global tensor (r)
>   virtual unsigned int rank() const
>   {
>     return 0;
>   }
>
>   /// Return the number of coefficients (n)
>   virtual unsigned int num_coefficients() const
>   {
>     return 0;
>   }
>
>   /// Return the number of cell integrals
>   virtual unsigned int num_cell_integrals() const
>   {
>     return 0;
>   }
>
>   /// Return the number of exterior facet integrals
>   virtual unsigned int num_exterior_facet_integrals() const
>   {
>     return 0;
>   }
>
>   /// Return the number of interior facet integrals
>   virtual unsigned int num_interior_facet_integrals() const
>   {
>     return 0;
>   }
>
>   /// Create a new finite element for argument function i
>   virtual ufc::finite_element* create_finite_element(unsigned int i) const
>   {
>     switch (i)
>     {
>     case 0:
>       {
>         return new poisson_finite_element_0();
>         break;
>       }
>     }
>
>     return 0;
>   }
>
>   /// Create a new dof map for argument function i
>   virtual ufc::dof_map* create_dof_map(unsigned int i) const
>   {
> switch (i)
> {
> case 0:
>   {
>     return new poisson_auxiliary_dof_map_0();
>     break;
>   }
> }
>
> return 0;
>   }
>
>   /// Create a new cell integral on sub domain i
>   virtual ufc::cell_integral* create_cell_integral(unsigned int i) const
>   {
>     return 0;
>   }
>
>   /// Create a new exterior facet integral on sub domain i
>   virtual ufc::exterior_facet_integral* create_exterior_facet_integral(unsigned int i) const
>   {
>     return 0;
>   }
>
>   /// Create a new interior facet integral on sub domain i
>   virtual ufc::interior_facet_integral* create_interior_facet_integral(unsigned int i) const
>   {
>     return 0;
>   }
>
> };
>
> /// This class defines the interface for the assembly of the global
> /// tensor corresponding to a form with r + n arguments, that is, a
> /// mapping
> ///
> ///     a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R
> ///
> /// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r
> /// global tensor A is defined by
> ///
> ///     A = a(V1, V2, ..., Vr, w1, w2, ..., wn),
> ///
> /// where each argument Vj represents the application to the
> /// sequence of basis functions of Vj and w1, w2, ..., wn are given
> /// fixed functions (coefficients).
>
> class poisson_auxiliary_form_1: public ufc::form
> {
>
> public:
>
>   /// Constructor
>   poisson_auxiliary_form_1() : ufc::form()
>   {
>     // Do nothing
>   }
>
>   /// Destructor
>   virtual ~poisson_auxiliary_form_1()
>   {
>     // Do nothing
>   }
>
>   /// Return a string identifying the form
>   virtual const char* signature() const
>   {
>     return "auxiliary form";
>   }
>
>   /// Return the rank of the global tensor (r)
>   virtual unsigned int rank() const
>   {
>     return 0;
>   }
>
>   /// Return the number of coefficients (n)
>   virtual unsigned int num_coefficients() const
>   {
>     return 0;
>   }
>
>   /// Return the number of cell integrals
>   virtual unsigned int num_cell_integrals() const
>   {
>     return 0;
>   }
>
>   /// Return the number of exterior facet integrals
>   virtual unsigned int num_exterior_facet_integrals() const
>   {
>     return 0;
>   }
>
>   /// Return the number of interior facet integrals
>   virtual unsigned int num_interior_facet_integrals() const
>   {
>     return 0;
>   }
>
>   /// Create a new finite element for argument function i
>   virtual ufc::finite_element* create_finite_element(unsigned int i) const
>   {
>     switch (i)
>     {
>     case 0:
>       {
>         return new poisson_finite_element_0();
>         break;
>       }
>     }
>
>     return 0;
>   }
>
>   /// Create a new dof map for argument function i
>   virtual ufc::dof_map* create_dof_map(unsigned int i) const
>   {
> switch (i)
> {
> case 0:
>   {
>     return new poisson_auxiliary_dof_map_0();
>     break;
>   }
> }
>
> return 0;
>   }
>
>   /// Create a new cell integral on sub domain i
>   virtual ufc::cell_integral* create_cell_integral(unsigned int i) const
>   {
>     return 0;
>   }
>
>   /// Create a new exterior facet integral on sub domain i
>   virtual ufc::exterior_facet_integral* create_exterior_facet_integral(unsigned int i) const
>   {
>     return 0;
>   }
>
>   /// Create a new interior facet integral on sub domain i
>   virtual ufc::interior_facet_integral* create_interior_facet_integral(unsigned int i) const
>   {
>     return 0;
>   }
>
> };
>
> /// This class defines the interface for post-processing on vector x
> /// to obtain x0, u and j where,
> ///
> /// - x is the solution vector containing standard and enriched degrees of freedom
> /// defined on continuous/discontinuous space
> /// - u is the standard part of solution vector defined on continuous space
> /// - j is the enriched part pf solution vector defined on continuous space
> /// - x0 is the result vector, equall to u + j, defined on continuous space
> /// by considering enrichement function
> //
>
> // Dolfin includes
> #include <dolfin/common/NoDeleter.h>
> #include <dolfin/mesh/Mesh.h>
> #include <dolfin/fem/DofMap.h>
> #include <dolfin/la/GenericVector.h>
>
> // PartitionOfUnity includes
> #include <pum/PostProcess.h>
> #include <pum/FunctionSpace.h>
> #include <pum/PUM.h>
> #include <pum/GenericSurface.h>
>
> namespace Poisson
> {
>   class PostProcess:  public pum::PostProcess
>   {
>     const dolfin::Mesh& mesh;
>     pum::FunctionSpace& function_space;
>
>   public:
>
>     /// Constructor
>     PostProcess(pum::FunctionSpace& function_space):
>                 pum::PostProcess(function_space.mesh()), mesh(function_space.mesh()),
>                 function_space(function_space)
>     {
>       // Do nothing
>     }
>
>     /// Destructor
>     ~PostProcess()
>     {
>        // Do nothing
>     }
>
>     /// Return a string identifying the underling element
>     const char* signature() const
>     {
>       return "Interpolating results to the continuous space of EnrichedElement(FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), ElementRestriction(FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), Measure('surface', 0, None)))";
>     }
>
>     /// Obtain result vector 'x0' from solution vector 'x'
>     void interpolate(const dolfin::GenericVector& x, dolfin::GenericVector& x0) const
>     {
>
>       // Compute number of standard dofs for field 0
>       dolfin::DofMap dof_map_0(boost::shared_ptr<ufc::dof_map>(new poisson_dof_map_0()), mesh);
>       unsigned int num_standard_dofs_0 = dof_map_0.global_dimension();
>
>       double value;
>       double h;
>
>       /// Selecting standard degrees of freedom related to field 0 from the solution vector
>       double* values_0 = new double[num_standard_dofs_0];
>       unsigned int* positions_0 = new unsigned int [num_standard_dofs_0];
>
>       for (unsigned int i = 0; i < num_standard_dofs_0; ++i)
>         positions_0[i] = i;
>
>       x.get(values_0, num_standard_dofs_0, positions_0);
>       x0.set(values_0, num_standard_dofs_0, positions_0);
>
>       x0.apply("insert");
>
>       const std::vector<const pum::GenericPUM*>& pums = function_space.pums;
>
>       /// Selecting enriched degrees of freedom related to field 0 from the solution vector
>       std::vector <std::vector<unsigned int> > enhanced_dof_maps_0;
>       enhanced_dof_maps_0.resize(num_standard_dofs_0);
>
>       std::vector<unsigned int> enhanced_dof_values_0;
>       enhanced_dof_values_0.resize(num_standard_dofs_0);
>
>       compute_enhanced_dof_maps(*pums[0], dof_map_0, enhanced_dof_maps_0);
>       compute_enhanced_dof_values(*pums[0], dof_map_0, enhanced_dof_values_0);
>
>       //compute_enhanced_dof_maps(pum_0, dof_map_0, enhanced_dof_maps_0);
>       //compute_enhanced_dof_values(pum_0, dof_map_0, enhanced_dof_values_0);
>
>       for (unsigned int i = 0; i != num_standard_dofs_0; ++i)
>       {
>         unsigned int pos = i;
>
>         for (std::vector<unsigned int>::const_iterator it = enhanced_dof_maps_0[i].begin();
>                              it != enhanced_dof_maps_0[i].end(); ++it)
>         {
>           h = enhanced_dof_values_0[i];
>           unsigned int pos_n = *it + num_standard_dofs_0;
>
>           x.get(&value, 1, &pos_n);
>           value *= h;
>           x0.add(&value, 1, &pos);
>         }
>       }
>
>
>       // memory clean up
>
>       delete[] values_0;
>       delete[] positions_0;
>
>       x0.apply("add");
>     }
>
>     /// Obtain continuous u and discontinuous j parts of solution vector 'x'
>     void interpolate(const dolfin::GenericVector& x, dolfin::GenericVector& u, dolfin::GenericVector& j) const
>     {
>
>       // Compute number of standard dofs for field 0
>       dolfin::DofMap dof_map_0(boost::shared_ptr<ufc::dof_map>(new poisson_dof_map_0()), mesh);
>       unsigned int num_standard_dofs_0 = dof_map_0.global_dimension();
>
>       double value;
>
>       /// Selecting standard degrees of freedom related to field 0 from the solution vector
>       double* values_0 = new double[num_standard_dofs_0];
>       unsigned int* positions_0 = new unsigned int [num_standard_dofs_0];
>
>       for (unsigned int i = 0; i < num_standard_dofs_0; ++i)
>         positions_0[i] = i;
>
>       x.get(values_0, num_standard_dofs_0, positions_0);
>       u.set(values_0, num_standard_dofs_0, positions_0);
>
>
>       const std::vector<const pum::GenericPUM*>& pums = function_space.pums;
>
>       /// Selecting enriched degrees of freedom related to field 0 from the solution vector
>       std::vector <std::vector<unsigned int> > enhanced_dof_maps_0;
>       enhanced_dof_maps_0.resize(num_standard_dofs_0);
>
>       // Compute enhanced dof maps
>       compute_enhanced_dof_maps(*pums[0], dof_map_0, enhanced_dof_maps_0);
>
>
>       for (unsigned int i = 0; i != num_standard_dofs_0; ++i)
>       {
>         unsigned int pos = i ;
>
>         for (std::vector<unsigned int>::const_iterator it = enhanced_dof_maps_0[i].begin();
>                            it != enhanced_dof_maps_0[i].end(); ++it)
>         {
>           unsigned int pos_n = *it + num_standard_dofs_0;
>
>           x.get(&value, 1, &pos_n);
>           j.set(&value, 1, &pos);
>         }
>       }
>
>
>       // memory clean up
>
>       delete[] values_0;
>       delete[] positions_0;
>
>       u.apply("insert");
>       j.apply("insert");
>     }
>
>   };
> }
>
> // DOLFIN wrappers
>
> // Standard library includes
> #include <string>
>
> // DOLFIN includes
> #include <dolfin/common/NoDeleter.h>
> #include <dolfin/fem/FiniteElement.h>
> #include <dolfin/fem/DofMap.h>
> #include <dolfin/fem/Form.h>
> #include <dolfin/function/FunctionSpace.h>
> #include <dolfin/function/Function.h>
> #include <dolfin/function/GenericFunction.h>
> #include <dolfin/function/CoefficientAssigner.h>
>
> namespace Poisson
> {
>
> class CoefficientSpace_f: public dolfin::FunctionSpace
> {
> public:
>
>
>   CoefficientSpace_f(const dolfin::Mesh & mesh):
>       dolfin::FunctionSpace(dolfin::reference_to_no_delete_pointer(mesh),
>                             boost::shared_ptr<const dolfin::FiniteElement>(new dolfin::FiniteElement
>                             (boost::shared_ptr<ufc::finite_element>(new poisson_finite_element_0()))),
>                             boost::shared_ptr<const dolfin::DofMap>(new dolfin::DofMap(boost::shared_ptr<ufc::dof_map>
>                             (new poisson_dof_map_0()), mesh)))
>   {
>     // Do nothing
>   }
>
>   CoefficientSpace_f(dolfin::Mesh & mesh):
>     dolfin::FunctionSpace(dolfin::reference_to_no_delete_pointer(mesh),
>                           boost::shared_ptr<const dolfin::FiniteElement>(new dolfin::FiniteElement(boost::shared_ptr<ufc::finite_element>(new poisson_finite_element_0()))),
>                           boost::shared_ptr<const dolfin::DofMap>(new dolfin::DofMap(boost::shared_ptr<ufc::dof_map>(new poisson_dof_map_0()), mesh)))
>   {
>     // Do nothing
>   }
>
>   CoefficientSpace_f(boost::shared_ptr<dolfin::Mesh> mesh):
>       dolfin::FunctionSpace(mesh,
>                             boost::shared_ptr<const dolfin::FiniteElement>(new dolfin::FiniteElement(boost::shared_ptr<ufc::finite_element>(new poisson_finite_element_0()))),
>                             boost::shared_ptr<const dolfin::DofMap>(new dolfin::DofMap(boost::shared_ptr<ufc::dof_map>(new poisson_dof_map_0()), *mesh)))
>   {
>       // Do nothing
>   }
>
>   CoefficientSpace_f(boost::shared_ptr<const dolfin::Mesh> mesh):
>       dolfin::FunctionSpace(mesh,
>                             boost::shared_ptr<const dolfin::FiniteElement>(new dolfin::FiniteElement(boost::shared_ptr<ufc::finite_element>(new poisson_finite_element_0()))),
>                             boost::shared_ptr<const dolfin::DofMap>(new dolfin::DofMap(boost::shared_ptr<ufc::dof_map>(new poisson_dof_map_0()), *mesh)))
>   {
>       // Do nothing
>   }
>
>
>   ~CoefficientSpace_f()
>   {
>   }
>
> };
>
> class CoefficientSpace_g: public dolfin::FunctionSpace
> {
> public:
>
>
>   CoefficientSpace_g(const dolfin::Mesh & mesh):
>       dolfin::FunctionSpace(dolfin::reference_to_no_delete_pointer(mesh),
>                             boost::shared_ptr<const dolfin::FiniteElement>(new dolfin::FiniteElement
>                             (boost::shared_ptr<ufc::finite_element>(new poisson_finite_element_0()))),
>                             boost::shared_ptr<const dolfin::DofMap>(new dolfin::DofMap(boost::shared_ptr<ufc::dof_map>
>                             (new poisson_dof_map_0()), mesh)))
>   {
>     // Do nothing
>   }
>
>   CoefficientSpace_g(dolfin::Mesh & mesh):
>     dolfin::FunctionSpace(dolfin::reference_to_no_delete_pointer(mesh),
>                           boost::shared_ptr<const dolfin::FiniteElement>(new dolfin::FiniteElement(boost::shared_ptr<ufc::finite_element>(new poisson_finite_element_0()))),
>                           boost::shared_ptr<const dolfin::DofMap>(new dolfin::DofMap(boost::shared_ptr<ufc::dof_map>(new poisson_dof_map_0()), mesh)))
>   {
>     // Do nothing
>   }
>
>   CoefficientSpace_g(boost::shared_ptr<dolfin::Mesh> mesh):
>       dolfin::FunctionSpace(mesh,
>                             boost::shared_ptr<const dolfin::FiniteElement>(new dolfin::FiniteElement(boost::shared_ptr<ufc::finite_element>(new poisson_finite_element_0()))),
>                             boost::shared_ptr<const dolfin::DofMap>(new dolfin::DofMap(boost::shared_ptr<ufc::dof_map>(new poisson_dof_map_0()), *mesh)))
>   {
>       // Do nothing
>   }
>
>   CoefficientSpace_g(boost::shared_ptr<const dolfin::Mesh> mesh):
>       dolfin::FunctionSpace(mesh,
>                             boost::shared_ptr<const dolfin::FiniteElement>(new dolfin::FiniteElement(boost::shared_ptr<ufc::finite_element>(new poisson_finite_element_0()))),
>                             boost::shared_ptr<const dolfin::DofMap>(new dolfin::DofMap(boost::shared_ptr<ufc::dof_map>(new poisson_dof_map_0()), *mesh)))
>   {
>       // Do nothing
>   }
>
>
>   ~CoefficientSpace_g()
>   {
>   }
>
> };
>
> class CoefficientSpace_w: public dolfin::FunctionSpace
> {
> public:
>
>
>   CoefficientSpace_w(const dolfin::Mesh & mesh):
>       dolfin::FunctionSpace(dolfin::reference_to_no_delete_pointer(mesh),
>                             boost::shared_ptr<const dolfin::FiniteElement>(new dolfin::FiniteElement
>                             (boost::shared_ptr<ufc::finite_element>(new poisson_finite_element_0()))),
>                             boost::shared_ptr<const dolfin::DofMap>(new dolfin::DofMap(boost::shared_ptr<ufc::dof_map>
>                             (new poisson_dof_map_0()), mesh)))
>   {
>     // Do nothing
>   }
>
>   CoefficientSpace_w(dolfin::Mesh & mesh):
>     dolfin::FunctionSpace(dolfin::reference_to_no_delete_pointer(mesh),
>                           boost::shared_ptr<const dolfin::FiniteElement>(new dolfin::FiniteElement(boost::shared_ptr<ufc::finite_element>(new poisson_finite_element_0()))),
>                           boost::shared_ptr<const dolfin::DofMap>(new dolfin::DofMap(boost::shared_ptr<ufc::dof_map>(new poisson_dof_map_0()), mesh)))
>   {
>     // Do nothing
>   }
>
>   CoefficientSpace_w(boost::shared_ptr<dolfin::Mesh> mesh):
>       dolfin::FunctionSpace(mesh,
>                             boost::shared_ptr<const dolfin::FiniteElement>(new dolfin::FiniteElement(boost::shared_ptr<ufc::finite_element>(new poisson_finite_element_0()))),
>                             boost::shared_ptr<const dolfin::DofMap>(new dolfin::DofMap(boost::shared_ptr<ufc::dof_map>(new poisson_dof_map_0()), *mesh)))
>   {
>       // Do nothing
>   }
>
>   CoefficientSpace_w(boost::shared_ptr<const dolfin::Mesh> mesh):
>       dolfin::FunctionSpace(mesh,
>                             boost::shared_ptr<const dolfin::FiniteElement>(new dolfin::FiniteElement(boost::shared_ptr<ufc::finite_element>(new poisson_finite_element_0()))),
>                             boost::shared_ptr<const dolfin::DofMap>(new dolfin::DofMap(boost::shared_ptr<ufc::dof_map>(new poisson_dof_map_0()), *mesh)))
>   {
>       // Do nothing
>   }
>
>
>   ~CoefficientSpace_w()
>   {
>   }
>
> };
>
> class Form_0_FunctionSpace_0: public pum::FunctionSpace
> {
> public:
>
>
>   Form_0_FunctionSpace_0(const dolfin::Mesh & mesh ,const std::vector<const pum::GenericPUM*>& pums):
>       pum::FunctionSpace(dolfin::reference_to_no_delete_pointer(mesh),
>                             boost::shared_ptr<const dolfin::FiniteElement>(new dolfin::FiniteElement
>                             (boost::shared_ptr<ufc::finite_element>(new poisson_finite_element_1()))),
>                             boost::shared_ptr<const dolfin::DofMap>(new dolfin::DofMap(boost::shared_ptr<ufc::dof_map>
>                             (new poisson_dof_map_1(pums)), mesh)) ,pums)
>   {
>     // Do nothing
>   }
>
>   Form_0_FunctionSpace_0(dolfin::Mesh & mesh ,const std::vector<const pum::GenericPUM*>& pums):
>     pum::FunctionSpace(dolfin::reference_to_no_delete_pointer(mesh),
>                           boost::shared_ptr<const dolfin::FiniteElement>(new dolfin::FiniteElement(boost::shared_ptr<ufc::finite_element>(new poisson_finite_element_1()))),
>                           boost::shared_ptr<const dolfin::DofMap>(new dolfin::DofMap(boost::shared_ptr<ufc::dof_map>(new poisson_dof_map_1(pums)), mesh)) ,pums)
>   {
>     // Do nothing
>   }
>
>   Form_0_FunctionSpace_0(boost::shared_ptr<dolfin::Mesh> mesh ,const std::vector<const pum::GenericPUM*>& pums):
>       pum::FunctionSpace(mesh,
>                             boost::shared_ptr<const dolfin::FiniteElement>(new dolfin::FiniteElement(boost::shared_ptr<ufc::finite_element>(new poisson_finite_element_1()))),
>                             boost::shared_ptr<const dolfin::DofMap>(new dolfin::DofMap(boost::shared_ptr<ufc::dof_map>(new poisson_dof_map_1(pums)), *mesh)) ,pums)
>   {
>       // Do nothing
>   }
>
>   Form_0_FunctionSpace_0(boost::shared_ptr<const dolfin::Mesh> mesh ,const std::vector<const pum::GenericPUM*>& pums):
>       pum::FunctionSpace(mesh,
>                             boost::shared_ptr<const dolfin::FiniteElement>(new dolfin::FiniteElement(boost::shared_ptr<ufc::finite_element>(new poisson_finite_element_1()))),
>                             boost::shared_ptr<const dolfin::DofMap>(new dolfin::DofMap(boost::shared_ptr<ufc::dof_map>(new poisson_dof_map_1(pums)), *mesh)) ,pums)
>   {
>       // Do nothing
>   }
>
>
>   ~Form_0_FunctionSpace_0()
>   {
>   }
>
> };
>
> class Form_0_FunctionSpace_1: public pum::FunctionSpace
> {
> public:
>
>
>   Form_0_FunctionSpace_1(const dolfin::Mesh & mesh ,const std::vector<const pum::GenericPUM*>& pums):
>       pum::FunctionSpace(dolfin::reference_to_no_delete_pointer(mesh),
>                             boost::shared_ptr<const dolfin::FiniteElement>(new dolfin::FiniteElement
>                             (boost::shared_ptr<ufc::finite_element>(new poisson_finite_element_1()))),
>                             boost::shared_ptr<const dolfin::DofMap>(new dolfin::DofMap(boost::shared_ptr<ufc::dof_map>
>                             (new poisson_dof_map_1(pums)), mesh)) ,pums)
>   {
>     // Do nothing
>   }
>
>   Form_0_FunctionSpace_1(dolfin::Mesh & mesh ,const std::vector<const pum::GenericPUM*>& pums):
>     pum::FunctionSpace(dolfin::reference_to_no_delete_pointer(mesh),
>                           boost::shared_ptr<const dolfin::FiniteElement>(new dolfin::FiniteElement(boost::shared_ptr<ufc::finite_element>(new poisson_finite_element_1()))),
>                           boost::shared_ptr<const dolfin::DofMap>(new dolfin::DofMap(boost::shared_ptr<ufc::dof_map>(new poisson_dof_map_1(pums)), mesh)) ,pums)
>   {
>     // Do nothing
>   }
>
>   Form_0_FunctionSpace_1(boost::shared_ptr<dolfin::Mesh> mesh ,const std::vector<const pum::GenericPUM*>& pums):
>       pum::FunctionSpace(mesh,
>                             boost::shared_ptr<const dolfin::FiniteElement>(new dolfin::FiniteElement(boost::shared_ptr<ufc::finite_element>(new poisson_finite_element_1()))),
>                             boost::shared_ptr<const dolfin::DofMap>(new dolfin::DofMap(boost::shared_ptr<ufc::dof_map>(new poisson_dof_map_1(pums)), *mesh)) ,pums)
>   {
>       // Do nothing
>   }
>
>   Form_0_FunctionSpace_1(boost::shared_ptr<const dolfin::Mesh> mesh ,const std::vector<const pum::GenericPUM*>& pums):
>       pum::FunctionSpace(mesh,
>                             boost::shared_ptr<const dolfin::FiniteElement>(new dolfin::FiniteElement(boost::shared_ptr<ufc::finite_element>(new poisson_finite_element_1()))),
>                             boost::shared_ptr<const dolfin::DofMap>(new dolfin::DofMap(boost::shared_ptr<ufc::dof_map>(new poisson_dof_map_1(pums)), *mesh)) ,pums)
>   {
>       // Do nothing
>   }
>
>
>   ~Form_0_FunctionSpace_1()
>   {
>   }
>
> };
>
> typedef CoefficientSpace_w Form_0_FunctionSpace_2;
>
> class Form_0: public dolfin::Form
> {
> public:
>
>   // Constructor
>   Form_0(const pum::FunctionSpace& V0, const pum::FunctionSpace& V1):
>     dolfin::Form(2, 1), w(*this, 0)
>   {
>     _function_spaces[0] = reference_to_no_delete_pointer(V0);
>     _function_spaces[1] = reference_to_no_delete_pointer(V1);
>
>     _ufc_form = boost::shared_ptr<const ufc::form>(new poisson_form_0(V0.pums));
>   }
>
>   // Constructor
>   Form_0(const pum::FunctionSpace& V0, const pum::FunctionSpace& V1, dolfin::GenericFunction & w):
>     dolfin::Form(2, 1), w(*this, 0)
>   {
>     _function_spaces[0] = reference_to_no_delete_pointer(V0);
>     _function_spaces[1] = reference_to_no_delete_pointer(V1);
>
>     this->w = w;
>
>     _ufc_form = boost::shared_ptr<const ufc::form>(new poisson_form_0(V0.pums));
>   }
>
>   // Constructor
>   Form_0(const pum::FunctionSpace& V0, const pum::FunctionSpace& V1, boost::shared_ptr<dolfin::GenericFunction> w):
>     dolfin::Form(2, 1), w(*this, 0)
>   {
>     _function_spaces[0] = reference_to_no_delete_pointer(V0);
>     _function_spaces[1] = reference_to_no_delete_pointer(V1);
>
>     this->w = *w;
>
>     _ufc_form = boost::shared_ptr<const ufc::form>(new poisson_form_0(V0.pums));
>   }
>
>   // Constructor
>   Form_0(boost::shared_ptr<const pum::FunctionSpace> V0, boost::shared_ptr<const pum::FunctionSpace> V1):
>     dolfin::Form(2, 1), w(*this, 0)
>   {
>     _function_spaces[0] = V0;
>     _function_spaces[1] = V1;
>
>     _ufc_form = boost::shared_ptr<const ufc::form>(new poisson_form_0(V0->pums));
>   }
>
>   // Constructor
>   Form_0(boost::shared_ptr<const pum::FunctionSpace> V0, boost::shared_ptr<const pum::FunctionSpace> V1, dolfin::GenericFunction & w):
>     dolfin::Form(2, 1), w(*this, 0)
>   {
>     _function_spaces[0] = V0;
>     _function_spaces[1] = V1;
>
>     this->w = w;
>
>     _ufc_form = boost::shared_ptr<const ufc::form>(new poisson_form_0(V0->pums));
>   }
>
>   // Constructor
>   Form_0(boost::shared_ptr<const pum::FunctionSpace> V0, boost::shared_ptr<const pum::FunctionSpace> V1, boost::shared_ptr<dolfin::GenericFunction> w):
>     dolfin::Form(2, 1), w(*this, 0)
>   {
>     _function_spaces[0] = V0;
>     _function_spaces[1] = V1;
>
>     this->w = *w;
>
>     _ufc_form = boost::shared_ptr<const ufc::form>(new poisson_form_0(V0->pums));
>   }
>
>   // Destructor
>   ~Form_0()
>   {}
>
>   /// Return the number of the coefficient with this name
>   virtual dolfin::uint coefficient_number(const std::string& name) const
>   {
>     if(name == "w") return 0;
>     dolfin::error("Invalid coefficient.");
>     return 0;
>   }
>
>   /// Return the name of the coefficient with this number
>   virtual std::string coefficient_name(dolfin::uint i) const
>   {
>     switch(i)
>     {
>       case 0: return "w";
>     }
>     dolfin::error("Invalid coefficient.");
>     return "unnamed";
>   }
>
>   // Typedefs
>   typedef Form_0_FunctionSpace_0 TestSpace;
>   typedef Form_0_FunctionSpace_1 TrialSpace;
>   typedef Form_0_FunctionSpace_2 CoefficientSpace_w;
>
>   // Coefficients
>   dolfin::CoefficientAssigner w;
> };
>
> class Form_1_FunctionSpace_0: public pum::FunctionSpace
> {
> public:
>
>
>   Form_1_FunctionSpace_0(const dolfin::Mesh & mesh ,const std::vector<const pum::GenericPUM*>& pums):
>       pum::FunctionSpace(dolfin::reference_to_no_delete_pointer(mesh),
>                             boost::shared_ptr<const dolfin::FiniteElement>(new dolfin::FiniteElement
>                             (boost::shared_ptr<ufc::finite_element>(new poisson_finite_element_1()))),
>                             boost::shared_ptr<const dolfin::DofMap>(new dolfin::DofMap(boost::shared_ptr<ufc::dof_map>
>                             (new poisson_dof_map_1(pums)), mesh)) ,pums)
>   {
>     // Do nothing
>   }
>
>   Form_1_FunctionSpace_0(dolfin::Mesh & mesh ,const std::vector<const pum::GenericPUM*>& pums):
>     pum::FunctionSpace(dolfin::reference_to_no_delete_pointer(mesh),
>                           boost::shared_ptr<const dolfin::FiniteElement>(new dolfin::FiniteElement(boost::shared_ptr<ufc::finite_element>(new poisson_finite_element_1()))),
>                           boost::shared_ptr<const dolfin::DofMap>(new dolfin::DofMap(boost::shared_ptr<ufc::dof_map>(new poisson_dof_map_1(pums)), mesh)) ,pums)
>   {
>     // Do nothing
>   }
>
>   Form_1_FunctionSpace_0(boost::shared_ptr<dolfin::Mesh> mesh ,const std::vector<const pum::GenericPUM*>& pums):
>       pum::FunctionSpace(mesh,
>                             boost::shared_ptr<const dolfin::FiniteElement>(new dolfin::FiniteElement(boost::shared_ptr<ufc::finite_element>(new poisson_finite_element_1()))),
>                             boost::shared_ptr<const dolfin::DofMap>(new dolfin::DofMap(boost::shared_ptr<ufc::dof_map>(new poisson_dof_map_1(pums)), *mesh)) ,pums)
>   {
>       // Do nothing
>   }
>
>   Form_1_FunctionSpace_0(boost::shared_ptr<const dolfin::Mesh> mesh ,const std::vector<const pum::GenericPUM*>& pums):
>       pum::FunctionSpace(mesh,
>                             boost::shared_ptr<const dolfin::FiniteElement>(new dolfin::FiniteElement(boost::shared_ptr<ufc::finite_element>(new poisson_finite_element_1()))),
>                             boost::shared_ptr<const dolfin::DofMap>(new dolfin::DofMap(boost::shared_ptr<ufc::dof_map>(new poisson_dof_map_1(pums)), *mesh)) ,pums)
>   {
>       // Do nothing
>   }
>
>
>   ~Form_1_FunctionSpace_0()
>   {
>   }
>
> };
>
> typedef CoefficientSpace_f Form_1_FunctionSpace_1;
>
> typedef CoefficientSpace_g Form_1_FunctionSpace_2;
>
> class Form_1: public dolfin::Form
> {
> public:
>
>   // Constructor
>   Form_1(const pum::FunctionSpace& V0):
>     dolfin::Form(1, 2), f(*this, 0), g(*this, 1)
>   {
>     _function_spaces[0] = reference_to_no_delete_pointer(V0);
>
>     _ufc_form = boost::shared_ptr<const ufc::form>(new poisson_form_1(V0.pums));
>   }
>
>   // Constructor
>   Form_1(const pum::FunctionSpace& V0, dolfin::GenericFunction & f, dolfin::GenericFunction & g):
>     dolfin::Form(1, 2), f(*this, 0), g(*this, 1)
>   {
>     _function_spaces[0] = reference_to_no_delete_pointer(V0);
>
>     this->f = f;
>     this->g = g;
>
>     _ufc_form = boost::shared_ptr<const ufc::form>(new poisson_form_1(V0.pums));
>   }
>
>   // Constructor
>   Form_1(const pum::FunctionSpace& V0, boost::shared_ptr<dolfin::GenericFunction> f, boost::shared_ptr<dolfin::GenericFunction> g):
>     dolfin::Form(1, 2), f(*this, 0), g(*this, 1)
>   {
>     _function_spaces[0] = reference_to_no_delete_pointer(V0);
>
>     this->f = *f;
>     this->g = *g;
>
>     _ufc_form = boost::shared_ptr<const ufc::form>(new poisson_form_1(V0.pums));
>   }
>
>   // Constructor
>   Form_1(boost::shared_ptr<const pum::FunctionSpace> V0):
>     dolfin::Form(1, 2), f(*this, 0), g(*this, 1)
>   {
>     _function_spaces[0] = V0;
>
>     _ufc_form = boost::shared_ptr<const ufc::form>(new poisson_form_1(V0->pums));
>   }
>
>   // Constructor
>   Form_1(boost::shared_ptr<const pum::FunctionSpace> V0, dolfin::GenericFunction & f, dolfin::GenericFunction & g):
>     dolfin::Form(1, 2), f(*this, 0), g(*this, 1)
>   {
>     _function_spaces[0] = V0;
>
>     this->f = f;
>     this->g = g;
>
>     _ufc_form = boost::shared_ptr<const ufc::form>(new poisson_form_1(V0->pums));
>   }
>
>   // Constructor
>   Form_1(boost::shared_ptr<const pum::FunctionSpace> V0, boost::shared_ptr<dolfin::GenericFunction> f, boost::shared_ptr<dolfin::GenericFunction> g):
>     dolfin::Form(1, 2), f(*this, 0), g(*this, 1)
>   {
>     _function_spaces[0] = V0;
>
>     this->f = *f;
>     this->g = *g;
>
>     _ufc_form = boost::shared_ptr<const ufc::form>(new poisson_form_1(V0->pums));
>   }
>
>   // Destructor
>   ~Form_1()
>   {}
>
>   /// Return the number of the coefficient with this name
>   virtual dolfin::uint coefficient_number(const std::string& name) const
>   {
>     if(name == "f") return 0;
>     else if(name == "g") return 1;
>     dolfin::error("Invalid coefficient.");
>     return 0;
>   }
>
>   /// Return the name of the coefficient with this number
>   virtual std::string coefficient_name(dolfin::uint i) const
>   {
>     switch(i)
>     {
>       case 0: return "f";
>       case 1: return "g";
>     }
>     dolfin::error("Invalid coefficient.");
>     return "unnamed";
>   }
>
>   // Typedefs
>   typedef Form_1_FunctionSpace_0 TestSpace;
>   typedef Form_1_FunctionSpace_1 CoefficientSpace_f;
>   typedef Form_1_FunctionSpace_2 CoefficientSpace_g;
>
>   // Coefficients
>   dolfin::CoefficientAssigner f;
>   dolfin::CoefficientAssigner g;
> };
>
> // Class typedefs
> typedef Form_0 BilinearForm;
> typedef Form_1 LinearForm;
> typedef Form_0::TestSpace FunctionSpace;
>
> } // namespace Poisson
>
> // DOLFIN wrappers
>
> // Standard library includes
> #include <string>
>
> // DOLFIN includes
> #include <dolfin/common/NoDeleter.h>
> #include <dolfin/fem/FiniteElement.h>
> #include <dolfin/fem/DofMap.h>
> #include <dolfin/fem/Form.h>
> #include <dolfin/function/FunctionSpace.h>
> #include <dolfin/function/Function.h>
> #include <dolfin/function/GenericFunction.h>
> #include <dolfin/function/CoefficientAssigner.h>
>
> namespace Poisson
> {
>
> class Form_auxiliary_0_FunctionSpace_auxiliary_0: public dolfin::FunctionSpace
> {
> public:
>
>
>   Form_auxiliary_0_FunctionSpace_auxiliary_0(const dolfin::Mesh & mesh):
>       dolfin::FunctionSpace(dolfin::reference_to_no_delete_pointer(mesh),
>                             boost::shared_ptr<const dolfin::FiniteElement>(new dolfin::FiniteElement
>                             (boost::shared_ptr<ufc::finite_element>(new poisson_auxiliary_finite_element_0()))),
>                             boost::shared_ptr<const dolfin::DofMap>(new dolfin::DofMap(boost::shared_ptr<ufc::dof_map>
>                             (new poisson_auxiliary_dof_map_0()), mesh)))
>   {
>     // Do nothing
>   }
>
>   Form_auxiliary_0_FunctionSpace_auxiliary_0(dolfin::Mesh & mesh):
>     dolfin::FunctionSpace(dolfin::reference_to_no_delete_pointer(mesh),
>                           boost::shared_ptr<const dolfin::FiniteElement>(new dolfin::FiniteElement(boost::shared_ptr<ufc::finite_element>(new poisson_auxiliary_finite_element_0()))),
>                           boost::shared_ptr<const dolfin::DofMap>(new dolfin::DofMap(boost::shared_ptr<ufc::dof_map>(new poisson_auxiliary_dof_map_0()), mesh)))
>   {
>     // Do nothing
>   }
>
>   Form_auxiliary_0_FunctionSpace_auxiliary_0(boost::shared_ptr<dolfin::Mesh> mesh):
>       dolfin::FunctionSpace(mesh,
>                             boost::shared_ptr<const dolfin::FiniteElement>(new dolfin::FiniteElement(boost::shared_ptr<ufc::finite_element>(new poisson_auxiliary_finite_element_0()))),
>                             boost::shared_ptr<const dolfin::DofMap>(new dolfin::DofMap(boost::shared_ptr<ufc::dof_map>(new poisson_auxiliary_dof_map_0()), *mesh)))
>   {
>       // Do nothing
>   }
>
>   Form_auxiliary_0_FunctionSpace_auxiliary_0(boost::shared_ptr<const dolfin::Mesh> mesh):
>       dolfin::FunctionSpace(mesh,
>                             boost::shared_ptr<const dolfin::FiniteElement>(new dolfin::FiniteElement(boost::shared_ptr<ufc::finite_element>(new poisson_auxiliary_finite_element_0()))),
>                             boost::shared_ptr<const dolfin::DofMap>(new dolfin::DofMap(boost::shared_ptr<ufc::dof_map>(new poisson_auxiliary_dof_map_0()), *mesh)))
>   {
>       // Do nothing
>   }
>
>
>   ~Form_auxiliary_0_FunctionSpace_auxiliary_0()
>   {
>   }
>
> };
>
> class Form_auxiliary_0: public dolfin::Form
> {
> public:
>
>   // Constructor
>   Form_auxiliary_0(const dolfin::FunctionSpace& V0):
>     dolfin::Form(1, 0)
>   {
>     _function_spaces[0] = reference_to_no_delete_pointer(V0);
>
>     _ufc_form = boost::shared_ptr<const ufc::form>(new poisson_auxiliary_form_0());
>   }
>
>   // Constructor
>   Form_auxiliary_0(boost::shared_ptr<const dolfin::FunctionSpace> V0):
>     dolfin::Form(1, 0)
>   {
>     _function_spaces[0] = V0;
>
>     _ufc_form = boost::shared_ptr<const ufc::form>(new poisson_auxiliary_form_0());
>   }
>
>   // Destructor
>   ~Form_auxiliary_0()
>   {}
>
>   /// Return the number of the coefficient with this name
>   virtual dolfin::uint coefficient_number(const std::string& name) const
>   {
>     dolfin::error("No coefficients.");
>     return 0;
>   }
>
>   /// Return the name of the coefficient with this number
>   virtual std::string coefficient_name(dolfin::uint i) const
>   {
>     dolfin::error("No coefficients.");
>     return "unnamed";
>   }
>
>   // Typedefs
>   typedef Form_auxiliary_0_FunctionSpace_auxiliary_0 TestSpace;
>
>   // Coefficients
> };
>
> class Form_auxiliary_1_FunctionSpace_auxiliary_0: public dolfin::FunctionSpace
> {
> public:
>
>
>   Form_auxiliary_1_FunctionSpace_auxiliary_0(const dolfin::Mesh & mesh):
>       dolfin::FunctionSpace(dolfin::reference_to_no_delete_pointer(mesh),
>                             boost::shared_ptr<const dolfin::FiniteElement>(new dolfin::FiniteElement
>                             (boost::shared_ptr<ufc::finite_element>(new poisson_auxiliary_finite_element_0()))),
>                             boost::shared_ptr<const dolfin::DofMap>(new dolfin::DofMap(boost::shared_ptr<ufc::dof_map>
>                             (new poisson_auxiliary_dof_map_0()), mesh)))
>   {
>     // Do nothing
>   }
>
>   Form_auxiliary_1_FunctionSpace_auxiliary_0(dolfin::Mesh & mesh):
>     dolfin::FunctionSpace(dolfin::reference_to_no_delete_pointer(mesh),
>                           boost::shared_ptr<const dolfin::FiniteElement>(new dolfin::FiniteElement(boost::shared_ptr<ufc::finite_element>(new poisson_auxiliary_finite_element_0()))),
>                           boost::shared_ptr<const dolfin::DofMap>(new dolfin::DofMap(boost::shared_ptr<ufc::dof_map>(new poisson_auxiliary_dof_map_0()), mesh)))
>   {
>     // Do nothing
>   }
>
>   Form_auxiliary_1_FunctionSpace_auxiliary_0(boost::shared_ptr<dolfin::Mesh> mesh):
>       dolfin::FunctionSpace(mesh,
>                             boost::shared_ptr<const dolfin::FiniteElement>(new dolfin::FiniteElement(boost::shared_ptr<ufc::finite_element>(new poisson_auxiliary_finite_element_0()))),
>                             boost::shared_ptr<const dolfin::DofMap>(new dolfin::DofMap(boost::shared_ptr<ufc::dof_map>(new poisson_auxiliary_dof_map_0()), *mesh)))
>   {
>       // Do nothing
>   }
>
>   Form_auxiliary_1_FunctionSpace_auxiliary_0(boost::shared_ptr<const dolfin::Mesh> mesh):
>       dolfin::FunctionSpace(mesh,
>                             boost::shared_ptr<const dolfin::FiniteElement>(new dolfin::FiniteElement(boost::shared_ptr<ufc::finite_element>(new poisson_auxiliary_finite_element_0()))),
>                             boost::shared_ptr<const dolfin::DofMap>(new dolfin::DofMap(boost::shared_ptr<ufc::dof_map>(new poisson_auxiliary_dof_map_0()), *mesh)))
>   {
>       // Do nothing
>   }
>
>
>   ~Form_auxiliary_1_FunctionSpace_auxiliary_0()
>   {
>   }
>
> };
>
> class Form_auxiliary_1: public dolfin::Form
> {
> public:
>
>   // Constructor
>   Form_auxiliary_1(const dolfin::FunctionSpace& V0):
>     dolfin::Form(1, 0)
>   {
>     _function_spaces[0] = reference_to_no_delete_pointer(V0);
>
>     _ufc_form = boost::shared_ptr<const ufc::form>(new poisson_auxiliary_form_1());
>   }
>
>   // Constructor
>   Form_auxiliary_1(boost::shared_ptr<const dolfin::FunctionSpace> V0):
>     dolfin::Form(1, 0)
>   {
>     _function_spaces[0] = V0;
>
>     _ufc_form = boost::shared_ptr<const ufc::form>(new poisson_auxiliary_form_1());
>   }
>
>   // Destructor
>   ~Form_auxiliary_1()
>   {}
>
>   /// Return the number of the coefficient with this name
>   virtual dolfin::uint coefficient_number(const std::string& name) const
>   {
>     dolfin::error("No coefficients.");
>     return 0;
>   }
>
>   /// Return the name of the coefficient with this number
>   virtual std::string coefficient_name(dolfin::uint i) const
>   {
>     dolfin::error("No coefficients.");
>     return "unnamed";
>   }
>
>   // Typedefs
>   typedef Form_auxiliary_1_FunctionSpace_auxiliary_0 TestSpace;
>
>   // Coefficients
> };
>
> // Class typedefs
> typedef Form_auxiliary_0::TestSpace FunctionSpace_auxiliary;
>
> } // namespace Poisson
>
> /// This class defines the interface for computing enriched function space
> /// and auxiliary function spaces
> ///
> //
>
> // Dolfin includes
> #include <dolfin/common/NoDeleter.h>
> #include <dolfin/mesh/Mesh.h>
> #include <dolfin/fem/DofMap.h>
>
> // PartitionOfUnity includes
> #include <pum/FunctionSpace.h>
> #include <pum/PUM.h>
> #include <pum/GenericSurface.h>
>
> namespace Poisson
> {
>   class FunctionSpaces
>   {
>     dolfin::Mesh& mesh;
>     std::vector<const pum::GenericSurface*>& surfaces;
>     std::vector<const pum::GenericPUM*> pums;
>
>
>     pum::PUM* pum_0;
>     dolfin::DofMap* dof_map_0;
>
>     /// Build PUM objects to intialize enriched FunctionSpace
>     void init()
>     {
>
>       // Create DofMap instance for the field 0
>       //dolfin::DofMap dof_map_0(boost::shared_ptr<ufc::dof_map>(new poisson_dof_map_0()), mesh);
>       dof_map_0 = new dolfin::DofMap(boost::shared_ptr<ufc::dof_map>(new poisson_dof_map_0()), mesh);
>
>       // Create PUM objects
>       pum_0 = new pum::PUM(surfaces, mesh, *dof_map_0);
>
>
>       // Push PUM objects to a vector
>       pums.push_back(pum_0);
>     }
>
>   public:
>
>     /// Constructor
>     FunctionSpaces(dolfin::Mesh& mesh, std::vector<const pum::GenericSurface*>& surfaces):
>                   mesh(mesh), surfaces(surfaces)
>     {
>       init();
>     }
>
>     /// Destructor
>     ~FunctionSpaces()
>     {
>
>       delete pum_0;
>       delete dof_map_0;
>     }
>
>     /// Return Enriched Function Space
>     pum::FunctionSpace space()
>     {
>        return FunctionSpace(mesh, pums);
>     }
>
>     /// Return Enriched Function Space
>     dolfin::FunctionSpace auxiliary_space()
>     {
>        return FunctionSpace_auxiliary(mesh);
>     }
>
>     /// Update PUM objects while surfaces evolve
>     void update()
>     {
>        for (unsigned int i = 0; i < pums.size(); ++i)
>            const_cast<pum::GenericPUM*>(pums[i])->update();
>     }
>
>
>   };
> }
>
> #endif

> # Copyright (C) 2008-2009 Mehdi Nikbakht and Garth N. Wells.
> # Licensed under the GNU GPL Version 3.0 or any later version.
> #
> # The bilinear form a(v, u) and linear form L(v) for
> # Poisson's equation with discontinuities.
> #
> # Compile this form with FFC: ffc-pum -l dolfin Poisson.ufl
> #
>
> elem_cont = FiniteElement("CG", triangle, 1)
> elem_discont = ElementRestriction(elem_cont, dc) # or ec[dc]
>
> #element = elem_cont * elem_discont
>
> #(vc, vd) = TestFunctions(element)
> #(uc, ud) = TrialFunctions(element)
>
> #v = vc + vd
> #u = uc + ud
>
> element = elem_cont + elem_discont
>
> v = TestFunction(element)
> u = TrialFunction(element)
>
> k  = Constant(triangle)
> f  = Coefficient(elem_cont)
> w  = Coefficient(elem_cont)
> g  = Coefficient(elem_cont)
>
> a = w*dot(grad(v), grad(u))*dx
> L = v*f*dx - v*g*ds
>

Attachment: signature.asc
Description: Digital signature


Follow ups

References