[cig-commits] commit: MADDs-5a working under 0.9.5

Mercurial hg at geodynamics.org
Wed Dec 9 20:51:22 PST 2009


changeset:   107:137baa77335a
user:        Marc Spiegelman <mspieg at ldeo.columbia.edu>
date:        Tue Dec 08 23:31:34 2009 -0500
files:       MADDs-5/MADDs-5a/cpp/MagmaEquations.cpp MADDs-5/MADDs-5a/cpp/MagmaEquations.ufl MADDs-5/MADDs-5a/cpp/MeltFlux.cpp MADDs-5/MADDs-5a/cpp/MeltFlux.ufl MADDs-5/MADDs-5a/cpp/Projection.cpp MADDs-5/MADDs-5a/cpp/Projection.ufl MADDs-5/MADDs-5a/cpp/SemiLagrangianRHS.cpp MADDs-5/MADDs-5a/cpp/SemiLagrangianRHS.ufl MADDs-5/MADDs-5a/cpp/forms/SemiLagrangianRHS_P2.ufl MADDs-5/MADDs-5a/cpp/main.cpp
description:
MADDs-5a working under 0.9.5


diff -r 18d756141ac1 -r 137baa77335a MADDs-5/MADDs-5a/cpp/MagmaEquations.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MADDs-5/MADDs-5a/cpp/MagmaEquations.cpp	Tue Dec 08 23:31:34 2009 -0500
@@ -0,0 +1,18203 @@
+#include "MagmaEquations.h"
+
+/// Constructor
+magmaequations_0_finite_element_0_0::magmaequations_0_finite_element_0_0() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+magmaequations_0_finite_element_0_0::~magmaequations_0_finite_element_0_0()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* magmaequations_0_finite_element_0_0::signature() const
+{
+    return "FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
+}
+
+/// Return the cell shape
+ufc::shape magmaequations_0_finite_element_0_0::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int magmaequations_0_finite_element_0_0::space_dimension() const
+{
+    return 6;
+}
+
+/// Return the rank of the value space
+unsigned int magmaequations_0_finite_element_0_0::value_rank() const
+{
+    return 0;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int magmaequations_0_finite_element_0_0::value_dimension(unsigned int i) const
+{
+    return 1;
+}
+
+/// Evaluate basis function i at given point in cell
+void magmaequations_0_finite_element_0_0::evaluate_basis(unsigned int i,
+                                   double* values,
+                                   const double* coordinates,
+                                   const ufc::cell& c) const
+{
+    // Extract vertex coordinates
+    const double * const * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Reset values
+    *values = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+    const double psitilde_bs_1_0 = 1;
+    const double psitilde_bs_1_1 = 2.5*y + 1.5;
+    const double psitilde_bs_2_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+    const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+    const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[6][6] = \
+    {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+    {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+    {0, 0, 0.2, 0, 0, 0.163299316185545},
+    {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+    {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+    {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+    // Extract relevant coefficients
+    const double coeff0_0 = coefficients0[dof][0];
+    const double coeff0_1 = coefficients0[dof][1];
+    const double coeff0_2 = coefficients0[dof][2];
+    const double coeff0_3 = coefficients0[dof][3];
+    const double coeff0_4 = coefficients0[dof][4];
+    const double coeff0_5 = coefficients0[dof][5];
+    
+    // Compute value(s)
+    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
+}
+
+/// Evaluate all basis functions at given point in cell
+void magmaequations_0_finite_element_0_0::evaluate_basis_all(double* values,
+                                       const double* coordinates,
+                                       const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
+}
+
+/// Evaluate order n derivatives of basis function i at given point in cell
+void magmaequations_0_finite_element_0_0::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 * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 2;
+    
+    
+    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
+    unsigned int **combinations = new unsigned int *[num_derivatives];
+    
+    for (unsigned int j = 0; j < num_derivatives; j++)
+    {
+      combinations[j] = new unsigned int [n];
+      for (unsigned int k = 0; k < n; k++)
+        combinations[j][k] = 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] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
+    
+    // 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
+    for (unsigned int j = 0; j < 1*num_derivatives; j++)
+      values[j] = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+    const double psitilde_bs_1_0 = 1;
+    const double psitilde_bs_1_1 = 2.5*y + 1.5;
+    const double psitilde_bs_2_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+    const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+    const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[6][6] = \
+    {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+    {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+    {0, 0, 0.2, 0, 0, 0.163299316185545},
+    {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+    {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+    {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+    // Interesting (new) part
+    // Tables of derivatives of the polynomial base (transpose)
+    static const double dmats0[6][6] = \
+    {{0, 0, 0, 0, 0, 0},
+    {4.89897948556636, 0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0},
+    {0, 9.48683298050514, 0, 0, 0, 0},
+    {4, 0, 7.07106781186548, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0}};
+    
+    static const double dmats1[6][6] = \
+    {{0, 0, 0, 0, 0, 0},
+    {2.44948974278318, 0, 0, 0, 0, 0},
+    {4.24264068711928, 0, 0, 0, 0, 0},
+    {2.58198889747161, 4.74341649025257, -0.912870929175277, 0, 0, 0},
+    {2, 6.12372435695795, 3.53553390593274, 0, 0, 0},
+    {-2.3094010767585, 0, 8.16496580927726, 0, 0, 0}};
+    
+    // Compute reference derivatives
+    // Declare pointer to array of derivatives on FIAT element
+    double *derivatives = new double [num_derivatives];
+    
+    // Declare coefficients
+    double coeff0_0 = 0;
+    double coeff0_1 = 0;
+    double coeff0_2 = 0;
+    double coeff0_3 = 0;
+    double coeff0_4 = 0;
+    double coeff0_5 = 0;
+    
+    // Declare new coefficients
+    double new_coeff0_0 = 0;
+    double new_coeff0_1 = 0;
+    double new_coeff0_2 = 0;
+    double new_coeff0_3 = 0;
+    double new_coeff0_4 = 0;
+    double new_coeff0_5 = 0;
+    
+    // Loop possible derivatives
+    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+    {
+      // Get values from coefficients array
+      new_coeff0_0 = coefficients0[dof][0];
+      new_coeff0_1 = coefficients0[dof][1];
+      new_coeff0_2 = coefficients0[dof][2];
+      new_coeff0_3 = coefficients0[dof][3];
+      new_coeff0_4 = coefficients0[dof][4];
+      new_coeff0_5 = coefficients0[dof][5];
+    
+      // Loop derivative order
+      for (unsigned int j = 0; j < n; j++)
+      {
+        // Update old coefficients
+        coeff0_0 = new_coeff0_0;
+        coeff0_1 = new_coeff0_1;
+        coeff0_2 = new_coeff0_2;
+        coeff0_3 = new_coeff0_3;
+        coeff0_4 = new_coeff0_4;
+        coeff0_5 = new_coeff0_5;
+    
+        if(combinations[deriv_num][j] == 0)
+        {
+          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
+          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
+          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
+          new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
+          new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
+          new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
+        }
+        if(combinations[deriv_num][j] == 1)
+        {
+          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
+          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
+          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
+          new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
+          new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
+          new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
+        }
+    
+      }
+      // Compute derivatives on reference element as dot product of coefficients and basisvalues
+      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
+    }
+    
+    // Transform derivatives back to physical element
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      for (unsigned int col = 0; col < num_derivatives; col++)
+      {
+        values[row] += transform[row][col]*derivatives[col];
+      }
+    }
+    // Delete pointer to array of derivatives on FIAT element
+    delete [] derivatives;
+    
+    // Delete pointer to array of combinations of derivatives and transform
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      delete [] combinations[row];
+      delete [] transform[row];
+    }
+    
+    delete [] combinations;
+    delete [] transform;
+}
+
+/// Evaluate order n derivatives of all basis functions at given point in cell
+void magmaequations_0_finite_element_0_0::evaluate_basis_derivatives_all(unsigned int n,
+                                                   double* values,
+                                                   const double* coordinates,
+                                                   const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
+}
+
+/// Evaluate linear functional for dof i on the function f
+double magmaequations_0_finite_element_0_0::evaluate_dof(unsigned int i,
+                                   const ufc::function& f,
+                                   const ufc::cell& c) const
+{
+    // The reference points, direction and weights:
+    static const double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}};
+    static const double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
+    static const double D[6][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}, {{1}}, {{1}}};
+    
+    const double * const * x = c.coordinates;
+    double result = 0.0;
+    // Iterate over the points:
+    // Evaluate basis functions for affine mapping
+    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    
+    // Compute affine mapping y = F(X)
+    double y[2];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
+    
+    // Evaluate function at physical points
+    double values[1];
+    f.evaluate(values, y, c);
+    
+    // Map function values using appropriate mapping
+    // Affine map: Do nothing
+    
+    // Note that we do not map the weights (yet).
+    
+    // Take directional components
+    for(int k = 0; k < 1; k++)
+      result += values[k]*D[i][0][k];
+    // Multiply by weights
+    result *= W[i][0];
+    
+    return result;
+}
+
+/// Evaluate linear functionals for all dofs on the function f
+void magmaequations_0_finite_element_0_0::evaluate_dofs(double* values,
+                                  const ufc::function& f,
+                                  const ufc::cell& c) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Interpolate vertex values from dof values
+void magmaequations_0_finite_element_0_0::interpolate_vertex_values(double* vertex_values,
+                                              const double* dof_values,
+                                              const ufc::cell& c) const
+{
+    // Evaluate at vertices and use affine mapping
+    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)
+unsigned int magmaequations_0_finite_element_0_0::num_sub_elements() const
+{
+    return 1;
+}
+
+/// Create a new finite element for sub element i (for a mixed element)
+ufc::finite_element* magmaequations_0_finite_element_0_0::create_sub_element(unsigned int i) const
+{
+    return new magmaequations_0_finite_element_0_0();
+}
+
+
+/// Constructor
+magmaequations_0_finite_element_0_1::magmaequations_0_finite_element_0_1() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+magmaequations_0_finite_element_0_1::~magmaequations_0_finite_element_0_1()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* magmaequations_0_finite_element_0_1::signature() const
+{
+    return "FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
+}
+
+/// Return the cell shape
+ufc::shape magmaequations_0_finite_element_0_1::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int magmaequations_0_finite_element_0_1::space_dimension() const
+{
+    return 6;
+}
+
+/// Return the rank of the value space
+unsigned int magmaequations_0_finite_element_0_1::value_rank() const
+{
+    return 0;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int magmaequations_0_finite_element_0_1::value_dimension(unsigned int i) const
+{
+    return 1;
+}
+
+/// Evaluate basis function i at given point in cell
+void magmaequations_0_finite_element_0_1::evaluate_basis(unsigned int i,
+                                   double* values,
+                                   const double* coordinates,
+                                   const ufc::cell& c) const
+{
+    // Extract vertex coordinates
+    const double * const * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Reset values
+    *values = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+    const double psitilde_bs_1_0 = 1;
+    const double psitilde_bs_1_1 = 2.5*y + 1.5;
+    const double psitilde_bs_2_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+    const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+    const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[6][6] = \
+    {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+    {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+    {0, 0, 0.2, 0, 0, 0.163299316185545},
+    {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+    {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+    {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+    // Extract relevant coefficients
+    const double coeff0_0 = coefficients0[dof][0];
+    const double coeff0_1 = coefficients0[dof][1];
+    const double coeff0_2 = coefficients0[dof][2];
+    const double coeff0_3 = coefficients0[dof][3];
+    const double coeff0_4 = coefficients0[dof][4];
+    const double coeff0_5 = coefficients0[dof][5];
+    
+    // Compute value(s)
+    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
+}
+
+/// Evaluate all basis functions at given point in cell
+void magmaequations_0_finite_element_0_1::evaluate_basis_all(double* values,
+                                       const double* coordinates,
+                                       const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
+}
+
+/// Evaluate order n derivatives of basis function i at given point in cell
+void magmaequations_0_finite_element_0_1::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 * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 2;
+    
+    
+    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
+    unsigned int **combinations = new unsigned int *[num_derivatives];
+    
+    for (unsigned int j = 0; j < num_derivatives; j++)
+    {
+      combinations[j] = new unsigned int [n];
+      for (unsigned int k = 0; k < n; k++)
+        combinations[j][k] = 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] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
+    
+    // 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
+    for (unsigned int j = 0; j < 1*num_derivatives; j++)
+      values[j] = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+    const double psitilde_bs_1_0 = 1;
+    const double psitilde_bs_1_1 = 2.5*y + 1.5;
+    const double psitilde_bs_2_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+    const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+    const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[6][6] = \
+    {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+    {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+    {0, 0, 0.2, 0, 0, 0.163299316185545},
+    {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+    {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+    {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+    // Interesting (new) part
+    // Tables of derivatives of the polynomial base (transpose)
+    static const double dmats0[6][6] = \
+    {{0, 0, 0, 0, 0, 0},
+    {4.89897948556636, 0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0},
+    {0, 9.48683298050514, 0, 0, 0, 0},
+    {4, 0, 7.07106781186548, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0}};
+    
+    static const double dmats1[6][6] = \
+    {{0, 0, 0, 0, 0, 0},
+    {2.44948974278318, 0, 0, 0, 0, 0},
+    {4.24264068711928, 0, 0, 0, 0, 0},
+    {2.58198889747161, 4.74341649025257, -0.912870929175277, 0, 0, 0},
+    {2, 6.12372435695795, 3.53553390593274, 0, 0, 0},
+    {-2.3094010767585, 0, 8.16496580927726, 0, 0, 0}};
+    
+    // Compute reference derivatives
+    // Declare pointer to array of derivatives on FIAT element
+    double *derivatives = new double [num_derivatives];
+    
+    // Declare coefficients
+    double coeff0_0 = 0;
+    double coeff0_1 = 0;
+    double coeff0_2 = 0;
+    double coeff0_3 = 0;
+    double coeff0_4 = 0;
+    double coeff0_5 = 0;
+    
+    // Declare new coefficients
+    double new_coeff0_0 = 0;
+    double new_coeff0_1 = 0;
+    double new_coeff0_2 = 0;
+    double new_coeff0_3 = 0;
+    double new_coeff0_4 = 0;
+    double new_coeff0_5 = 0;
+    
+    // Loop possible derivatives
+    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+    {
+      // Get values from coefficients array
+      new_coeff0_0 = coefficients0[dof][0];
+      new_coeff0_1 = coefficients0[dof][1];
+      new_coeff0_2 = coefficients0[dof][2];
+      new_coeff0_3 = coefficients0[dof][3];
+      new_coeff0_4 = coefficients0[dof][4];
+      new_coeff0_5 = coefficients0[dof][5];
+    
+      // Loop derivative order
+      for (unsigned int j = 0; j < n; j++)
+      {
+        // Update old coefficients
+        coeff0_0 = new_coeff0_0;
+        coeff0_1 = new_coeff0_1;
+        coeff0_2 = new_coeff0_2;
+        coeff0_3 = new_coeff0_3;
+        coeff0_4 = new_coeff0_4;
+        coeff0_5 = new_coeff0_5;
+    
+        if(combinations[deriv_num][j] == 0)
+        {
+          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
+          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
+          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
+          new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
+          new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
+          new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
+        }
+        if(combinations[deriv_num][j] == 1)
+        {
+          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
+          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
+          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
+          new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
+          new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
+          new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
+        }
+    
+      }
+      // Compute derivatives on reference element as dot product of coefficients and basisvalues
+      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
+    }
+    
+    // Transform derivatives back to physical element
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      for (unsigned int col = 0; col < num_derivatives; col++)
+      {
+        values[row] += transform[row][col]*derivatives[col];
+      }
+    }
+    // Delete pointer to array of derivatives on FIAT element
+    delete [] derivatives;
+    
+    // Delete pointer to array of combinations of derivatives and transform
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      delete [] combinations[row];
+      delete [] transform[row];
+    }
+    
+    delete [] combinations;
+    delete [] transform;
+}
+
+/// Evaluate order n derivatives of all basis functions at given point in cell
+void magmaequations_0_finite_element_0_1::evaluate_basis_derivatives_all(unsigned int n,
+                                                   double* values,
+                                                   const double* coordinates,
+                                                   const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
+}
+
+/// Evaluate linear functional for dof i on the function f
+double magmaequations_0_finite_element_0_1::evaluate_dof(unsigned int i,
+                                   const ufc::function& f,
+                                   const ufc::cell& c) const
+{
+    // The reference points, direction and weights:
+    static const double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}};
+    static const double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
+    static const double D[6][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}, {{1}}, {{1}}};
+    
+    const double * const * x = c.coordinates;
+    double result = 0.0;
+    // Iterate over the points:
+    // Evaluate basis functions for affine mapping
+    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    
+    // Compute affine mapping y = F(X)
+    double y[2];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
+    
+    // Evaluate function at physical points
+    double values[1];
+    f.evaluate(values, y, c);
+    
+    // Map function values using appropriate mapping
+    // Affine map: Do nothing
+    
+    // Note that we do not map the weights (yet).
+    
+    // Take directional components
+    for(int k = 0; k < 1; k++)
+      result += values[k]*D[i][0][k];
+    // Multiply by weights
+    result *= W[i][0];
+    
+    return result;
+}
+
+/// Evaluate linear functionals for all dofs on the function f
+void magmaequations_0_finite_element_0_1::evaluate_dofs(double* values,
+                                  const ufc::function& f,
+                                  const ufc::cell& c) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Interpolate vertex values from dof values
+void magmaequations_0_finite_element_0_1::interpolate_vertex_values(double* vertex_values,
+                                              const double* dof_values,
+                                              const ufc::cell& c) const
+{
+    // Evaluate at vertices and use affine mapping
+    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)
+unsigned int magmaequations_0_finite_element_0_1::num_sub_elements() const
+{
+    return 1;
+}
+
+/// Create a new finite element for sub element i (for a mixed element)
+ufc::finite_element* magmaequations_0_finite_element_0_1::create_sub_element(unsigned int i) const
+{
+    return new magmaequations_0_finite_element_0_1();
+}
+
+
+/// Constructor
+magmaequations_0_finite_element_0::magmaequations_0_finite_element_0() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+magmaequations_0_finite_element_0::~magmaequations_0_finite_element_0()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* magmaequations_0_finite_element_0::signature() const
+{
+    return "MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)], **{'value_shape': (2,) })";
+}
+
+/// Return the cell shape
+ufc::shape magmaequations_0_finite_element_0::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int magmaequations_0_finite_element_0::space_dimension() const
+{
+    return 12;
+}
+
+/// Return the rank of the value space
+unsigned int magmaequations_0_finite_element_0::value_rank() const
+{
+    return 1;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int magmaequations_0_finite_element_0::value_dimension(unsigned int i) const
+{
+    return 2;
+}
+
+/// Evaluate basis function i at given point in cell
+void magmaequations_0_finite_element_0::evaluate_basis(unsigned int i,
+                                   double* values,
+                                   const double* coordinates,
+                                   const ufc::cell& c) const
+{
+    // Extract vertex coordinates
+    const double * const * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Reset values
+    values[0] = 0;
+    values[1] = 0;
+    
+    if (0 <= i && i <= 5)
+    {
+      // Map degree of freedom to element degree of freedom
+      const unsigned int dof = i;
+    
+      // Generate scalings
+      const double scalings_y_0 = 1;
+      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+      const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+      // Compute psitilde_a
+      const double psitilde_a_0 = 1;
+      const double psitilde_a_1 = x;
+      const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+      // Compute psitilde_bs
+      const double psitilde_bs_0_0 = 1;
+      const double psitilde_bs_0_1 = 1.5*y + 0.5;
+      const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+      const double psitilde_bs_1_0 = 1;
+      const double psitilde_bs_1_1 = 2.5*y + 1.5;
+      const double psitilde_bs_2_0 = 1;
+    
+      // Compute basisvalues
+      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+      const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+      const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+      const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+      // Table(s) of coefficients
+      static const double coefficients0[6][6] =   \
+      {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+      {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+      {0, 0, 0.2, 0, 0, 0.163299316185545},
+      {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+      {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+      {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+      // Extract relevant coefficients
+      const double coeff0_0 =   coefficients0[dof][0];
+      const double coeff0_1 =   coefficients0[dof][1];
+      const double coeff0_2 =   coefficients0[dof][2];
+      const double coeff0_3 =   coefficients0[dof][3];
+      const double coeff0_4 =   coefficients0[dof][4];
+      const double coeff0_5 =   coefficients0[dof][5];
+    
+      // Compute value(s)
+      values[0] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
+    }
+    
+    if (6 <= i && i <= 11)
+    {
+      // Map degree of freedom to element degree of freedom
+      const unsigned int dof = i - 6;
+    
+      // Generate scalings
+      const double scalings_y_0 = 1;
+      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+      const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+      // Compute psitilde_a
+      const double psitilde_a_0 = 1;
+      const double psitilde_a_1 = x;
+      const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+      // Compute psitilde_bs
+      const double psitilde_bs_0_0 = 1;
+      const double psitilde_bs_0_1 = 1.5*y + 0.5;
+      const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+      const double psitilde_bs_1_0 = 1;
+      const double psitilde_bs_1_1 = 2.5*y + 1.5;
+      const double psitilde_bs_2_0 = 1;
+    
+      // Compute basisvalues
+      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+      const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+      const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+      const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+      // Table(s) of coefficients
+      static const double coefficients0[6][6] =   \
+      {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+      {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+      {0, 0, 0.2, 0, 0, 0.163299316185545},
+      {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+      {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+      {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+      // Extract relevant coefficients
+      const double coeff0_0 =   coefficients0[dof][0];
+      const double coeff0_1 =   coefficients0[dof][1];
+      const double coeff0_2 =   coefficients0[dof][2];
+      const double coeff0_3 =   coefficients0[dof][3];
+      const double coeff0_4 =   coefficients0[dof][4];
+      const double coeff0_5 =   coefficients0[dof][5];
+    
+      // Compute value(s)
+      values[1] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
+    }
+    
+}
+
+/// Evaluate all basis functions at given point in cell
+void magmaequations_0_finite_element_0::evaluate_basis_all(double* values,
+                                       const double* coordinates,
+                                       const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
+}
+
+/// Evaluate order n derivatives of basis function i at given point in cell
+void magmaequations_0_finite_element_0::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 * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 2;
+    
+    
+    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
+    unsigned int **combinations = new unsigned int *[num_derivatives];
+    
+    for (unsigned int j = 0; j < num_derivatives; j++)
+    {
+      combinations[j] = new unsigned int [n];
+      for (unsigned int k = 0; k < n; k++)
+        combinations[j][k] = 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] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
+    
+    // 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
+    for (unsigned int j = 0; j < 2*num_derivatives; j++)
+      values[j] = 0;
+    
+    if (0 <= i && i <= 5)
+    {
+      // Map degree of freedom to element degree of freedom
+      const unsigned int dof = i;
+    
+      // Generate scalings
+      const double scalings_y_0 = 1;
+      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+      const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+      // Compute psitilde_a
+      const double psitilde_a_0 = 1;
+      const double psitilde_a_1 = x;
+      const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+      // Compute psitilde_bs
+      const double psitilde_bs_0_0 = 1;
+      const double psitilde_bs_0_1 = 1.5*y + 0.5;
+      const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+      const double psitilde_bs_1_0 = 1;
+      const double psitilde_bs_1_1 = 2.5*y + 1.5;
+      const double psitilde_bs_2_0 = 1;
+    
+      // Compute basisvalues
+      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+      const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+      const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+      const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+      // Table(s) of coefficients
+      static const double coefficients0[6][6] =   \
+      {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+      {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+      {0, 0, 0.2, 0, 0, 0.163299316185545},
+      {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+      {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+      {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+      // Interesting (new) part
+      // Tables of derivatives of the polynomial base (transpose)
+      static const double dmats0[6][6] =   \
+      {{0, 0, 0, 0, 0, 0},
+      {4.89897948556636, 0, 0, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0},
+      {0, 9.48683298050514, 0, 0, 0, 0},
+      {4, 0, 7.07106781186548, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0}};
+    
+      static const double dmats1[6][6] =   \
+      {{0, 0, 0, 0, 0, 0},
+      {2.44948974278318, 0, 0, 0, 0, 0},
+      {4.24264068711928, 0, 0, 0, 0, 0},
+      {2.58198889747161, 4.74341649025257, -0.912870929175277, 0, 0, 0},
+      {2, 6.12372435695795, 3.53553390593274, 0, 0, 0},
+      {-2.3094010767585, 0, 8.16496580927726, 0, 0, 0}};
+    
+      // Compute reference derivatives
+      // Declare pointer to array of derivatives on FIAT element
+      double *derivatives = new double [num_derivatives];
+    
+      // Declare coefficients
+      double coeff0_0 = 0;
+      double coeff0_1 = 0;
+      double coeff0_2 = 0;
+      double coeff0_3 = 0;
+      double coeff0_4 = 0;
+      double coeff0_5 = 0;
+    
+      // Declare new coefficients
+      double new_coeff0_0 = 0;
+      double new_coeff0_1 = 0;
+      double new_coeff0_2 = 0;
+      double new_coeff0_3 = 0;
+      double new_coeff0_4 = 0;
+      double new_coeff0_5 = 0;
+    
+      // Loop possible derivatives
+      for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+      {
+        // Get values from coefficients array
+        new_coeff0_0 = coefficients0[dof][0];
+        new_coeff0_1 = coefficients0[dof][1];
+        new_coeff0_2 = coefficients0[dof][2];
+        new_coeff0_3 = coefficients0[dof][3];
+        new_coeff0_4 = coefficients0[dof][4];
+        new_coeff0_5 = coefficients0[dof][5];
+    
+        // Loop derivative order
+        for (unsigned int j = 0; j < n; j++)
+        {
+          // Update old coefficients
+          coeff0_0 = new_coeff0_0;
+          coeff0_1 = new_coeff0_1;
+          coeff0_2 = new_coeff0_2;
+          coeff0_3 = new_coeff0_3;
+          coeff0_4 = new_coeff0_4;
+          coeff0_5 = new_coeff0_5;
+    
+          if(combinations[deriv_num][j] == 0)
+          {
+            new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
+            new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
+            new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
+            new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
+            new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
+            new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
+          }
+          if(combinations[deriv_num][j] == 1)
+          {
+            new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
+            new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
+            new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
+            new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
+            new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
+            new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
+          }
+    
+        }
+        // Compute derivatives on reference element as dot product of coefficients and basisvalues
+        derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
+      }
+    
+      // Transform derivatives back to physical element
+      for (unsigned int row = 0; row < num_derivatives; row++)
+      {
+        for (unsigned int col = 0; col < num_derivatives; col++)
+        {
+          values[row] += transform[row][col]*derivatives[col];
+        }
+      }
+      // Delete pointer to array of derivatives on FIAT element
+      delete [] derivatives;
+    
+      // Delete pointer to array of combinations of derivatives and transform
+      for (unsigned int row = 0; row < num_derivatives; row++)
+      {
+        delete [] combinations[row];
+        delete [] transform[row];
+      }
+    
+      delete [] combinations;
+      delete [] transform;
+    }
+    
+    if (6 <= i && i <= 11)
+    {
+      // Map degree of freedom to element degree of freedom
+      const unsigned int dof = i - 6;
+    
+      // Generate scalings
+      const double scalings_y_0 = 1;
+      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+      const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+      // Compute psitilde_a
+      const double psitilde_a_0 = 1;
+      const double psitilde_a_1 = x;
+      const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+      // Compute psitilde_bs
+      const double psitilde_bs_0_0 = 1;
+      const double psitilde_bs_0_1 = 1.5*y + 0.5;
+      const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+      const double psitilde_bs_1_0 = 1;
+      const double psitilde_bs_1_1 = 2.5*y + 1.5;
+      const double psitilde_bs_2_0 = 1;
+    
+      // Compute basisvalues
+      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+      const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+      const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+      const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+      // Table(s) of coefficients
+      static const double coefficients0[6][6] =   \
+      {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+      {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+      {0, 0, 0.2, 0, 0, 0.163299316185545},
+      {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+      {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+      {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+      // Interesting (new) part
+      // Tables of derivatives of the polynomial base (transpose)
+      static const double dmats0[6][6] =   \
+      {{0, 0, 0, 0, 0, 0},
+      {4.89897948556636, 0, 0, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0},
+      {0, 9.48683298050514, 0, 0, 0, 0},
+      {4, 0, 7.07106781186548, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0}};
+    
+      static const double dmats1[6][6] =   \
+      {{0, 0, 0, 0, 0, 0},
+      {2.44948974278318, 0, 0, 0, 0, 0},
+      {4.24264068711928, 0, 0, 0, 0, 0},
+      {2.58198889747161, 4.74341649025257, -0.912870929175277, 0, 0, 0},
+      {2, 6.12372435695795, 3.53553390593274, 0, 0, 0},
+      {-2.3094010767585, 0, 8.16496580927726, 0, 0, 0}};
+    
+      // Compute reference derivatives
+      // Declare pointer to array of derivatives on FIAT element
+      double *derivatives = new double [num_derivatives];
+    
+      // Declare coefficients
+      double coeff0_0 = 0;
+      double coeff0_1 = 0;
+      double coeff0_2 = 0;
+      double coeff0_3 = 0;
+      double coeff0_4 = 0;
+      double coeff0_5 = 0;
+    
+      // Declare new coefficients
+      double new_coeff0_0 = 0;
+      double new_coeff0_1 = 0;
+      double new_coeff0_2 = 0;
+      double new_coeff0_3 = 0;
+      double new_coeff0_4 = 0;
+      double new_coeff0_5 = 0;
+    
+      // Loop possible derivatives
+      for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+      {
+        // Get values from coefficients array
+        new_coeff0_0 = coefficients0[dof][0];
+        new_coeff0_1 = coefficients0[dof][1];
+        new_coeff0_2 = coefficients0[dof][2];
+        new_coeff0_3 = coefficients0[dof][3];
+        new_coeff0_4 = coefficients0[dof][4];
+        new_coeff0_5 = coefficients0[dof][5];
+    
+        // Loop derivative order
+        for (unsigned int j = 0; j < n; j++)
+        {
+          // Update old coefficients
+          coeff0_0 = new_coeff0_0;
+          coeff0_1 = new_coeff0_1;
+          coeff0_2 = new_coeff0_2;
+          coeff0_3 = new_coeff0_3;
+          coeff0_4 = new_coeff0_4;
+          coeff0_5 = new_coeff0_5;
+    
+          if(combinations[deriv_num][j] == 0)
+          {
+            new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
+            new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
+            new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
+            new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
+            new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
+            new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
+          }
+          if(combinations[deriv_num][j] == 1)
+          {
+            new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
+            new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
+            new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
+            new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
+            new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
+            new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
+          }
+    
+        }
+        // Compute derivatives on reference element as dot product of coefficients and basisvalues
+        derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
+      }
+    
+      // Transform derivatives back to physical element
+      for (unsigned int row = 0; row < num_derivatives; row++)
+      {
+        for (unsigned int col = 0; col < num_derivatives; col++)
+        {
+          values[num_derivatives + row] += transform[row][col]*derivatives[col];
+        }
+      }
+      // Delete pointer to array of derivatives on FIAT element
+      delete [] derivatives;
+    
+      // Delete pointer to array of combinations of derivatives and transform
+      for (unsigned int row = 0; row < num_derivatives; row++)
+      {
+        delete [] combinations[row];
+        delete [] transform[row];
+      }
+    
+      delete [] combinations;
+      delete [] transform;
+    }
+    
+}
+
+/// Evaluate order n derivatives of all basis functions at given point in cell
+void magmaequations_0_finite_element_0::evaluate_basis_derivatives_all(unsigned int n,
+                                                   double* values,
+                                                   const double* coordinates,
+                                                   const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
+}
+
+/// Evaluate linear functional for dof i on the function f
+double magmaequations_0_finite_element_0::evaluate_dof(unsigned int i,
+                                   const ufc::function& f,
+                                   const ufc::cell& c) const
+{
+    // The reference points, direction and weights:
+    static const double X[12][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}, {{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}};
+    static const double W[12][1] = {{1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}};
+    static const double D[12][1][2] = {{{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{0, 1}}, {{0, 1}}, {{0, 1}}, {{0, 1}}, {{0, 1}}, {{0, 1}}};
+    
+    const double * const * x = c.coordinates;
+    double result = 0.0;
+    // Iterate over the points:
+    // Evaluate basis functions for affine mapping
+    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    
+    // Compute affine mapping y = F(X)
+    double y[2];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
+    
+    // Evaluate function at physical points
+    double values[2];
+    f.evaluate(values, y, c);
+    
+    // Map function values using appropriate mapping
+    // Affine map: Do nothing
+    
+    // Note that we do not map the weights (yet).
+    
+    // Take directional components
+    for(int k = 0; k < 2; k++)
+      result += values[k]*D[i][0][k];
+    // Multiply by weights
+    result *= W[i][0];
+    
+    return result;
+}
+
+/// Evaluate linear functionals for all dofs on the function f
+void magmaequations_0_finite_element_0::evaluate_dofs(double* values,
+                                  const ufc::function& f,
+                                  const ufc::cell& c) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Interpolate vertex values from dof values
+void magmaequations_0_finite_element_0::interpolate_vertex_values(double* vertex_values,
+                                              const double* dof_values,
+                                              const ufc::cell& c) const
+{
+    // Evaluate at vertices and use affine mapping
+    vertex_values[0] = dof_values[0];
+    vertex_values[2] = dof_values[1];
+    vertex_values[4] = dof_values[2];
+    // Evaluate at vertices and use affine mapping
+    vertex_values[1] = dof_values[6];
+    vertex_values[3] = dof_values[7];
+    vertex_values[5] = dof_values[8];
+}
+
+/// Return the number of sub elements (for a mixed element)
+unsigned int magmaequations_0_finite_element_0::num_sub_elements() const
+{
+    return 2;
+}
+
+/// Create a new finite element for sub element i (for a mixed element)
+ufc::finite_element* magmaequations_0_finite_element_0::create_sub_element(unsigned int i) const
+{
+    switch ( i )
+    {
+    case 0:
+      return new magmaequations_0_finite_element_0_0();
+      break;
+    case 1:
+      return new magmaequations_0_finite_element_0_1();
+      break;
+    }
+    return 0;
+}
+
+
+/// Constructor
+magmaequations_0_finite_element_1_0::magmaequations_0_finite_element_1_0() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+magmaequations_0_finite_element_1_0::~magmaequations_0_finite_element_1_0()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* magmaequations_0_finite_element_1_0::signature() const
+{
+    return "FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
+}
+
+/// Return the cell shape
+ufc::shape magmaequations_0_finite_element_1_0::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int magmaequations_0_finite_element_1_0::space_dimension() const
+{
+    return 6;
+}
+
+/// Return the rank of the value space
+unsigned int magmaequations_0_finite_element_1_0::value_rank() const
+{
+    return 0;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int magmaequations_0_finite_element_1_0::value_dimension(unsigned int i) const
+{
+    return 1;
+}
+
+/// Evaluate basis function i at given point in cell
+void magmaequations_0_finite_element_1_0::evaluate_basis(unsigned int i,
+                                   double* values,
+                                   const double* coordinates,
+                                   const ufc::cell& c) const
+{
+    // Extract vertex coordinates
+    const double * const * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Reset values
+    *values = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+    const double psitilde_bs_1_0 = 1;
+    const double psitilde_bs_1_1 = 2.5*y + 1.5;
+    const double psitilde_bs_2_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+    const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+    const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[6][6] = \
+    {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+    {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+    {0, 0, 0.2, 0, 0, 0.163299316185545},
+    {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+    {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+    {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+    // Extract relevant coefficients
+    const double coeff0_0 = coefficients0[dof][0];
+    const double coeff0_1 = coefficients0[dof][1];
+    const double coeff0_2 = coefficients0[dof][2];
+    const double coeff0_3 = coefficients0[dof][3];
+    const double coeff0_4 = coefficients0[dof][4];
+    const double coeff0_5 = coefficients0[dof][5];
+    
+    // Compute value(s)
+    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
+}
+
+/// Evaluate all basis functions at given point in cell
+void magmaequations_0_finite_element_1_0::evaluate_basis_all(double* values,
+                                       const double* coordinates,
+                                       const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
+}
+
+/// Evaluate order n derivatives of basis function i at given point in cell
+void magmaequations_0_finite_element_1_0::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 * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 2;
+    
+    
+    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
+    unsigned int **combinations = new unsigned int *[num_derivatives];
+    
+    for (unsigned int j = 0; j < num_derivatives; j++)
+    {
+      combinations[j] = new unsigned int [n];
+      for (unsigned int k = 0; k < n; k++)
+        combinations[j][k] = 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] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
+    
+    // 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
+    for (unsigned int j = 0; j < 1*num_derivatives; j++)
+      values[j] = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+    const double psitilde_bs_1_0 = 1;
+    const double psitilde_bs_1_1 = 2.5*y + 1.5;
+    const double psitilde_bs_2_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+    const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+    const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[6][6] = \
+    {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+    {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+    {0, 0, 0.2, 0, 0, 0.163299316185545},
+    {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+    {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+    {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+    // Interesting (new) part
+    // Tables of derivatives of the polynomial base (transpose)
+    static const double dmats0[6][6] = \
+    {{0, 0, 0, 0, 0, 0},
+    {4.89897948556636, 0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0},
+    {0, 9.48683298050514, 0, 0, 0, 0},
+    {4, 0, 7.07106781186548, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0}};
+    
+    static const double dmats1[6][6] = \
+    {{0, 0, 0, 0, 0, 0},
+    {2.44948974278318, 0, 0, 0, 0, 0},
+    {4.24264068711928, 0, 0, 0, 0, 0},
+    {2.58198889747161, 4.74341649025257, -0.912870929175277, 0, 0, 0},
+    {2, 6.12372435695795, 3.53553390593274, 0, 0, 0},
+    {-2.3094010767585, 0, 8.16496580927726, 0, 0, 0}};
+    
+    // Compute reference derivatives
+    // Declare pointer to array of derivatives on FIAT element
+    double *derivatives = new double [num_derivatives];
+    
+    // Declare coefficients
+    double coeff0_0 = 0;
+    double coeff0_1 = 0;
+    double coeff0_2 = 0;
+    double coeff0_3 = 0;
+    double coeff0_4 = 0;
+    double coeff0_5 = 0;
+    
+    // Declare new coefficients
+    double new_coeff0_0 = 0;
+    double new_coeff0_1 = 0;
+    double new_coeff0_2 = 0;
+    double new_coeff0_3 = 0;
+    double new_coeff0_4 = 0;
+    double new_coeff0_5 = 0;
+    
+    // Loop possible derivatives
+    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+    {
+      // Get values from coefficients array
+      new_coeff0_0 = coefficients0[dof][0];
+      new_coeff0_1 = coefficients0[dof][1];
+      new_coeff0_2 = coefficients0[dof][2];
+      new_coeff0_3 = coefficients0[dof][3];
+      new_coeff0_4 = coefficients0[dof][4];
+      new_coeff0_5 = coefficients0[dof][5];
+    
+      // Loop derivative order
+      for (unsigned int j = 0; j < n; j++)
+      {
+        // Update old coefficients
+        coeff0_0 = new_coeff0_0;
+        coeff0_1 = new_coeff0_1;
+        coeff0_2 = new_coeff0_2;
+        coeff0_3 = new_coeff0_3;
+        coeff0_4 = new_coeff0_4;
+        coeff0_5 = new_coeff0_5;
+    
+        if(combinations[deriv_num][j] == 0)
+        {
+          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
+          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
+          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
+          new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
+          new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
+          new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
+        }
+        if(combinations[deriv_num][j] == 1)
+        {
+          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
+          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
+          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
+          new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
+          new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
+          new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
+        }
+    
+      }
+      // Compute derivatives on reference element as dot product of coefficients and basisvalues
+      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
+    }
+    
+    // Transform derivatives back to physical element
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      for (unsigned int col = 0; col < num_derivatives; col++)
+      {
+        values[row] += transform[row][col]*derivatives[col];
+      }
+    }
+    // Delete pointer to array of derivatives on FIAT element
+    delete [] derivatives;
+    
+    // Delete pointer to array of combinations of derivatives and transform
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      delete [] combinations[row];
+      delete [] transform[row];
+    }
+    
+    delete [] combinations;
+    delete [] transform;
+}
+
+/// Evaluate order n derivatives of all basis functions at given point in cell
+void magmaequations_0_finite_element_1_0::evaluate_basis_derivatives_all(unsigned int n,
+                                                   double* values,
+                                                   const double* coordinates,
+                                                   const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
+}
+
+/// Evaluate linear functional for dof i on the function f
+double magmaequations_0_finite_element_1_0::evaluate_dof(unsigned int i,
+                                   const ufc::function& f,
+                                   const ufc::cell& c) const
+{
+    // The reference points, direction and weights:
+    static const double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}};
+    static const double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
+    static const double D[6][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}, {{1}}, {{1}}};
+    
+    const double * const * x = c.coordinates;
+    double result = 0.0;
+    // Iterate over the points:
+    // Evaluate basis functions for affine mapping
+    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    
+    // Compute affine mapping y = F(X)
+    double y[2];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
+    
+    // Evaluate function at physical points
+    double values[1];
+    f.evaluate(values, y, c);
+    
+    // Map function values using appropriate mapping
+    // Affine map: Do nothing
+    
+    // Note that we do not map the weights (yet).
+    
+    // Take directional components
+    for(int k = 0; k < 1; k++)
+      result += values[k]*D[i][0][k];
+    // Multiply by weights
+    result *= W[i][0];
+    
+    return result;
+}
+
+/// Evaluate linear functionals for all dofs on the function f
+void magmaequations_0_finite_element_1_0::evaluate_dofs(double* values,
+                                  const ufc::function& f,
+                                  const ufc::cell& c) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Interpolate vertex values from dof values
+void magmaequations_0_finite_element_1_0::interpolate_vertex_values(double* vertex_values,
+                                              const double* dof_values,
+                                              const ufc::cell& c) const
+{
+    // Evaluate at vertices and use affine mapping
+    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)
+unsigned int magmaequations_0_finite_element_1_0::num_sub_elements() const
+{
+    return 1;
+}
+
+/// Create a new finite element for sub element i (for a mixed element)
+ufc::finite_element* magmaequations_0_finite_element_1_0::create_sub_element(unsigned int i) const
+{
+    return new magmaequations_0_finite_element_1_0();
+}
+
+
+/// Constructor
+magmaequations_0_finite_element_1_1::magmaequations_0_finite_element_1_1() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+magmaequations_0_finite_element_1_1::~magmaequations_0_finite_element_1_1()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* magmaequations_0_finite_element_1_1::signature() const
+{
+    return "FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
+}
+
+/// Return the cell shape
+ufc::shape magmaequations_0_finite_element_1_1::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int magmaequations_0_finite_element_1_1::space_dimension() const
+{
+    return 6;
+}
+
+/// Return the rank of the value space
+unsigned int magmaequations_0_finite_element_1_1::value_rank() const
+{
+    return 0;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int magmaequations_0_finite_element_1_1::value_dimension(unsigned int i) const
+{
+    return 1;
+}
+
+/// Evaluate basis function i at given point in cell
+void magmaequations_0_finite_element_1_1::evaluate_basis(unsigned int i,
+                                   double* values,
+                                   const double* coordinates,
+                                   const ufc::cell& c) const
+{
+    // Extract vertex coordinates
+    const double * const * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Reset values
+    *values = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+    const double psitilde_bs_1_0 = 1;
+    const double psitilde_bs_1_1 = 2.5*y + 1.5;
+    const double psitilde_bs_2_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+    const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+    const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[6][6] = \
+    {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+    {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+    {0, 0, 0.2, 0, 0, 0.163299316185545},
+    {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+    {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+    {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+    // Extract relevant coefficients
+    const double coeff0_0 = coefficients0[dof][0];
+    const double coeff0_1 = coefficients0[dof][1];
+    const double coeff0_2 = coefficients0[dof][2];
+    const double coeff0_3 = coefficients0[dof][3];
+    const double coeff0_4 = coefficients0[dof][4];
+    const double coeff0_5 = coefficients0[dof][5];
+    
+    // Compute value(s)
+    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
+}
+
+/// Evaluate all basis functions at given point in cell
+void magmaequations_0_finite_element_1_1::evaluate_basis_all(double* values,
+                                       const double* coordinates,
+                                       const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
+}
+
+/// Evaluate order n derivatives of basis function i at given point in cell
+void magmaequations_0_finite_element_1_1::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 * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 2;
+    
+    
+    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
+    unsigned int **combinations = new unsigned int *[num_derivatives];
+    
+    for (unsigned int j = 0; j < num_derivatives; j++)
+    {
+      combinations[j] = new unsigned int [n];
+      for (unsigned int k = 0; k < n; k++)
+        combinations[j][k] = 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] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
+    
+    // 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
+    for (unsigned int j = 0; j < 1*num_derivatives; j++)
+      values[j] = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+    const double psitilde_bs_1_0 = 1;
+    const double psitilde_bs_1_1 = 2.5*y + 1.5;
+    const double psitilde_bs_2_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+    const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+    const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[6][6] = \
+    {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+    {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+    {0, 0, 0.2, 0, 0, 0.163299316185545},
+    {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+    {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+    {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+    // Interesting (new) part
+    // Tables of derivatives of the polynomial base (transpose)
+    static const double dmats0[6][6] = \
+    {{0, 0, 0, 0, 0, 0},
+    {4.89897948556636, 0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0},
+    {0, 9.48683298050514, 0, 0, 0, 0},
+    {4, 0, 7.07106781186548, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0}};
+    
+    static const double dmats1[6][6] = \
+    {{0, 0, 0, 0, 0, 0},
+    {2.44948974278318, 0, 0, 0, 0, 0},
+    {4.24264068711928, 0, 0, 0, 0, 0},
+    {2.58198889747161, 4.74341649025257, -0.912870929175277, 0, 0, 0},
+    {2, 6.12372435695795, 3.53553390593274, 0, 0, 0},
+    {-2.3094010767585, 0, 8.16496580927726, 0, 0, 0}};
+    
+    // Compute reference derivatives
+    // Declare pointer to array of derivatives on FIAT element
+    double *derivatives = new double [num_derivatives];
+    
+    // Declare coefficients
+    double coeff0_0 = 0;
+    double coeff0_1 = 0;
+    double coeff0_2 = 0;
+    double coeff0_3 = 0;
+    double coeff0_4 = 0;
+    double coeff0_5 = 0;
+    
+    // Declare new coefficients
+    double new_coeff0_0 = 0;
+    double new_coeff0_1 = 0;
+    double new_coeff0_2 = 0;
+    double new_coeff0_3 = 0;
+    double new_coeff0_4 = 0;
+    double new_coeff0_5 = 0;
+    
+    // Loop possible derivatives
+    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+    {
+      // Get values from coefficients array
+      new_coeff0_0 = coefficients0[dof][0];
+      new_coeff0_1 = coefficients0[dof][1];
+      new_coeff0_2 = coefficients0[dof][2];
+      new_coeff0_3 = coefficients0[dof][3];
+      new_coeff0_4 = coefficients0[dof][4];
+      new_coeff0_5 = coefficients0[dof][5];
+    
+      // Loop derivative order
+      for (unsigned int j = 0; j < n; j++)
+      {
+        // Update old coefficients
+        coeff0_0 = new_coeff0_0;
+        coeff0_1 = new_coeff0_1;
+        coeff0_2 = new_coeff0_2;
+        coeff0_3 = new_coeff0_3;
+        coeff0_4 = new_coeff0_4;
+        coeff0_5 = new_coeff0_5;
+    
+        if(combinations[deriv_num][j] == 0)
+        {
+          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
+          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
+          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
+          new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
+          new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
+          new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
+        }
+        if(combinations[deriv_num][j] == 1)
+        {
+          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
+          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
+          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
+          new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
+          new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
+          new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
+        }
+    
+      }
+      // Compute derivatives on reference element as dot product of coefficients and basisvalues
+      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
+    }
+    
+    // Transform derivatives back to physical element
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      for (unsigned int col = 0; col < num_derivatives; col++)
+      {
+        values[row] += transform[row][col]*derivatives[col];
+      }
+    }
+    // Delete pointer to array of derivatives on FIAT element
+    delete [] derivatives;
+    
+    // Delete pointer to array of combinations of derivatives and transform
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      delete [] combinations[row];
+      delete [] transform[row];
+    }
+    
+    delete [] combinations;
+    delete [] transform;
+}
+
+/// Evaluate order n derivatives of all basis functions at given point in cell
+void magmaequations_0_finite_element_1_1::evaluate_basis_derivatives_all(unsigned int n,
+                                                   double* values,
+                                                   const double* coordinates,
+                                                   const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
+}
+
+/// Evaluate linear functional for dof i on the function f
+double magmaequations_0_finite_element_1_1::evaluate_dof(unsigned int i,
+                                   const ufc::function& f,
+                                   const ufc::cell& c) const
+{
+    // The reference points, direction and weights:
+    static const double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}};
+    static const double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
+    static const double D[6][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}, {{1}}, {{1}}};
+    
+    const double * const * x = c.coordinates;
+    double result = 0.0;
+    // Iterate over the points:
+    // Evaluate basis functions for affine mapping
+    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    
+    // Compute affine mapping y = F(X)
+    double y[2];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
+    
+    // Evaluate function at physical points
+    double values[1];
+    f.evaluate(values, y, c);
+    
+    // Map function values using appropriate mapping
+    // Affine map: Do nothing
+    
+    // Note that we do not map the weights (yet).
+    
+    // Take directional components
+    for(int k = 0; k < 1; k++)
+      result += values[k]*D[i][0][k];
+    // Multiply by weights
+    result *= W[i][0];
+    
+    return result;
+}
+
+/// Evaluate linear functionals for all dofs on the function f
+void magmaequations_0_finite_element_1_1::evaluate_dofs(double* values,
+                                  const ufc::function& f,
+                                  const ufc::cell& c) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Interpolate vertex values from dof values
+void magmaequations_0_finite_element_1_1::interpolate_vertex_values(double* vertex_values,
+                                              const double* dof_values,
+                                              const ufc::cell& c) const
+{
+    // Evaluate at vertices and use affine mapping
+    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)
+unsigned int magmaequations_0_finite_element_1_1::num_sub_elements() const
+{
+    return 1;
+}
+
+/// Create a new finite element for sub element i (for a mixed element)
+ufc::finite_element* magmaequations_0_finite_element_1_1::create_sub_element(unsigned int i) const
+{
+    return new magmaequations_0_finite_element_1_1();
+}
+
+
+/// Constructor
+magmaequations_0_finite_element_1::magmaequations_0_finite_element_1() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+magmaequations_0_finite_element_1::~magmaequations_0_finite_element_1()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* magmaequations_0_finite_element_1::signature() const
+{
+    return "MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)], **{'value_shape': (2,) })";
+}
+
+/// Return the cell shape
+ufc::shape magmaequations_0_finite_element_1::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int magmaequations_0_finite_element_1::space_dimension() const
+{
+    return 12;
+}
+
+/// Return the rank of the value space
+unsigned int magmaequations_0_finite_element_1::value_rank() const
+{
+    return 1;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int magmaequations_0_finite_element_1::value_dimension(unsigned int i) const
+{
+    return 2;
+}
+
+/// Evaluate basis function i at given point in cell
+void magmaequations_0_finite_element_1::evaluate_basis(unsigned int i,
+                                   double* values,
+                                   const double* coordinates,
+                                   const ufc::cell& c) const
+{
+    // Extract vertex coordinates
+    const double * const * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Reset values
+    values[0] = 0;
+    values[1] = 0;
+    
+    if (0 <= i && i <= 5)
+    {
+      // Map degree of freedom to element degree of freedom
+      const unsigned int dof = i;
+    
+      // Generate scalings
+      const double scalings_y_0 = 1;
+      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+      const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+      // Compute psitilde_a
+      const double psitilde_a_0 = 1;
+      const double psitilde_a_1 = x;
+      const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+      // Compute psitilde_bs
+      const double psitilde_bs_0_0 = 1;
+      const double psitilde_bs_0_1 = 1.5*y + 0.5;
+      const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+      const double psitilde_bs_1_0 = 1;
+      const double psitilde_bs_1_1 = 2.5*y + 1.5;
+      const double psitilde_bs_2_0 = 1;
+    
+      // Compute basisvalues
+      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+      const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+      const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+      const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+      // Table(s) of coefficients
+      static const double coefficients0[6][6] =   \
+      {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+      {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+      {0, 0, 0.2, 0, 0, 0.163299316185545},
+      {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+      {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+      {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+      // Extract relevant coefficients
+      const double coeff0_0 =   coefficients0[dof][0];
+      const double coeff0_1 =   coefficients0[dof][1];
+      const double coeff0_2 =   coefficients0[dof][2];
+      const double coeff0_3 =   coefficients0[dof][3];
+      const double coeff0_4 =   coefficients0[dof][4];
+      const double coeff0_5 =   coefficients0[dof][5];
+    
+      // Compute value(s)
+      values[0] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
+    }
+    
+    if (6 <= i && i <= 11)
+    {
+      // Map degree of freedom to element degree of freedom
+      const unsigned int dof = i - 6;
+    
+      // Generate scalings
+      const double scalings_y_0 = 1;
+      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+      const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+      // Compute psitilde_a
+      const double psitilde_a_0 = 1;
+      const double psitilde_a_1 = x;
+      const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+      // Compute psitilde_bs
+      const double psitilde_bs_0_0 = 1;
+      const double psitilde_bs_0_1 = 1.5*y + 0.5;
+      const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+      const double psitilde_bs_1_0 = 1;
+      const double psitilde_bs_1_1 = 2.5*y + 1.5;
+      const double psitilde_bs_2_0 = 1;
+    
+      // Compute basisvalues
+      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+      const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+      const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+      const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+      // Table(s) of coefficients
+      static const double coefficients0[6][6] =   \
+      {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+      {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+      {0, 0, 0.2, 0, 0, 0.163299316185545},
+      {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+      {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+      {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+      // Extract relevant coefficients
+      const double coeff0_0 =   coefficients0[dof][0];
+      const double coeff0_1 =   coefficients0[dof][1];
+      const double coeff0_2 =   coefficients0[dof][2];
+      const double coeff0_3 =   coefficients0[dof][3];
+      const double coeff0_4 =   coefficients0[dof][4];
+      const double coeff0_5 =   coefficients0[dof][5];
+    
+      // Compute value(s)
+      values[1] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
+    }
+    
+}
+
+/// Evaluate all basis functions at given point in cell
+void magmaequations_0_finite_element_1::evaluate_basis_all(double* values,
+                                       const double* coordinates,
+                                       const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
+}
+
+/// Evaluate order n derivatives of basis function i at given point in cell
+void magmaequations_0_finite_element_1::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 * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 2;
+    
+    
+    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
+    unsigned int **combinations = new unsigned int *[num_derivatives];
+    
+    for (unsigned int j = 0; j < num_derivatives; j++)
+    {
+      combinations[j] = new unsigned int [n];
+      for (unsigned int k = 0; k < n; k++)
+        combinations[j][k] = 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] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
+    
+    // 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
+    for (unsigned int j = 0; j < 2*num_derivatives; j++)
+      values[j] = 0;
+    
+    if (0 <= i && i <= 5)
+    {
+      // Map degree of freedom to element degree of freedom
+      const unsigned int dof = i;
+    
+      // Generate scalings
+      const double scalings_y_0 = 1;
+      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+      const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+      // Compute psitilde_a
+      const double psitilde_a_0 = 1;
+      const double psitilde_a_1 = x;
+      const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+      // Compute psitilde_bs
+      const double psitilde_bs_0_0 = 1;
+      const double psitilde_bs_0_1 = 1.5*y + 0.5;
+      const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+      const double psitilde_bs_1_0 = 1;
+      const double psitilde_bs_1_1 = 2.5*y + 1.5;
+      const double psitilde_bs_2_0 = 1;
+    
+      // Compute basisvalues
+      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+      const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+      const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+      const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+      // Table(s) of coefficients
+      static const double coefficients0[6][6] =   \
+      {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+      {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+      {0, 0, 0.2, 0, 0, 0.163299316185545},
+      {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+      {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+      {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+      // Interesting (new) part
+      // Tables of derivatives of the polynomial base (transpose)
+      static const double dmats0[6][6] =   \
+      {{0, 0, 0, 0, 0, 0},
+      {4.89897948556636, 0, 0, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0},
+      {0, 9.48683298050514, 0, 0, 0, 0},
+      {4, 0, 7.07106781186548, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0}};
+    
+      static const double dmats1[6][6] =   \
+      {{0, 0, 0, 0, 0, 0},
+      {2.44948974278318, 0, 0, 0, 0, 0},
+      {4.24264068711928, 0, 0, 0, 0, 0},
+      {2.58198889747161, 4.74341649025257, -0.912870929175277, 0, 0, 0},
+      {2, 6.12372435695795, 3.53553390593274, 0, 0, 0},
+      {-2.3094010767585, 0, 8.16496580927726, 0, 0, 0}};
+    
+      // Compute reference derivatives
+      // Declare pointer to array of derivatives on FIAT element
+      double *derivatives = new double [num_derivatives];
+    
+      // Declare coefficients
+      double coeff0_0 = 0;
+      double coeff0_1 = 0;
+      double coeff0_2 = 0;
+      double coeff0_3 = 0;
+      double coeff0_4 = 0;
+      double coeff0_5 = 0;
+    
+      // Declare new coefficients
+      double new_coeff0_0 = 0;
+      double new_coeff0_1 = 0;
+      double new_coeff0_2 = 0;
+      double new_coeff0_3 = 0;
+      double new_coeff0_4 = 0;
+      double new_coeff0_5 = 0;
+    
+      // Loop possible derivatives
+      for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+      {
+        // Get values from coefficients array
+        new_coeff0_0 = coefficients0[dof][0];
+        new_coeff0_1 = coefficients0[dof][1];
+        new_coeff0_2 = coefficients0[dof][2];
+        new_coeff0_3 = coefficients0[dof][3];
+        new_coeff0_4 = coefficients0[dof][4];
+        new_coeff0_5 = coefficients0[dof][5];
+    
+        // Loop derivative order
+        for (unsigned int j = 0; j < n; j++)
+        {
+          // Update old coefficients
+          coeff0_0 = new_coeff0_0;
+          coeff0_1 = new_coeff0_1;
+          coeff0_2 = new_coeff0_2;
+          coeff0_3 = new_coeff0_3;
+          coeff0_4 = new_coeff0_4;
+          coeff0_5 = new_coeff0_5;
+    
+          if(combinations[deriv_num][j] == 0)
+          {
+            new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
+            new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
+            new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
+            new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
+            new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
+            new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
+          }
+          if(combinations[deriv_num][j] == 1)
+          {
+            new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
+            new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
+            new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
+            new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
+            new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
+            new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
+          }
+    
+        }
+        // Compute derivatives on reference element as dot product of coefficients and basisvalues
+        derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
+      }
+    
+      // Transform derivatives back to physical element
+      for (unsigned int row = 0; row < num_derivatives; row++)
+      {
+        for (unsigned int col = 0; col < num_derivatives; col++)
+        {
+          values[row] += transform[row][col]*derivatives[col];
+        }
+      }
+      // Delete pointer to array of derivatives on FIAT element
+      delete [] derivatives;
+    
+      // Delete pointer to array of combinations of derivatives and transform
+      for (unsigned int row = 0; row < num_derivatives; row++)
+      {
+        delete [] combinations[row];
+        delete [] transform[row];
+      }
+    
+      delete [] combinations;
+      delete [] transform;
+    }
+    
+    if (6 <= i && i <= 11)
+    {
+      // Map degree of freedom to element degree of freedom
+      const unsigned int dof = i - 6;
+    
+      // Generate scalings
+      const double scalings_y_0 = 1;
+      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+      const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+      // Compute psitilde_a
+      const double psitilde_a_0 = 1;
+      const double psitilde_a_1 = x;
+      const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+      // Compute psitilde_bs
+      const double psitilde_bs_0_0 = 1;
+      const double psitilde_bs_0_1 = 1.5*y + 0.5;
+      const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+      const double psitilde_bs_1_0 = 1;
+      const double psitilde_bs_1_1 = 2.5*y + 1.5;
+      const double psitilde_bs_2_0 = 1;
+    
+      // Compute basisvalues
+      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+      const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+      const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+      const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+      // Table(s) of coefficients
+      static const double coefficients0[6][6] =   \
+      {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+      {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+      {0, 0, 0.2, 0, 0, 0.163299316185545},
+      {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+      {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+      {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+      // Interesting (new) part
+      // Tables of derivatives of the polynomial base (transpose)
+      static const double dmats0[6][6] =   \
+      {{0, 0, 0, 0, 0, 0},
+      {4.89897948556636, 0, 0, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0},
+      {0, 9.48683298050514, 0, 0, 0, 0},
+      {4, 0, 7.07106781186548, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0}};
+    
+      static const double dmats1[6][6] =   \
+      {{0, 0, 0, 0, 0, 0},
+      {2.44948974278318, 0, 0, 0, 0, 0},
+      {4.24264068711928, 0, 0, 0, 0, 0},
+      {2.58198889747161, 4.74341649025257, -0.912870929175277, 0, 0, 0},
+      {2, 6.12372435695795, 3.53553390593274, 0, 0, 0},
+      {-2.3094010767585, 0, 8.16496580927726, 0, 0, 0}};
+    
+      // Compute reference derivatives
+      // Declare pointer to array of derivatives on FIAT element
+      double *derivatives = new double [num_derivatives];
+    
+      // Declare coefficients
+      double coeff0_0 = 0;
+      double coeff0_1 = 0;
+      double coeff0_2 = 0;
+      double coeff0_3 = 0;
+      double coeff0_4 = 0;
+      double coeff0_5 = 0;
+    
+      // Declare new coefficients
+      double new_coeff0_0 = 0;
+      double new_coeff0_1 = 0;
+      double new_coeff0_2 = 0;
+      double new_coeff0_3 = 0;
+      double new_coeff0_4 = 0;
+      double new_coeff0_5 = 0;
+    
+      // Loop possible derivatives
+      for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+      {
+        // Get values from coefficients array
+        new_coeff0_0 = coefficients0[dof][0];
+        new_coeff0_1 = coefficients0[dof][1];
+        new_coeff0_2 = coefficients0[dof][2];
+        new_coeff0_3 = coefficients0[dof][3];
+        new_coeff0_4 = coefficients0[dof][4];
+        new_coeff0_5 = coefficients0[dof][5];
+    
+        // Loop derivative order
+        for (unsigned int j = 0; j < n; j++)
+        {
+          // Update old coefficients
+          coeff0_0 = new_coeff0_0;
+          coeff0_1 = new_coeff0_1;
+          coeff0_2 = new_coeff0_2;
+          coeff0_3 = new_coeff0_3;
+          coeff0_4 = new_coeff0_4;
+          coeff0_5 = new_coeff0_5;
+    
+          if(combinations[deriv_num][j] == 0)
+          {
+            new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
+            new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
+            new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
+            new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
+            new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
+            new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
+          }
+          if(combinations[deriv_num][j] == 1)
+          {
+            new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
+            new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
+            new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
+            new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
+            new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
+            new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
+          }
+    
+        }
+        // Compute derivatives on reference element as dot product of coefficients and basisvalues
+        derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
+      }
+    
+      // Transform derivatives back to physical element
+      for (unsigned int row = 0; row < num_derivatives; row++)
+      {
+        for (unsigned int col = 0; col < num_derivatives; col++)
+        {
+          values[num_derivatives + row] += transform[row][col]*derivatives[col];
+        }
+      }
+      // Delete pointer to array of derivatives on FIAT element
+      delete [] derivatives;
+    
+      // Delete pointer to array of combinations of derivatives and transform
+      for (unsigned int row = 0; row < num_derivatives; row++)
+      {
+        delete [] combinations[row];
+        delete [] transform[row];
+      }
+    
+      delete [] combinations;
+      delete [] transform;
+    }
+    
+}
+
+/// Evaluate order n derivatives of all basis functions at given point in cell
+void magmaequations_0_finite_element_1::evaluate_basis_derivatives_all(unsigned int n,
+                                                   double* values,
+                                                   const double* coordinates,
+                                                   const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
+}
+
+/// Evaluate linear functional for dof i on the function f
+double magmaequations_0_finite_element_1::evaluate_dof(unsigned int i,
+                                   const ufc::function& f,
+                                   const ufc::cell& c) const
+{
+    // The reference points, direction and weights:
+    static const double X[12][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}, {{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}};
+    static const double W[12][1] = {{1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}};
+    static const double D[12][1][2] = {{{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{0, 1}}, {{0, 1}}, {{0, 1}}, {{0, 1}}, {{0, 1}}, {{0, 1}}};
+    
+    const double * const * x = c.coordinates;
+    double result = 0.0;
+    // Iterate over the points:
+    // Evaluate basis functions for affine mapping
+    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    
+    // Compute affine mapping y = F(X)
+    double y[2];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
+    
+    // Evaluate function at physical points
+    double values[2];
+    f.evaluate(values, y, c);
+    
+    // Map function values using appropriate mapping
+    // Affine map: Do nothing
+    
+    // Note that we do not map the weights (yet).
+    
+    // Take directional components
+    for(int k = 0; k < 2; k++)
+      result += values[k]*D[i][0][k];
+    // Multiply by weights
+    result *= W[i][0];
+    
+    return result;
+}
+
+/// Evaluate linear functionals for all dofs on the function f
+void magmaequations_0_finite_element_1::evaluate_dofs(double* values,
+                                  const ufc::function& f,
+                                  const ufc::cell& c) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Interpolate vertex values from dof values
+void magmaequations_0_finite_element_1::interpolate_vertex_values(double* vertex_values,
+                                              const double* dof_values,
+                                              const ufc::cell& c) const
+{
+    // Evaluate at vertices and use affine mapping
+    vertex_values[0] = dof_values[0];
+    vertex_values[2] = dof_values[1];
+    vertex_values[4] = dof_values[2];
+    // Evaluate at vertices and use affine mapping
+    vertex_values[1] = dof_values[6];
+    vertex_values[3] = dof_values[7];
+    vertex_values[5] = dof_values[8];
+}
+
+/// Return the number of sub elements (for a mixed element)
+unsigned int magmaequations_0_finite_element_1::num_sub_elements() const
+{
+    return 2;
+}
+
+/// Create a new finite element for sub element i (for a mixed element)
+ufc::finite_element* magmaequations_0_finite_element_1::create_sub_element(unsigned int i) const
+{
+    switch ( i )
+    {
+    case 0:
+      return new magmaequations_0_finite_element_1_0();
+      break;
+    case 1:
+      return new magmaequations_0_finite_element_1_1();
+      break;
+    }
+    return 0;
+}
+
+
+/// Constructor
+magmaequations_0_finite_element_2_0::magmaequations_0_finite_element_2_0() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+magmaequations_0_finite_element_2_0::~magmaequations_0_finite_element_2_0()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* magmaequations_0_finite_element_2_0::signature() const
+{
+    return "FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
+}
+
+/// Return the cell shape
+ufc::shape magmaequations_0_finite_element_2_0::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int magmaequations_0_finite_element_2_0::space_dimension() const
+{
+    return 6;
+}
+
+/// Return the rank of the value space
+unsigned int magmaequations_0_finite_element_2_0::value_rank() const
+{
+    return 0;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int magmaequations_0_finite_element_2_0::value_dimension(unsigned int i) const
+{
+    return 1;
+}
+
+/// Evaluate basis function i at given point in cell
+void magmaequations_0_finite_element_2_0::evaluate_basis(unsigned int i,
+                                   double* values,
+                                   const double* coordinates,
+                                   const ufc::cell& c) const
+{
+    // Extract vertex coordinates
+    const double * const * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Reset values
+    *values = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+    const double psitilde_bs_1_0 = 1;
+    const double psitilde_bs_1_1 = 2.5*y + 1.5;
+    const double psitilde_bs_2_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+    const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+    const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[6][6] = \
+    {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+    {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+    {0, 0, 0.2, 0, 0, 0.163299316185545},
+    {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+    {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+    {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+    // Extract relevant coefficients
+    const double coeff0_0 = coefficients0[dof][0];
+    const double coeff0_1 = coefficients0[dof][1];
+    const double coeff0_2 = coefficients0[dof][2];
+    const double coeff0_3 = coefficients0[dof][3];
+    const double coeff0_4 = coefficients0[dof][4];
+    const double coeff0_5 = coefficients0[dof][5];
+    
+    // Compute value(s)
+    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
+}
+
+/// Evaluate all basis functions at given point in cell
+void magmaequations_0_finite_element_2_0::evaluate_basis_all(double* values,
+                                       const double* coordinates,
+                                       const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
+}
+
+/// Evaluate order n derivatives of basis function i at given point in cell
+void magmaequations_0_finite_element_2_0::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 * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 2;
+    
+    
+    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
+    unsigned int **combinations = new unsigned int *[num_derivatives];
+    
+    for (unsigned int j = 0; j < num_derivatives; j++)
+    {
+      combinations[j] = new unsigned int [n];
+      for (unsigned int k = 0; k < n; k++)
+        combinations[j][k] = 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] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
+    
+    // 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
+    for (unsigned int j = 0; j < 1*num_derivatives; j++)
+      values[j] = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+    const double psitilde_bs_1_0 = 1;
+    const double psitilde_bs_1_1 = 2.5*y + 1.5;
+    const double psitilde_bs_2_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+    const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+    const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[6][6] = \
+    {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+    {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+    {0, 0, 0.2, 0, 0, 0.163299316185545},
+    {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+    {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+    {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+    // Interesting (new) part
+    // Tables of derivatives of the polynomial base (transpose)
+    static const double dmats0[6][6] = \
+    {{0, 0, 0, 0, 0, 0},
+    {4.89897948556636, 0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0},
+    {0, 9.48683298050514, 0, 0, 0, 0},
+    {4, 0, 7.07106781186548, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0}};
+    
+    static const double dmats1[6][6] = \
+    {{0, 0, 0, 0, 0, 0},
+    {2.44948974278318, 0, 0, 0, 0, 0},
+    {4.24264068711928, 0, 0, 0, 0, 0},
+    {2.58198889747161, 4.74341649025257, -0.912870929175277, 0, 0, 0},
+    {2, 6.12372435695795, 3.53553390593274, 0, 0, 0},
+    {-2.3094010767585, 0, 8.16496580927726, 0, 0, 0}};
+    
+    // Compute reference derivatives
+    // Declare pointer to array of derivatives on FIAT element
+    double *derivatives = new double [num_derivatives];
+    
+    // Declare coefficients
+    double coeff0_0 = 0;
+    double coeff0_1 = 0;
+    double coeff0_2 = 0;
+    double coeff0_3 = 0;
+    double coeff0_4 = 0;
+    double coeff0_5 = 0;
+    
+    // Declare new coefficients
+    double new_coeff0_0 = 0;
+    double new_coeff0_1 = 0;
+    double new_coeff0_2 = 0;
+    double new_coeff0_3 = 0;
+    double new_coeff0_4 = 0;
+    double new_coeff0_5 = 0;
+    
+    // Loop possible derivatives
+    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+    {
+      // Get values from coefficients array
+      new_coeff0_0 = coefficients0[dof][0];
+      new_coeff0_1 = coefficients0[dof][1];
+      new_coeff0_2 = coefficients0[dof][2];
+      new_coeff0_3 = coefficients0[dof][3];
+      new_coeff0_4 = coefficients0[dof][4];
+      new_coeff0_5 = coefficients0[dof][5];
+    
+      // Loop derivative order
+      for (unsigned int j = 0; j < n; j++)
+      {
+        // Update old coefficients
+        coeff0_0 = new_coeff0_0;
+        coeff0_1 = new_coeff0_1;
+        coeff0_2 = new_coeff0_2;
+        coeff0_3 = new_coeff0_3;
+        coeff0_4 = new_coeff0_4;
+        coeff0_5 = new_coeff0_5;
+    
+        if(combinations[deriv_num][j] == 0)
+        {
+          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
+          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
+          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
+          new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
+          new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
+          new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
+        }
+        if(combinations[deriv_num][j] == 1)
+        {
+          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
+          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
+          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
+          new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
+          new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
+          new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
+        }
+    
+      }
+      // Compute derivatives on reference element as dot product of coefficients and basisvalues
+      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
+    }
+    
+    // Transform derivatives back to physical element
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      for (unsigned int col = 0; col < num_derivatives; col++)
+      {
+        values[row] += transform[row][col]*derivatives[col];
+      }
+    }
+    // Delete pointer to array of derivatives on FIAT element
+    delete [] derivatives;
+    
+    // Delete pointer to array of combinations of derivatives and transform
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      delete [] combinations[row];
+      delete [] transform[row];
+    }
+    
+    delete [] combinations;
+    delete [] transform;
+}
+
+/// Evaluate order n derivatives of all basis functions at given point in cell
+void magmaequations_0_finite_element_2_0::evaluate_basis_derivatives_all(unsigned int n,
+                                                   double* values,
+                                                   const double* coordinates,
+                                                   const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
+}
+
+/// Evaluate linear functional for dof i on the function f
+double magmaequations_0_finite_element_2_0::evaluate_dof(unsigned int i,
+                                   const ufc::function& f,
+                                   const ufc::cell& c) const
+{
+    // The reference points, direction and weights:
+    static const double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}};
+    static const double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
+    static const double D[6][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}, {{1}}, {{1}}};
+    
+    const double * const * x = c.coordinates;
+    double result = 0.0;
+    // Iterate over the points:
+    // Evaluate basis functions for affine mapping
+    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    
+    // Compute affine mapping y = F(X)
+    double y[2];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
+    
+    // Evaluate function at physical points
+    double values[1];
+    f.evaluate(values, y, c);
+    
+    // Map function values using appropriate mapping
+    // Affine map: Do nothing
+    
+    // Note that we do not map the weights (yet).
+    
+    // Take directional components
+    for(int k = 0; k < 1; k++)
+      result += values[k]*D[i][0][k];
+    // Multiply by weights
+    result *= W[i][0];
+    
+    return result;
+}
+
+/// Evaluate linear functionals for all dofs on the function f
+void magmaequations_0_finite_element_2_0::evaluate_dofs(double* values,
+                                  const ufc::function& f,
+                                  const ufc::cell& c) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Interpolate vertex values from dof values
+void magmaequations_0_finite_element_2_0::interpolate_vertex_values(double* vertex_values,
+                                              const double* dof_values,
+                                              const ufc::cell& c) const
+{
+    // Evaluate at vertices and use affine mapping
+    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)
+unsigned int magmaequations_0_finite_element_2_0::num_sub_elements() const
+{
+    return 1;
+}
+
+/// Create a new finite element for sub element i (for a mixed element)
+ufc::finite_element* magmaequations_0_finite_element_2_0::create_sub_element(unsigned int i) const
+{
+    return new magmaequations_0_finite_element_2_0();
+}
+
+
+/// Constructor
+magmaequations_0_finite_element_2_1::magmaequations_0_finite_element_2_1() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+magmaequations_0_finite_element_2_1::~magmaequations_0_finite_element_2_1()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* magmaequations_0_finite_element_2_1::signature() const
+{
+    return "FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
+}
+
+/// Return the cell shape
+ufc::shape magmaequations_0_finite_element_2_1::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int magmaequations_0_finite_element_2_1::space_dimension() const
+{
+    return 6;
+}
+
+/// Return the rank of the value space
+unsigned int magmaequations_0_finite_element_2_1::value_rank() const
+{
+    return 0;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int magmaequations_0_finite_element_2_1::value_dimension(unsigned int i) const
+{
+    return 1;
+}
+
+/// Evaluate basis function i at given point in cell
+void magmaequations_0_finite_element_2_1::evaluate_basis(unsigned int i,
+                                   double* values,
+                                   const double* coordinates,
+                                   const ufc::cell& c) const
+{
+    // Extract vertex coordinates
+    const double * const * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Reset values
+    *values = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+    const double psitilde_bs_1_0 = 1;
+    const double psitilde_bs_1_1 = 2.5*y + 1.5;
+    const double psitilde_bs_2_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+    const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+    const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[6][6] = \
+    {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+    {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+    {0, 0, 0.2, 0, 0, 0.163299316185545},
+    {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+    {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+    {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+    // Extract relevant coefficients
+    const double coeff0_0 = coefficients0[dof][0];
+    const double coeff0_1 = coefficients0[dof][1];
+    const double coeff0_2 = coefficients0[dof][2];
+    const double coeff0_3 = coefficients0[dof][3];
+    const double coeff0_4 = coefficients0[dof][4];
+    const double coeff0_5 = coefficients0[dof][5];
+    
+    // Compute value(s)
+    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
+}
+
+/// Evaluate all basis functions at given point in cell
+void magmaequations_0_finite_element_2_1::evaluate_basis_all(double* values,
+                                       const double* coordinates,
+                                       const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
+}
+
+/// Evaluate order n derivatives of basis function i at given point in cell
+void magmaequations_0_finite_element_2_1::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 * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 2;
+    
+    
+    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
+    unsigned int **combinations = new unsigned int *[num_derivatives];
+    
+    for (unsigned int j = 0; j < num_derivatives; j++)
+    {
+      combinations[j] = new unsigned int [n];
+      for (unsigned int k = 0; k < n; k++)
+        combinations[j][k] = 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] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
+    
+    // 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
+    for (unsigned int j = 0; j < 1*num_derivatives; j++)
+      values[j] = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+    const double psitilde_bs_1_0 = 1;
+    const double psitilde_bs_1_1 = 2.5*y + 1.5;
+    const double psitilde_bs_2_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+    const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+    const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[6][6] = \
+    {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+    {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+    {0, 0, 0.2, 0, 0, 0.163299316185545},
+    {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+    {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+    {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+    // Interesting (new) part
+    // Tables of derivatives of the polynomial base (transpose)
+    static const double dmats0[6][6] = \
+    {{0, 0, 0, 0, 0, 0},
+    {4.89897948556636, 0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0},
+    {0, 9.48683298050514, 0, 0, 0, 0},
+    {4, 0, 7.07106781186548, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0}};
+    
+    static const double dmats1[6][6] = \
+    {{0, 0, 0, 0, 0, 0},
+    {2.44948974278318, 0, 0, 0, 0, 0},
+    {4.24264068711928, 0, 0, 0, 0, 0},
+    {2.58198889747161, 4.74341649025257, -0.912870929175277, 0, 0, 0},
+    {2, 6.12372435695795, 3.53553390593274, 0, 0, 0},
+    {-2.3094010767585, 0, 8.16496580927726, 0, 0, 0}};
+    
+    // Compute reference derivatives
+    // Declare pointer to array of derivatives on FIAT element
+    double *derivatives = new double [num_derivatives];
+    
+    // Declare coefficients
+    double coeff0_0 = 0;
+    double coeff0_1 = 0;
+    double coeff0_2 = 0;
+    double coeff0_3 = 0;
+    double coeff0_4 = 0;
+    double coeff0_5 = 0;
+    
+    // Declare new coefficients
+    double new_coeff0_0 = 0;
+    double new_coeff0_1 = 0;
+    double new_coeff0_2 = 0;
+    double new_coeff0_3 = 0;
+    double new_coeff0_4 = 0;
+    double new_coeff0_5 = 0;
+    
+    // Loop possible derivatives
+    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+    {
+      // Get values from coefficients array
+      new_coeff0_0 = coefficients0[dof][0];
+      new_coeff0_1 = coefficients0[dof][1];
+      new_coeff0_2 = coefficients0[dof][2];
+      new_coeff0_3 = coefficients0[dof][3];
+      new_coeff0_4 = coefficients0[dof][4];
+      new_coeff0_5 = coefficients0[dof][5];
+    
+      // Loop derivative order
+      for (unsigned int j = 0; j < n; j++)
+      {
+        // Update old coefficients
+        coeff0_0 = new_coeff0_0;
+        coeff0_1 = new_coeff0_1;
+        coeff0_2 = new_coeff0_2;
+        coeff0_3 = new_coeff0_3;
+        coeff0_4 = new_coeff0_4;
+        coeff0_5 = new_coeff0_5;
+    
+        if(combinations[deriv_num][j] == 0)
+        {
+          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
+          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
+          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
+          new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
+          new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
+          new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
+        }
+        if(combinations[deriv_num][j] == 1)
+        {
+          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
+          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
+          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
+          new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
+          new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
+          new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
+        }
+    
+      }
+      // Compute derivatives on reference element as dot product of coefficients and basisvalues
+      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
+    }
+    
+    // Transform derivatives back to physical element
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      for (unsigned int col = 0; col < num_derivatives; col++)
+      {
+        values[row] += transform[row][col]*derivatives[col];
+      }
+    }
+    // Delete pointer to array of derivatives on FIAT element
+    delete [] derivatives;
+    
+    // Delete pointer to array of combinations of derivatives and transform
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      delete [] combinations[row];
+      delete [] transform[row];
+    }
+    
+    delete [] combinations;
+    delete [] transform;
+}
+
+/// Evaluate order n derivatives of all basis functions at given point in cell
+void magmaequations_0_finite_element_2_1::evaluate_basis_derivatives_all(unsigned int n,
+                                                   double* values,
+                                                   const double* coordinates,
+                                                   const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
+}
+
+/// Evaluate linear functional for dof i on the function f
+double magmaequations_0_finite_element_2_1::evaluate_dof(unsigned int i,
+                                   const ufc::function& f,
+                                   const ufc::cell& c) const
+{
+    // The reference points, direction and weights:
+    static const double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}};
+    static const double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
+    static const double D[6][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}, {{1}}, {{1}}};
+    
+    const double * const * x = c.coordinates;
+    double result = 0.0;
+    // Iterate over the points:
+    // Evaluate basis functions for affine mapping
+    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    
+    // Compute affine mapping y = F(X)
+    double y[2];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
+    
+    // Evaluate function at physical points
+    double values[1];
+    f.evaluate(values, y, c);
+    
+    // Map function values using appropriate mapping
+    // Affine map: Do nothing
+    
+    // Note that we do not map the weights (yet).
+    
+    // Take directional components
+    for(int k = 0; k < 1; k++)
+      result += values[k]*D[i][0][k];
+    // Multiply by weights
+    result *= W[i][0];
+    
+    return result;
+}
+
+/// Evaluate linear functionals for all dofs on the function f
+void magmaequations_0_finite_element_2_1::evaluate_dofs(double* values,
+                                  const ufc::function& f,
+                                  const ufc::cell& c) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Interpolate vertex values from dof values
+void magmaequations_0_finite_element_2_1::interpolate_vertex_values(double* vertex_values,
+                                              const double* dof_values,
+                                              const ufc::cell& c) const
+{
+    // Evaluate at vertices and use affine mapping
+    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)
+unsigned int magmaequations_0_finite_element_2_1::num_sub_elements() const
+{
+    return 1;
+}
+
+/// Create a new finite element for sub element i (for a mixed element)
+ufc::finite_element* magmaequations_0_finite_element_2_1::create_sub_element(unsigned int i) const
+{
+    return new magmaequations_0_finite_element_2_1();
+}
+
+
+/// Constructor
+magmaequations_0_finite_element_2::magmaequations_0_finite_element_2() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+magmaequations_0_finite_element_2::~magmaequations_0_finite_element_2()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* magmaequations_0_finite_element_2::signature() const
+{
+    return "MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)], **{'value_shape': (2,) })";
+}
+
+/// Return the cell shape
+ufc::shape magmaequations_0_finite_element_2::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int magmaequations_0_finite_element_2::space_dimension() const
+{
+    return 12;
+}
+
+/// Return the rank of the value space
+unsigned int magmaequations_0_finite_element_2::value_rank() const
+{
+    return 1;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int magmaequations_0_finite_element_2::value_dimension(unsigned int i) const
+{
+    return 2;
+}
+
+/// Evaluate basis function i at given point in cell
+void magmaequations_0_finite_element_2::evaluate_basis(unsigned int i,
+                                   double* values,
+                                   const double* coordinates,
+                                   const ufc::cell& c) const
+{
+    // Extract vertex coordinates
+    const double * const * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Reset values
+    values[0] = 0;
+    values[1] = 0;
+    
+    if (0 <= i && i <= 5)
+    {
+      // Map degree of freedom to element degree of freedom
+      const unsigned int dof = i;
+    
+      // Generate scalings
+      const double scalings_y_0 = 1;
+      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+      const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+      // Compute psitilde_a
+      const double psitilde_a_0 = 1;
+      const double psitilde_a_1 = x;
+      const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+      // Compute psitilde_bs
+      const double psitilde_bs_0_0 = 1;
+      const double psitilde_bs_0_1 = 1.5*y + 0.5;
+      const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+      const double psitilde_bs_1_0 = 1;
+      const double psitilde_bs_1_1 = 2.5*y + 1.5;
+      const double psitilde_bs_2_0 = 1;
+    
+      // Compute basisvalues
+      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+      const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+      const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+      const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+      // Table(s) of coefficients
+      static const double coefficients0[6][6] =   \
+      {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+      {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+      {0, 0, 0.2, 0, 0, 0.163299316185545},
+      {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+      {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+      {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+      // Extract relevant coefficients
+      const double coeff0_0 =   coefficients0[dof][0];
+      const double coeff0_1 =   coefficients0[dof][1];
+      const double coeff0_2 =   coefficients0[dof][2];
+      const double coeff0_3 =   coefficients0[dof][3];
+      const double coeff0_4 =   coefficients0[dof][4];
+      const double coeff0_5 =   coefficients0[dof][5];
+    
+      // Compute value(s)
+      values[0] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
+    }
+    
+    if (6 <= i && i <= 11)
+    {
+      // Map degree of freedom to element degree of freedom
+      const unsigned int dof = i - 6;
+    
+      // Generate scalings
+      const double scalings_y_0 = 1;
+      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+      const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+      // Compute psitilde_a
+      const double psitilde_a_0 = 1;
+      const double psitilde_a_1 = x;
+      const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+      // Compute psitilde_bs
+      const double psitilde_bs_0_0 = 1;
+      const double psitilde_bs_0_1 = 1.5*y + 0.5;
+      const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+      const double psitilde_bs_1_0 = 1;
+      const double psitilde_bs_1_1 = 2.5*y + 1.5;
+      const double psitilde_bs_2_0 = 1;
+    
+      // Compute basisvalues
+      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+      const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+      const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+      const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+      // Table(s) of coefficients
+      static const double coefficients0[6][6] =   \
+      {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+      {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+      {0, 0, 0.2, 0, 0, 0.163299316185545},
+      {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+      {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+      {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+      // Extract relevant coefficients
+      const double coeff0_0 =   coefficients0[dof][0];
+      const double coeff0_1 =   coefficients0[dof][1];
+      const double coeff0_2 =   coefficients0[dof][2];
+      const double coeff0_3 =   coefficients0[dof][3];
+      const double coeff0_4 =   coefficients0[dof][4];
+      const double coeff0_5 =   coefficients0[dof][5];
+    
+      // Compute value(s)
+      values[1] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
+    }
+    
+}
+
+/// Evaluate all basis functions at given point in cell
+void magmaequations_0_finite_element_2::evaluate_basis_all(double* values,
+                                       const double* coordinates,
+                                       const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
+}
+
+/// Evaluate order n derivatives of basis function i at given point in cell
+void magmaequations_0_finite_element_2::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 * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 2;
+    
+    
+    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
+    unsigned int **combinations = new unsigned int *[num_derivatives];
+    
+    for (unsigned int j = 0; j < num_derivatives; j++)
+    {
+      combinations[j] = new unsigned int [n];
+      for (unsigned int k = 0; k < n; k++)
+        combinations[j][k] = 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] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
+    
+    // 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
+    for (unsigned int j = 0; j < 2*num_derivatives; j++)
+      values[j] = 0;
+    
+    if (0 <= i && i <= 5)
+    {
+      // Map degree of freedom to element degree of freedom
+      const unsigned int dof = i;
+    
+      // Generate scalings
+      const double scalings_y_0 = 1;
+      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+      const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+      // Compute psitilde_a
+      const double psitilde_a_0 = 1;
+      const double psitilde_a_1 = x;
+      const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+      // Compute psitilde_bs
+      const double psitilde_bs_0_0 = 1;
+      const double psitilde_bs_0_1 = 1.5*y + 0.5;
+      const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+      const double psitilde_bs_1_0 = 1;
+      const double psitilde_bs_1_1 = 2.5*y + 1.5;
+      const double psitilde_bs_2_0 = 1;
+    
+      // Compute basisvalues
+      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+      const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+      const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+      const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+      // Table(s) of coefficients
+      static const double coefficients0[6][6] =   \
+      {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+      {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+      {0, 0, 0.2, 0, 0, 0.163299316185545},
+      {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+      {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+      {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+      // Interesting (new) part
+      // Tables of derivatives of the polynomial base (transpose)
+      static const double dmats0[6][6] =   \
+      {{0, 0, 0, 0, 0, 0},
+      {4.89897948556636, 0, 0, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0},
+      {0, 9.48683298050514, 0, 0, 0, 0},
+      {4, 0, 7.07106781186548, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0}};
+    
+      static const double dmats1[6][6] =   \
+      {{0, 0, 0, 0, 0, 0},
+      {2.44948974278318, 0, 0, 0, 0, 0},
+      {4.24264068711928, 0, 0, 0, 0, 0},
+      {2.58198889747161, 4.74341649025257, -0.912870929175277, 0, 0, 0},
+      {2, 6.12372435695795, 3.53553390593274, 0, 0, 0},
+      {-2.3094010767585, 0, 8.16496580927726, 0, 0, 0}};
+    
+      // Compute reference derivatives
+      // Declare pointer to array of derivatives on FIAT element
+      double *derivatives = new double [num_derivatives];
+    
+      // Declare coefficients
+      double coeff0_0 = 0;
+      double coeff0_1 = 0;
+      double coeff0_2 = 0;
+      double coeff0_3 = 0;
+      double coeff0_4 = 0;
+      double coeff0_5 = 0;
+    
+      // Declare new coefficients
+      double new_coeff0_0 = 0;
+      double new_coeff0_1 = 0;
+      double new_coeff0_2 = 0;
+      double new_coeff0_3 = 0;
+      double new_coeff0_4 = 0;
+      double new_coeff0_5 = 0;
+    
+      // Loop possible derivatives
+      for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+      {
+        // Get values from coefficients array
+        new_coeff0_0 = coefficients0[dof][0];
+        new_coeff0_1 = coefficients0[dof][1];
+        new_coeff0_2 = coefficients0[dof][2];
+        new_coeff0_3 = coefficients0[dof][3];
+        new_coeff0_4 = coefficients0[dof][4];
+        new_coeff0_5 = coefficients0[dof][5];
+    
+        // Loop derivative order
+        for (unsigned int j = 0; j < n; j++)
+        {
+          // Update old coefficients
+          coeff0_0 = new_coeff0_0;
+          coeff0_1 = new_coeff0_1;
+          coeff0_2 = new_coeff0_2;
+          coeff0_3 = new_coeff0_3;
+          coeff0_4 = new_coeff0_4;
+          coeff0_5 = new_coeff0_5;
+    
+          if(combinations[deriv_num][j] == 0)
+          {
+            new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
+            new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
+            new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
+            new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
+            new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
+            new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
+          }
+          if(combinations[deriv_num][j] == 1)
+          {
+            new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
+            new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
+            new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
+            new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
+            new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
+            new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
+          }
+    
+        }
+        // Compute derivatives on reference element as dot product of coefficients and basisvalues
+        derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
+      }
+    
+      // Transform derivatives back to physical element
+      for (unsigned int row = 0; row < num_derivatives; row++)
+      {
+        for (unsigned int col = 0; col < num_derivatives; col++)
+        {
+          values[row] += transform[row][col]*derivatives[col];
+        }
+      }
+      // Delete pointer to array of derivatives on FIAT element
+      delete [] derivatives;
+    
+      // Delete pointer to array of combinations of derivatives and transform
+      for (unsigned int row = 0; row < num_derivatives; row++)
+      {
+        delete [] combinations[row];
+        delete [] transform[row];
+      }
+    
+      delete [] combinations;
+      delete [] transform;
+    }
+    
+    if (6 <= i && i <= 11)
+    {
+      // Map degree of freedom to element degree of freedom
+      const unsigned int dof = i - 6;
+    
+      // Generate scalings
+      const double scalings_y_0 = 1;
+      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+      const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+      // Compute psitilde_a
+      const double psitilde_a_0 = 1;
+      const double psitilde_a_1 = x;
+      const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+      // Compute psitilde_bs
+      const double psitilde_bs_0_0 = 1;
+      const double psitilde_bs_0_1 = 1.5*y + 0.5;
+      const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+      const double psitilde_bs_1_0 = 1;
+      const double psitilde_bs_1_1 = 2.5*y + 1.5;
+      const double psitilde_bs_2_0 = 1;
+    
+      // Compute basisvalues
+      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+      const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+      const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+      const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+      // Table(s) of coefficients
+      static const double coefficients0[6][6] =   \
+      {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+      {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+      {0, 0, 0.2, 0, 0, 0.163299316185545},
+      {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+      {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+      {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+      // Interesting (new) part
+      // Tables of derivatives of the polynomial base (transpose)
+      static const double dmats0[6][6] =   \
+      {{0, 0, 0, 0, 0, 0},
+      {4.89897948556636, 0, 0, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0},
+      {0, 9.48683298050514, 0, 0, 0, 0},
+      {4, 0, 7.07106781186548, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0}};
+    
+      static const double dmats1[6][6] =   \
+      {{0, 0, 0, 0, 0, 0},
+      {2.44948974278318, 0, 0, 0, 0, 0},
+      {4.24264068711928, 0, 0, 0, 0, 0},
+      {2.58198889747161, 4.74341649025257, -0.912870929175277, 0, 0, 0},
+      {2, 6.12372435695795, 3.53553390593274, 0, 0, 0},
+      {-2.3094010767585, 0, 8.16496580927726, 0, 0, 0}};
+    
+      // Compute reference derivatives
+      // Declare pointer to array of derivatives on FIAT element
+      double *derivatives = new double [num_derivatives];
+    
+      // Declare coefficients
+      double coeff0_0 = 0;
+      double coeff0_1 = 0;
+      double coeff0_2 = 0;
+      double coeff0_3 = 0;
+      double coeff0_4 = 0;
+      double coeff0_5 = 0;
+    
+      // Declare new coefficients
+      double new_coeff0_0 = 0;
+      double new_coeff0_1 = 0;
+      double new_coeff0_2 = 0;
+      double new_coeff0_3 = 0;
+      double new_coeff0_4 = 0;
+      double new_coeff0_5 = 0;
+    
+      // Loop possible derivatives
+      for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+      {
+        // Get values from coefficients array
+        new_coeff0_0 = coefficients0[dof][0];
+        new_coeff0_1 = coefficients0[dof][1];
+        new_coeff0_2 = coefficients0[dof][2];
+        new_coeff0_3 = coefficients0[dof][3];
+        new_coeff0_4 = coefficients0[dof][4];
+        new_coeff0_5 = coefficients0[dof][5];
+    
+        // Loop derivative order
+        for (unsigned int j = 0; j < n; j++)
+        {
+          // Update old coefficients
+          coeff0_0 = new_coeff0_0;
+          coeff0_1 = new_coeff0_1;
+          coeff0_2 = new_coeff0_2;
+          coeff0_3 = new_coeff0_3;
+          coeff0_4 = new_coeff0_4;
+          coeff0_5 = new_coeff0_5;
+    
+          if(combinations[deriv_num][j] == 0)
+          {
+            new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
+            new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
+            new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
+            new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
+            new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
+            new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
+          }
+          if(combinations[deriv_num][j] == 1)
+          {
+            new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
+            new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
+            new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
+            new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
+            new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
+            new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
+          }
+    
+        }
+        // Compute derivatives on reference element as dot product of coefficients and basisvalues
+        derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
+      }
+    
+      // Transform derivatives back to physical element
+      for (unsigned int row = 0; row < num_derivatives; row++)
+      {
+        for (unsigned int col = 0; col < num_derivatives; col++)
+        {
+          values[num_derivatives + row] += transform[row][col]*derivatives[col];
+        }
+      }
+      // Delete pointer to array of derivatives on FIAT element
+      delete [] derivatives;
+    
+      // Delete pointer to array of combinations of derivatives and transform
+      for (unsigned int row = 0; row < num_derivatives; row++)
+      {
+        delete [] combinations[row];
+        delete [] transform[row];
+      }
+    
+      delete [] combinations;
+      delete [] transform;
+    }
+    
+}
+
+/// Evaluate order n derivatives of all basis functions at given point in cell
+void magmaequations_0_finite_element_2::evaluate_basis_derivatives_all(unsigned int n,
+                                                   double* values,
+                                                   const double* coordinates,
+                                                   const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
+}
+
+/// Evaluate linear functional for dof i on the function f
+double magmaequations_0_finite_element_2::evaluate_dof(unsigned int i,
+                                   const ufc::function& f,
+                                   const ufc::cell& c) const
+{
+    // The reference points, direction and weights:
+    static const double X[12][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}, {{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}};
+    static const double W[12][1] = {{1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}};
+    static const double D[12][1][2] = {{{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{0, 1}}, {{0, 1}}, {{0, 1}}, {{0, 1}}, {{0, 1}}, {{0, 1}}};
+    
+    const double * const * x = c.coordinates;
+    double result = 0.0;
+    // Iterate over the points:
+    // Evaluate basis functions for affine mapping
+    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    
+    // Compute affine mapping y = F(X)
+    double y[2];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
+    
+    // Evaluate function at physical points
+    double values[2];
+    f.evaluate(values, y, c);
+    
+    // Map function values using appropriate mapping
+    // Affine map: Do nothing
+    
+    // Note that we do not map the weights (yet).
+    
+    // Take directional components
+    for(int k = 0; k < 2; k++)
+      result += values[k]*D[i][0][k];
+    // Multiply by weights
+    result *= W[i][0];
+    
+    return result;
+}
+
+/// Evaluate linear functionals for all dofs on the function f
+void magmaequations_0_finite_element_2::evaluate_dofs(double* values,
+                                  const ufc::function& f,
+                                  const ufc::cell& c) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Interpolate vertex values from dof values
+void magmaequations_0_finite_element_2::interpolate_vertex_values(double* vertex_values,
+                                              const double* dof_values,
+                                              const ufc::cell& c) const
+{
+    // Evaluate at vertices and use affine mapping
+    vertex_values[0] = dof_values[0];
+    vertex_values[2] = dof_values[1];
+    vertex_values[4] = dof_values[2];
+    // Evaluate at vertices and use affine mapping
+    vertex_values[1] = dof_values[6];
+    vertex_values[3] = dof_values[7];
+    vertex_values[5] = dof_values[8];
+}
+
+/// Return the number of sub elements (for a mixed element)
+unsigned int magmaequations_0_finite_element_2::num_sub_elements() const
+{
+    return 2;
+}
+
+/// Create a new finite element for sub element i (for a mixed element)
+ufc::finite_element* magmaequations_0_finite_element_2::create_sub_element(unsigned int i) const
+{
+    switch ( i )
+    {
+    case 0:
+      return new magmaequations_0_finite_element_2_0();
+      break;
+    case 1:
+      return new magmaequations_0_finite_element_2_1();
+      break;
+    }
+    return 0;
+}
+
+
+/// Constructor
+magmaequations_0_finite_element_3::magmaequations_0_finite_element_3() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+magmaequations_0_finite_element_3::~magmaequations_0_finite_element_3()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* magmaequations_0_finite_element_3::signature() const
+{
+    return "FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 0)";
+}
+
+/// Return the cell shape
+ufc::shape magmaequations_0_finite_element_3::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int magmaequations_0_finite_element_3::space_dimension() const
+{
+    return 1;
+}
+
+/// Return the rank of the value space
+unsigned int magmaequations_0_finite_element_3::value_rank() const
+{
+    return 0;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int magmaequations_0_finite_element_3::value_dimension(unsigned int i) const
+{
+    return 1;
+}
+
+/// Evaluate basis function i at given point in cell
+void magmaequations_0_finite_element_3::evaluate_basis(unsigned int i,
+                                   double* values,
+                                   const double* coordinates,
+                                   const ufc::cell& c) const
+{
+    // Extract vertex coordinates
+    const double * const * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Reset values
+    *values = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[1][1] = \
+    {{1.41421356237309}};
+    
+    // Extract relevant coefficients
+    const double coeff0_0 = coefficients0[dof][0];
+    
+    // Compute value(s)
+    *values = coeff0_0*basisvalue0;
+}
+
+/// Evaluate all basis functions at given point in cell
+void magmaequations_0_finite_element_3::evaluate_basis_all(double* values,
+                                       const double* coordinates,
+                                       const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
+}
+
+/// Evaluate order n derivatives of basis function i at given point in cell
+void magmaequations_0_finite_element_3::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 * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 2;
+    
+    
+    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
+    unsigned int **combinations = new unsigned int *[num_derivatives];
+    
+    for (unsigned int j = 0; j < num_derivatives; j++)
+    {
+      combinations[j] = new unsigned int [n];
+      for (unsigned int k = 0; k < n; k++)
+        combinations[j][k] = 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] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
+    
+    // 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
+    for (unsigned int j = 0; j < 1*num_derivatives; j++)
+      values[j] = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[1][1] = \
+    {{1.41421356237309}};
+    
+    // Interesting (new) part
+    // Tables of derivatives of the polynomial base (transpose)
+    static const double dmats0[1][1] = \
+    {{0}};
+    
+    static const double dmats1[1][1] = \
+    {{0}};
+    
+    // Compute reference derivatives
+    // Declare pointer to array of derivatives on FIAT element
+    double *derivatives = new double [num_derivatives];
+    
+    // Declare coefficients
+    double coeff0_0 = 0;
+    
+    // Declare new coefficients
+    double new_coeff0_0 = 0;
+    
+    // Loop possible derivatives
+    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+    {
+      // Get values from coefficients array
+      new_coeff0_0 = coefficients0[dof][0];
+    
+      // Loop derivative order
+      for (unsigned int j = 0; j < n; j++)
+      {
+        // Update old coefficients
+        coeff0_0 = new_coeff0_0;
+    
+        if(combinations[deriv_num][j] == 0)
+        {
+          new_coeff0_0 = coeff0_0*dmats0[0][0];
+        }
+        if(combinations[deriv_num][j] == 1)
+        {
+          new_coeff0_0 = coeff0_0*dmats1[0][0];
+        }
+    
+      }
+      // Compute derivatives on reference element as dot product of coefficients and basisvalues
+      derivatives[deriv_num] = new_coeff0_0*basisvalue0;
+    }
+    
+    // Transform derivatives back to physical element
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      for (unsigned int col = 0; col < num_derivatives; col++)
+      {
+        values[row] += transform[row][col]*derivatives[col];
+      }
+    }
+    // Delete pointer to array of derivatives on FIAT element
+    delete [] derivatives;
+    
+    // Delete pointer to array of combinations of derivatives and transform
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      delete [] combinations[row];
+      delete [] transform[row];
+    }
+    
+    delete [] combinations;
+    delete [] transform;
+}
+
+/// Evaluate order n derivatives of all basis functions at given point in cell
+void magmaequations_0_finite_element_3::evaluate_basis_derivatives_all(unsigned int n,
+                                                   double* values,
+                                                   const double* coordinates,
+                                                   const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
+}
+
+/// Evaluate linear functional for dof i on the function f
+double magmaequations_0_finite_element_3::evaluate_dof(unsigned int i,
+                                   const ufc::function& f,
+                                   const ufc::cell& c) const
+{
+    // The reference points, direction and weights:
+    static const double X[1][1][2] = {{{0.333333333333333, 0.333333333333333}}};
+    static const double W[1][1] = {{1}};
+    static const double D[1][1][1] = {{{1}}};
+    
+    const double * const * x = c.coordinates;
+    double result = 0.0;
+    // Iterate over the points:
+    // Evaluate basis functions for affine mapping
+    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    
+    // Compute affine mapping y = F(X)
+    double y[2];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
+    
+    // Evaluate function at physical points
+    double values[1];
+    f.evaluate(values, y, c);
+    
+    // Map function values using appropriate mapping
+    // Affine map: Do nothing
+    
+    // Note that we do not map the weights (yet).
+    
+    // Take directional components
+    for(int k = 0; k < 1; k++)
+      result += values[k]*D[i][0][k];
+    // Multiply by weights
+    result *= W[i][0];
+    
+    return result;
+}
+
+/// Evaluate linear functionals for all dofs on the function f
+void magmaequations_0_finite_element_3::evaluate_dofs(double* values,
+                                  const ufc::function& f,
+                                  const ufc::cell& c) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Interpolate vertex values from dof values
+void magmaequations_0_finite_element_3::interpolate_vertex_values(double* vertex_values,
+                                              const double* dof_values,
+                                              const ufc::cell& c) const
+{
+    // Evaluate at vertices and use affine mapping
+    vertex_values[0] = dof_values[0];
+    vertex_values[1] = dof_values[0];
+    vertex_values[2] = dof_values[0];
+}
+
+/// Return the number of sub elements (for a mixed element)
+unsigned int magmaequations_0_finite_element_3::num_sub_elements() const
+{
+    return 1;
+}
+
+/// Create a new finite element for sub element i (for a mixed element)
+ufc::finite_element* magmaequations_0_finite_element_3::create_sub_element(unsigned int i) const
+{
+    return new magmaequations_0_finite_element_3();
+}
+
+
+/// Constructor
+magmaequations_0_finite_element_4::magmaequations_0_finite_element_4() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+magmaequations_0_finite_element_4::~magmaequations_0_finite_element_4()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* magmaequations_0_finite_element_4::signature() const
+{
+    return "FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 0)";
+}
+
+/// Return the cell shape
+ufc::shape magmaequations_0_finite_element_4::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int magmaequations_0_finite_element_4::space_dimension() const
+{
+    return 1;
+}
+
+/// Return the rank of the value space
+unsigned int magmaequations_0_finite_element_4::value_rank() const
+{
+    return 0;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int magmaequations_0_finite_element_4::value_dimension(unsigned int i) const
+{
+    return 1;
+}
+
+/// Evaluate basis function i at given point in cell
+void magmaequations_0_finite_element_4::evaluate_basis(unsigned int i,
+                                   double* values,
+                                   const double* coordinates,
+                                   const ufc::cell& c) const
+{
+    // Extract vertex coordinates
+    const double * const * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Reset values
+    *values = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[1][1] = \
+    {{1.41421356237309}};
+    
+    // Extract relevant coefficients
+    const double coeff0_0 = coefficients0[dof][0];
+    
+    // Compute value(s)
+    *values = coeff0_0*basisvalue0;
+}
+
+/// Evaluate all basis functions at given point in cell
+void magmaequations_0_finite_element_4::evaluate_basis_all(double* values,
+                                       const double* coordinates,
+                                       const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
+}
+
+/// Evaluate order n derivatives of basis function i at given point in cell
+void magmaequations_0_finite_element_4::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 * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 2;
+    
+    
+    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
+    unsigned int **combinations = new unsigned int *[num_derivatives];
+    
+    for (unsigned int j = 0; j < num_derivatives; j++)
+    {
+      combinations[j] = new unsigned int [n];
+      for (unsigned int k = 0; k < n; k++)
+        combinations[j][k] = 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] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
+    
+    // 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
+    for (unsigned int j = 0; j < 1*num_derivatives; j++)
+      values[j] = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[1][1] = \
+    {{1.41421356237309}};
+    
+    // Interesting (new) part
+    // Tables of derivatives of the polynomial base (transpose)
+    static const double dmats0[1][1] = \
+    {{0}};
+    
+    static const double dmats1[1][1] = \
+    {{0}};
+    
+    // Compute reference derivatives
+    // Declare pointer to array of derivatives on FIAT element
+    double *derivatives = new double [num_derivatives];
+    
+    // Declare coefficients
+    double coeff0_0 = 0;
+    
+    // Declare new coefficients
+    double new_coeff0_0 = 0;
+    
+    // Loop possible derivatives
+    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+    {
+      // Get values from coefficients array
+      new_coeff0_0 = coefficients0[dof][0];
+    
+      // Loop derivative order
+      for (unsigned int j = 0; j < n; j++)
+      {
+        // Update old coefficients
+        coeff0_0 = new_coeff0_0;
+    
+        if(combinations[deriv_num][j] == 0)
+        {
+          new_coeff0_0 = coeff0_0*dmats0[0][0];
+        }
+        if(combinations[deriv_num][j] == 1)
+        {
+          new_coeff0_0 = coeff0_0*dmats1[0][0];
+        }
+    
+      }
+      // Compute derivatives on reference element as dot product of coefficients and basisvalues
+      derivatives[deriv_num] = new_coeff0_0*basisvalue0;
+    }
+    
+    // Transform derivatives back to physical element
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      for (unsigned int col = 0; col < num_derivatives; col++)
+      {
+        values[row] += transform[row][col]*derivatives[col];
+      }
+    }
+    // Delete pointer to array of derivatives on FIAT element
+    delete [] derivatives;
+    
+    // Delete pointer to array of combinations of derivatives and transform
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      delete [] combinations[row];
+      delete [] transform[row];
+    }
+    
+    delete [] combinations;
+    delete [] transform;
+}
+
+/// Evaluate order n derivatives of all basis functions at given point in cell
+void magmaequations_0_finite_element_4::evaluate_basis_derivatives_all(unsigned int n,
+                                                   double* values,
+                                                   const double* coordinates,
+                                                   const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
+}
+
+/// Evaluate linear functional for dof i on the function f
+double magmaequations_0_finite_element_4::evaluate_dof(unsigned int i,
+                                   const ufc::function& f,
+                                   const ufc::cell& c) const
+{
+    // The reference points, direction and weights:
+    static const double X[1][1][2] = {{{0.333333333333333, 0.333333333333333}}};
+    static const double W[1][1] = {{1}};
+    static const double D[1][1][1] = {{{1}}};
+    
+    const double * const * x = c.coordinates;
+    double result = 0.0;
+    // Iterate over the points:
+    // Evaluate basis functions for affine mapping
+    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    
+    // Compute affine mapping y = F(X)
+    double y[2];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
+    
+    // Evaluate function at physical points
+    double values[1];
+    f.evaluate(values, y, c);
+    
+    // Map function values using appropriate mapping
+    // Affine map: Do nothing
+    
+    // Note that we do not map the weights (yet).
+    
+    // Take directional components
+    for(int k = 0; k < 1; k++)
+      result += values[k]*D[i][0][k];
+    // Multiply by weights
+    result *= W[i][0];
+    
+    return result;
+}
+
+/// Evaluate linear functionals for all dofs on the function f
+void magmaequations_0_finite_element_4::evaluate_dofs(double* values,
+                                  const ufc::function& f,
+                                  const ufc::cell& c) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Interpolate vertex values from dof values
+void magmaequations_0_finite_element_4::interpolate_vertex_values(double* vertex_values,
+                                              const double* dof_values,
+                                              const ufc::cell& c) const
+{
+    // Evaluate at vertices and use affine mapping
+    vertex_values[0] = dof_values[0];
+    vertex_values[1] = dof_values[0];
+    vertex_values[2] = dof_values[0];
+}
+
+/// Return the number of sub elements (for a mixed element)
+unsigned int magmaequations_0_finite_element_4::num_sub_elements() const
+{
+    return 1;
+}
+
+/// Create a new finite element for sub element i (for a mixed element)
+ufc::finite_element* magmaequations_0_finite_element_4::create_sub_element(unsigned int i) const
+{
+    return new magmaequations_0_finite_element_4();
+}
+
+
+/// Constructor
+magmaequations_0_finite_element_5::magmaequations_0_finite_element_5() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+magmaequations_0_finite_element_5::~magmaequations_0_finite_element_5()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* magmaequations_0_finite_element_5::signature() const
+{
+    return "FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)";
+}
+
+/// Return the cell shape
+ufc::shape magmaequations_0_finite_element_5::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int magmaequations_0_finite_element_5::space_dimension() const
+{
+    return 3;
+}
+
+/// Return the rank of the value space
+unsigned int magmaequations_0_finite_element_5::value_rank() const
+{
+    return 0;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int magmaequations_0_finite_element_5::value_dimension(unsigned int i) const
+{
+    return 1;
+}
+
+/// Evaluate basis function i at given point in cell
+void magmaequations_0_finite_element_5::evaluate_basis(unsigned int i,
+                                   double* values,
+                                   const double* coordinates,
+                                   const ufc::cell& c) const
+{
+    // Extract vertex coordinates
+    const double * const * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Reset values
+    *values = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_1_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    
+    // 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, 0.333333333333333}};
+    
+    // Extract relevant coefficients
+    const double coeff0_0 = coefficients0[dof][0];
+    const double coeff0_1 = coefficients0[dof][1];
+    const double coeff0_2 = coefficients0[dof][2];
+    
+    // Compute value(s)
+    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
+}
+
+/// Evaluate all basis functions at given point in cell
+void magmaequations_0_finite_element_5::evaluate_basis_all(double* values,
+                                       const double* coordinates,
+                                       const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
+}
+
+/// Evaluate order n derivatives of basis function i at given point in cell
+void magmaequations_0_finite_element_5::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 * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 2;
+    
+    
+    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
+    unsigned int **combinations = new unsigned int *[num_derivatives];
+    
+    for (unsigned int j = 0; j < num_derivatives; j++)
+    {
+      combinations[j] = new unsigned int [n];
+      for (unsigned int k = 0; k < n; k++)
+        combinations[j][k] = 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] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
+    
+    // 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
+    for (unsigned int j = 0; j < 1*num_derivatives; j++)
+      values[j] = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_1_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    
+    // 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, 0.333333333333333}};
+    
+    // Interesting (new) part
+    // Tables of derivatives of the polynomial base (transpose)
+    static const double dmats0[3][3] = \
+    {{0, 0, 0},
+    {4.89897948556636, 0, 0},
+    {0, 0, 0}};
+    
+    static const double dmats1[3][3] = \
+    {{0, 0, 0},
+    {2.44948974278318, 0, 0},
+    {4.24264068711928, 0, 0}};
+    
+    // Compute reference derivatives
+    // Declare pointer to array of derivatives on FIAT element
+    double *derivatives = new double [num_derivatives];
+    
+    // Declare coefficients
+    double coeff0_0 = 0;
+    double coeff0_1 = 0;
+    double coeff0_2 = 0;
+    
+    // Declare new coefficients
+    double new_coeff0_0 = 0;
+    double new_coeff0_1 = 0;
+    double new_coeff0_2 = 0;
+    
+    // Loop possible derivatives
+    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+    {
+      // Get values from coefficients array
+      new_coeff0_0 = coefficients0[dof][0];
+      new_coeff0_1 = coefficients0[dof][1];
+      new_coeff0_2 = coefficients0[dof][2];
+    
+      // Loop derivative order
+      for (unsigned int j = 0; j < n; j++)
+      {
+        // Update old coefficients
+        coeff0_0 = new_coeff0_0;
+        coeff0_1 = new_coeff0_1;
+        coeff0_2 = new_coeff0_2;
+    
+        if(combinations[deriv_num][j] == 0)
+        {
+          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
+          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
+          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
+        }
+        if(combinations[deriv_num][j] == 1)
+        {
+          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
+          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
+          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
+        }
+    
+      }
+      // Compute derivatives on reference element as dot product of coefficients and basisvalues
+      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
+    }
+    
+    // Transform derivatives back to physical element
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      for (unsigned int col = 0; col < num_derivatives; col++)
+      {
+        values[row] += transform[row][col]*derivatives[col];
+      }
+    }
+    // Delete pointer to array of derivatives on FIAT element
+    delete [] derivatives;
+    
+    // Delete pointer to array of combinations of derivatives and transform
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      delete [] combinations[row];
+      delete [] transform[row];
+    }
+    
+    delete [] combinations;
+    delete [] transform;
+}
+
+/// Evaluate order n derivatives of all basis functions at given point in cell
+void magmaequations_0_finite_element_5::evaluate_basis_derivatives_all(unsigned int n,
+                                                   double* values,
+                                                   const double* coordinates,
+                                                   const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
+}
+
+/// Evaluate linear functional for dof i on the function f
+double magmaequations_0_finite_element_5::evaluate_dof(unsigned int i,
+                                   const ufc::function& f,
+                                   const ufc::cell& c) const
+{
+    // The reference points, direction and weights:
+    static const double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
+    static const double W[3][1] = {{1}, {1}, {1}};
+    static const double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
+    
+    const double * const * x = c.coordinates;
+    double result = 0.0;
+    // Iterate over the points:
+    // Evaluate basis functions for affine mapping
+    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    
+    // Compute affine mapping y = F(X)
+    double y[2];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
+    
+    // Evaluate function at physical points
+    double values[1];
+    f.evaluate(values, y, c);
+    
+    // Map function values using appropriate mapping
+    // Affine map: Do nothing
+    
+    // Note that we do not map the weights (yet).
+    
+    // Take directional components
+    for(int k = 0; k < 1; k++)
+      result += values[k]*D[i][0][k];
+    // Multiply by weights
+    result *= W[i][0];
+    
+    return result;
+}
+
+/// Evaluate linear functionals for all dofs on the function f
+void magmaequations_0_finite_element_5::evaluate_dofs(double* values,
+                                  const ufc::function& f,
+                                  const ufc::cell& c) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Interpolate vertex values from dof values
+void magmaequations_0_finite_element_5::interpolate_vertex_values(double* vertex_values,
+                                              const double* dof_values,
+                                              const ufc::cell& c) const
+{
+    // Evaluate at vertices and use affine mapping
+    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)
+unsigned int magmaequations_0_finite_element_5::num_sub_elements() const
+{
+    return 1;
+}
+
+/// Create a new finite element for sub element i (for a mixed element)
+ufc::finite_element* magmaequations_0_finite_element_5::create_sub_element(unsigned int i) const
+{
+    return new magmaequations_0_finite_element_5();
+}
+
+
+/// Constructor
+magmaequations_0_finite_element_6::magmaequations_0_finite_element_6() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+magmaequations_0_finite_element_6::~magmaequations_0_finite_element_6()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* magmaequations_0_finite_element_6::signature() const
+{
+    return "FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)";
+}
+
+/// Return the cell shape
+ufc::shape magmaequations_0_finite_element_6::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int magmaequations_0_finite_element_6::space_dimension() const
+{
+    return 3;
+}
+
+/// Return the rank of the value space
+unsigned int magmaequations_0_finite_element_6::value_rank() const
+{
+    return 0;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int magmaequations_0_finite_element_6::value_dimension(unsigned int i) const
+{
+    return 1;
+}
+
+/// Evaluate basis function i at given point in cell
+void magmaequations_0_finite_element_6::evaluate_basis(unsigned int i,
+                                   double* values,
+                                   const double* coordinates,
+                                   const ufc::cell& c) const
+{
+    // Extract vertex coordinates
+    const double * const * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Reset values
+    *values = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_1_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    
+    // 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, 0.333333333333333}};
+    
+    // Extract relevant coefficients
+    const double coeff0_0 = coefficients0[dof][0];
+    const double coeff0_1 = coefficients0[dof][1];
+    const double coeff0_2 = coefficients0[dof][2];
+    
+    // Compute value(s)
+    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
+}
+
+/// Evaluate all basis functions at given point in cell
+void magmaequations_0_finite_element_6::evaluate_basis_all(double* values,
+                                       const double* coordinates,
+                                       const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
+}
+
+/// Evaluate order n derivatives of basis function i at given point in cell
+void magmaequations_0_finite_element_6::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 * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 2;
+    
+    
+    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
+    unsigned int **combinations = new unsigned int *[num_derivatives];
+    
+    for (unsigned int j = 0; j < num_derivatives; j++)
+    {
+      combinations[j] = new unsigned int [n];
+      for (unsigned int k = 0; k < n; k++)
+        combinations[j][k] = 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] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
+    
+    // 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
+    for (unsigned int j = 0; j < 1*num_derivatives; j++)
+      values[j] = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_1_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    
+    // 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, 0.333333333333333}};
+    
+    // Interesting (new) part
+    // Tables of derivatives of the polynomial base (transpose)
+    static const double dmats0[3][3] = \
+    {{0, 0, 0},
+    {4.89897948556636, 0, 0},
+    {0, 0, 0}};
+    
+    static const double dmats1[3][3] = \
+    {{0, 0, 0},
+    {2.44948974278318, 0, 0},
+    {4.24264068711928, 0, 0}};
+    
+    // Compute reference derivatives
+    // Declare pointer to array of derivatives on FIAT element
+    double *derivatives = new double [num_derivatives];
+    
+    // Declare coefficients
+    double coeff0_0 = 0;
+    double coeff0_1 = 0;
+    double coeff0_2 = 0;
+    
+    // Declare new coefficients
+    double new_coeff0_0 = 0;
+    double new_coeff0_1 = 0;
+    double new_coeff0_2 = 0;
+    
+    // Loop possible derivatives
+    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+    {
+      // Get values from coefficients array
+      new_coeff0_0 = coefficients0[dof][0];
+      new_coeff0_1 = coefficients0[dof][1];
+      new_coeff0_2 = coefficients0[dof][2];
+    
+      // Loop derivative order
+      for (unsigned int j = 0; j < n; j++)
+      {
+        // Update old coefficients
+        coeff0_0 = new_coeff0_0;
+        coeff0_1 = new_coeff0_1;
+        coeff0_2 = new_coeff0_2;
+    
+        if(combinations[deriv_num][j] == 0)
+        {
+          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
+          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
+          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
+        }
+        if(combinations[deriv_num][j] == 1)
+        {
+          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
+          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
+          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
+        }
+    
+      }
+      // Compute derivatives on reference element as dot product of coefficients and basisvalues
+      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
+    }
+    
+    // Transform derivatives back to physical element
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      for (unsigned int col = 0; col < num_derivatives; col++)
+      {
+        values[row] += transform[row][col]*derivatives[col];
+      }
+    }
+    // Delete pointer to array of derivatives on FIAT element
+    delete [] derivatives;
+    
+    // Delete pointer to array of combinations of derivatives and transform
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      delete [] combinations[row];
+      delete [] transform[row];
+    }
+    
+    delete [] combinations;
+    delete [] transform;
+}
+
+/// Evaluate order n derivatives of all basis functions at given point in cell
+void magmaequations_0_finite_element_6::evaluate_basis_derivatives_all(unsigned int n,
+                                                   double* values,
+                                                   const double* coordinates,
+                                                   const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
+}
+
+/// Evaluate linear functional for dof i on the function f
+double magmaequations_0_finite_element_6::evaluate_dof(unsigned int i,
+                                   const ufc::function& f,
+                                   const ufc::cell& c) const
+{
+    // The reference points, direction and weights:
+    static const double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
+    static const double W[3][1] = {{1}, {1}, {1}};
+    static const double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
+    
+    const double * const * x = c.coordinates;
+    double result = 0.0;
+    // Iterate over the points:
+    // Evaluate basis functions for affine mapping
+    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    
+    // Compute affine mapping y = F(X)
+    double y[2];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
+    
+    // Evaluate function at physical points
+    double values[1];
+    f.evaluate(values, y, c);
+    
+    // Map function values using appropriate mapping
+    // Affine map: Do nothing
+    
+    // Note that we do not map the weights (yet).
+    
+    // Take directional components
+    for(int k = 0; k < 1; k++)
+      result += values[k]*D[i][0][k];
+    // Multiply by weights
+    result *= W[i][0];
+    
+    return result;
+}
+
+/// Evaluate linear functionals for all dofs on the function f
+void magmaequations_0_finite_element_6::evaluate_dofs(double* values,
+                                  const ufc::function& f,
+                                  const ufc::cell& c) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Interpolate vertex values from dof values
+void magmaequations_0_finite_element_6::interpolate_vertex_values(double* vertex_values,
+                                              const double* dof_values,
+                                              const ufc::cell& c) const
+{
+    // Evaluate at vertices and use affine mapping
+    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)
+unsigned int magmaequations_0_finite_element_6::num_sub_elements() const
+{
+    return 1;
+}
+
+/// Create a new finite element for sub element i (for a mixed element)
+ufc::finite_element* magmaequations_0_finite_element_6::create_sub_element(unsigned int i) const
+{
+    return new magmaequations_0_finite_element_6();
+}
+
+
+/// Constructor
+magmaequations_0_finite_element_7::magmaequations_0_finite_element_7() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+magmaequations_0_finite_element_7::~magmaequations_0_finite_element_7()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* magmaequations_0_finite_element_7::signature() const
+{
+    return "FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 0)";
+}
+
+/// Return the cell shape
+ufc::shape magmaequations_0_finite_element_7::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int magmaequations_0_finite_element_7::space_dimension() const
+{
+    return 1;
+}
+
+/// Return the rank of the value space
+unsigned int magmaequations_0_finite_element_7::value_rank() const
+{
+    return 0;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int magmaequations_0_finite_element_7::value_dimension(unsigned int i) const
+{
+    return 1;
+}
+
+/// Evaluate basis function i at given point in cell
+void magmaequations_0_finite_element_7::evaluate_basis(unsigned int i,
+                                   double* values,
+                                   const double* coordinates,
+                                   const ufc::cell& c) const
+{
+    // Extract vertex coordinates
+    const double * const * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Reset values
+    *values = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[1][1] = \
+    {{1.41421356237309}};
+    
+    // Extract relevant coefficients
+    const double coeff0_0 = coefficients0[dof][0];
+    
+    // Compute value(s)
+    *values = coeff0_0*basisvalue0;
+}
+
+/// Evaluate all basis functions at given point in cell
+void magmaequations_0_finite_element_7::evaluate_basis_all(double* values,
+                                       const double* coordinates,
+                                       const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
+}
+
+/// Evaluate order n derivatives of basis function i at given point in cell
+void magmaequations_0_finite_element_7::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 * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 2;
+    
+    
+    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
+    unsigned int **combinations = new unsigned int *[num_derivatives];
+    
+    for (unsigned int j = 0; j < num_derivatives; j++)
+    {
+      combinations[j] = new unsigned int [n];
+      for (unsigned int k = 0; k < n; k++)
+        combinations[j][k] = 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] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
+    
+    // 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
+    for (unsigned int j = 0; j < 1*num_derivatives; j++)
+      values[j] = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[1][1] = \
+    {{1.41421356237309}};
+    
+    // Interesting (new) part
+    // Tables of derivatives of the polynomial base (transpose)
+    static const double dmats0[1][1] = \
+    {{0}};
+    
+    static const double dmats1[1][1] = \
+    {{0}};
+    
+    // Compute reference derivatives
+    // Declare pointer to array of derivatives on FIAT element
+    double *derivatives = new double [num_derivatives];
+    
+    // Declare coefficients
+    double coeff0_0 = 0;
+    
+    // Declare new coefficients
+    double new_coeff0_0 = 0;
+    
+    // Loop possible derivatives
+    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+    {
+      // Get values from coefficients array
+      new_coeff0_0 = coefficients0[dof][0];
+    
+      // Loop derivative order
+      for (unsigned int j = 0; j < n; j++)
+      {
+        // Update old coefficients
+        coeff0_0 = new_coeff0_0;
+    
+        if(combinations[deriv_num][j] == 0)
+        {
+          new_coeff0_0 = coeff0_0*dmats0[0][0];
+        }
+        if(combinations[deriv_num][j] == 1)
+        {
+          new_coeff0_0 = coeff0_0*dmats1[0][0];
+        }
+    
+      }
+      // Compute derivatives on reference element as dot product of coefficients and basisvalues
+      derivatives[deriv_num] = new_coeff0_0*basisvalue0;
+    }
+    
+    // Transform derivatives back to physical element
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      for (unsigned int col = 0; col < num_derivatives; col++)
+      {
+        values[row] += transform[row][col]*derivatives[col];
+      }
+    }
+    // Delete pointer to array of derivatives on FIAT element
+    delete [] derivatives;
+    
+    // Delete pointer to array of combinations of derivatives and transform
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      delete [] combinations[row];
+      delete [] transform[row];
+    }
+    
+    delete [] combinations;
+    delete [] transform;
+}
+
+/// Evaluate order n derivatives of all basis functions at given point in cell
+void magmaequations_0_finite_element_7::evaluate_basis_derivatives_all(unsigned int n,
+                                                   double* values,
+                                                   const double* coordinates,
+                                                   const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
+}
+
+/// Evaluate linear functional for dof i on the function f
+double magmaequations_0_finite_element_7::evaluate_dof(unsigned int i,
+                                   const ufc::function& f,
+                                   const ufc::cell& c) const
+{
+    // The reference points, direction and weights:
+    static const double X[1][1][2] = {{{0.333333333333333, 0.333333333333333}}};
+    static const double W[1][1] = {{1}};
+    static const double D[1][1][1] = {{{1}}};
+    
+    const double * const * x = c.coordinates;
+    double result = 0.0;
+    // Iterate over the points:
+    // Evaluate basis functions for affine mapping
+    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    
+    // Compute affine mapping y = F(X)
+    double y[2];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
+    
+    // Evaluate function at physical points
+    double values[1];
+    f.evaluate(values, y, c);
+    
+    // Map function values using appropriate mapping
+    // Affine map: Do nothing
+    
+    // Note that we do not map the weights (yet).
+    
+    // Take directional components
+    for(int k = 0; k < 1; k++)
+      result += values[k]*D[i][0][k];
+    // Multiply by weights
+    result *= W[i][0];
+    
+    return result;
+}
+
+/// Evaluate linear functionals for all dofs on the function f
+void magmaequations_0_finite_element_7::evaluate_dofs(double* values,
+                                  const ufc::function& f,
+                                  const ufc::cell& c) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Interpolate vertex values from dof values
+void magmaequations_0_finite_element_7::interpolate_vertex_values(double* vertex_values,
+                                              const double* dof_values,
+                                              const ufc::cell& c) const
+{
+    // Evaluate at vertices and use affine mapping
+    vertex_values[0] = dof_values[0];
+    vertex_values[1] = dof_values[0];
+    vertex_values[2] = dof_values[0];
+}
+
+/// Return the number of sub elements (for a mixed element)
+unsigned int magmaequations_0_finite_element_7::num_sub_elements() const
+{
+    return 1;
+}
+
+/// Create a new finite element for sub element i (for a mixed element)
+ufc::finite_element* magmaequations_0_finite_element_7::create_sub_element(unsigned int i) const
+{
+    return new magmaequations_0_finite_element_7();
+}
+
+/// Constructor
+magmaequations_0_dof_map_0_0::magmaequations_0_dof_map_0_0() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+magmaequations_0_dof_map_0_0::~magmaequations_0_dof_map_0_0()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* magmaequations_0_dof_map_0_0::signature() const
+{
+    return "FFC dof map for FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool magmaequations_0_dof_map_0_0::needs_mesh_entities(unsigned int d) const
+{
+    switch ( d )
+    {
+    case 0:
+      return true;
+      break;
+    case 1:
+      return true;
+      break;
+    case 2:
+      return false;
+      break;
+    }
+    return false;
+}
+
+/// Initialize dof map for mesh (return true iff init_cell() is needed)
+bool magmaequations_0_dof_map_0_0::init_mesh(const ufc::mesh& m)
+{
+    __global_dimension = m.num_entities[0] + m.num_entities[1];
+    return false;
+}
+
+/// Initialize dof map for given cell
+void magmaequations_0_dof_map_0_0::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void magmaequations_0_dof_map_0_0::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int magmaequations_0_dof_map_0_0::global_dimension() const
+{
+    return __global_dimension;
+}
+
+/// Return the dimension of the local finite element function space for a cell
+unsigned int magmaequations_0_dof_map_0_0::local_dimension(const ufc::cell& c) const
+{
+    return 6;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int magmaequations_0_dof_map_0_0::max_local_dimension() const
+{
+    return 6;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int magmaequations_0_dof_map_0_0::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int magmaequations_0_dof_map_0_0::num_facet_dofs() const
+{
+    return 3;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int magmaequations_0_dof_map_0_0::num_entity_dofs(unsigned int d) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the local-to-global mapping of dofs on a cell
+void magmaequations_0_dof_map_0_0::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];
+    unsigned int offset = m.num_entities[0];
+    dofs[3] = offset + c.entity_indices[1][0];
+    dofs[4] = offset + c.entity_indices[1][1];
+    dofs[5] = offset + c.entity_indices[1][2];
+}
+
+/// Tabulate the local-to-local mapping from facet dofs to cell dofs
+void magmaequations_0_dof_map_0_0::tabulate_facet_dofs(unsigned int* dofs,
+                                        unsigned int facet) const
+{
+    switch ( facet )
+    {
+    case 0:
+      dofs[0] = 1;
+      dofs[1] = 2;
+      dofs[2] = 3;
+      break;
+    case 1:
+      dofs[0] = 0;
+      dofs[1] = 2;
+      dofs[2] = 4;
+      break;
+    case 2:
+      dofs[0] = 0;
+      dofs[1] = 1;
+      dofs[2] = 5;
+      break;
+    }
+}
+
+/// Tabulate the local-to-local mapping of dofs on entity (d, i)
+void magmaequations_0_dof_map_0_0::tabulate_entity_dofs(unsigned int* dofs,
+                                  unsigned int d, unsigned int i) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the coordinates of all dofs on a cell
+void magmaequations_0_dof_map_0_0::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];
+    coordinates[3][0] = 0.5*x[1][0] + 0.5*x[2][0];
+    coordinates[3][1] = 0.5*x[1][1] + 0.5*x[2][1];
+    coordinates[4][0] = 0.5*x[0][0] + 0.5*x[2][0];
+    coordinates[4][1] = 0.5*x[0][1] + 0.5*x[2][1];
+    coordinates[5][0] = 0.5*x[0][0] + 0.5*x[1][0];
+    coordinates[5][1] = 0.5*x[0][1] + 0.5*x[1][1];
+}
+
+/// Return the number of sub dof maps (for a mixed element)
+unsigned int magmaequations_0_dof_map_0_0::num_sub_dof_maps() const
+{
+    return 1;
+}
+
+/// Create a new dof_map for sub dof map i (for a mixed element)
+ufc::dof_map* magmaequations_0_dof_map_0_0::create_sub_dof_map(unsigned int i) const
+{
+    return new magmaequations_0_dof_map_0_0();
+}
+
+
+/// Constructor
+magmaequations_0_dof_map_0_1::magmaequations_0_dof_map_0_1() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+magmaequations_0_dof_map_0_1::~magmaequations_0_dof_map_0_1()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* magmaequations_0_dof_map_0_1::signature() const
+{
+    return "FFC dof map for FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool magmaequations_0_dof_map_0_1::needs_mesh_entities(unsigned int d) const
+{
+    switch ( d )
+    {
+    case 0:
+      return true;
+      break;
+    case 1:
+      return true;
+      break;
+    case 2:
+      return false;
+      break;
+    }
+    return false;
+}
+
+/// Initialize dof map for mesh (return true iff init_cell() is needed)
+bool magmaequations_0_dof_map_0_1::init_mesh(const ufc::mesh& m)
+{
+    __global_dimension = m.num_entities[0] + m.num_entities[1];
+    return false;
+}
+
+/// Initialize dof map for given cell
+void magmaequations_0_dof_map_0_1::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void magmaequations_0_dof_map_0_1::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int magmaequations_0_dof_map_0_1::global_dimension() const
+{
+    return __global_dimension;
+}
+
+/// Return the dimension of the local finite element function space for a cell
+unsigned int magmaequations_0_dof_map_0_1::local_dimension(const ufc::cell& c) const
+{
+    return 6;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int magmaequations_0_dof_map_0_1::max_local_dimension() const
+{
+    return 6;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int magmaequations_0_dof_map_0_1::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int magmaequations_0_dof_map_0_1::num_facet_dofs() const
+{
+    return 3;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int magmaequations_0_dof_map_0_1::num_entity_dofs(unsigned int d) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the local-to-global mapping of dofs on a cell
+void magmaequations_0_dof_map_0_1::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];
+    unsigned int offset = m.num_entities[0];
+    dofs[3] = offset + c.entity_indices[1][0];
+    dofs[4] = offset + c.entity_indices[1][1];
+    dofs[5] = offset + c.entity_indices[1][2];
+}
+
+/// Tabulate the local-to-local mapping from facet dofs to cell dofs
+void magmaequations_0_dof_map_0_1::tabulate_facet_dofs(unsigned int* dofs,
+                                        unsigned int facet) const
+{
+    switch ( facet )
+    {
+    case 0:
+      dofs[0] = 1;
+      dofs[1] = 2;
+      dofs[2] = 3;
+      break;
+    case 1:
+      dofs[0] = 0;
+      dofs[1] = 2;
+      dofs[2] = 4;
+      break;
+    case 2:
+      dofs[0] = 0;
+      dofs[1] = 1;
+      dofs[2] = 5;
+      break;
+    }
+}
+
+/// Tabulate the local-to-local mapping of dofs on entity (d, i)
+void magmaequations_0_dof_map_0_1::tabulate_entity_dofs(unsigned int* dofs,
+                                  unsigned int d, unsigned int i) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the coordinates of all dofs on a cell
+void magmaequations_0_dof_map_0_1::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];
+    coordinates[3][0] = 0.5*x[1][0] + 0.5*x[2][0];
+    coordinates[3][1] = 0.5*x[1][1] + 0.5*x[2][1];
+    coordinates[4][0] = 0.5*x[0][0] + 0.5*x[2][0];
+    coordinates[4][1] = 0.5*x[0][1] + 0.5*x[2][1];
+    coordinates[5][0] = 0.5*x[0][0] + 0.5*x[1][0];
+    coordinates[5][1] = 0.5*x[0][1] + 0.5*x[1][1];
+}
+
+/// Return the number of sub dof maps (for a mixed element)
+unsigned int magmaequations_0_dof_map_0_1::num_sub_dof_maps() const
+{
+    return 1;
+}
+
+/// Create a new dof_map for sub dof map i (for a mixed element)
+ufc::dof_map* magmaequations_0_dof_map_0_1::create_sub_dof_map(unsigned int i) const
+{
+    return new magmaequations_0_dof_map_0_1();
+}
+
+
+/// Constructor
+magmaequations_0_dof_map_0::magmaequations_0_dof_map_0() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+magmaequations_0_dof_map_0::~magmaequations_0_dof_map_0()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* magmaequations_0_dof_map_0::signature() const
+{
+    return "FFC dof map for MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)], **{'value_shape': (2,) })";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool magmaequations_0_dof_map_0::needs_mesh_entities(unsigned int d) const
+{
+    switch ( d )
+    {
+    case 0:
+      return true;
+      break;
+    case 1:
+      return true;
+      break;
+    case 2:
+      return false;
+      break;
+    }
+    return false;
+}
+
+/// Initialize dof map for mesh (return true iff init_cell() is needed)
+bool magmaequations_0_dof_map_0::init_mesh(const ufc::mesh& m)
+{
+    __global_dimension = 2*m.num_entities[0] + 2*m.num_entities[1];
+    return false;
+}
+
+/// Initialize dof map for given cell
+void magmaequations_0_dof_map_0::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void magmaequations_0_dof_map_0::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int magmaequations_0_dof_map_0::global_dimension() const
+{
+    return __global_dimension;
+}
+
+/// Return the dimension of the local finite element function space for a cell
+unsigned int magmaequations_0_dof_map_0::local_dimension(const ufc::cell& c) const
+{
+    return 12;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int magmaequations_0_dof_map_0::max_local_dimension() const
+{
+    return 12;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int magmaequations_0_dof_map_0::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int magmaequations_0_dof_map_0::num_facet_dofs() const
+{
+    return 6;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int magmaequations_0_dof_map_0::num_entity_dofs(unsigned int d) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the local-to-global mapping of dofs on a cell
+void magmaequations_0_dof_map_0::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];
+    unsigned int offset = m.num_entities[0];
+    dofs[3] = offset + c.entity_indices[1][0];
+    dofs[4] = offset + c.entity_indices[1][1];
+    dofs[5] = offset + c.entity_indices[1][2];
+    offset = offset + m.num_entities[1];
+    dofs[6] = offset + c.entity_indices[0][0];
+    dofs[7] = offset + c.entity_indices[0][1];
+    dofs[8] = offset + c.entity_indices[0][2];
+    offset = offset + m.num_entities[0];
+    dofs[9] = offset + c.entity_indices[1][0];
+    dofs[10] = offset + c.entity_indices[1][1];
+    dofs[11] = offset + c.entity_indices[1][2];
+}
+
+/// Tabulate the local-to-local mapping from facet dofs to cell dofs
+void magmaequations_0_dof_map_0::tabulate_facet_dofs(unsigned int* dofs,
+                                        unsigned int facet) const
+{
+    switch ( facet )
+    {
+    case 0:
+      dofs[0] = 1;
+      dofs[1] = 2;
+      dofs[2] = 3;
+      dofs[3] = 7;
+      dofs[4] = 8;
+      dofs[5] = 9;
+      break;
+    case 1:
+      dofs[0] = 0;
+      dofs[1] = 2;
+      dofs[2] = 4;
+      dofs[3] = 6;
+      dofs[4] = 8;
+      dofs[5] = 10;
+      break;
+    case 2:
+      dofs[0] = 0;
+      dofs[1] = 1;
+      dofs[2] = 5;
+      dofs[3] = 6;
+      dofs[4] = 7;
+      dofs[5] = 11;
+      break;
+    }
+}
+
+/// Tabulate the local-to-local mapping of dofs on entity (d, i)
+void magmaequations_0_dof_map_0::tabulate_entity_dofs(unsigned int* dofs,
+                                  unsigned int d, unsigned int i) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the coordinates of all dofs on a cell
+void magmaequations_0_dof_map_0::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];
+    coordinates[3][0] = 0.5*x[1][0] + 0.5*x[2][0];
+    coordinates[3][1] = 0.5*x[1][1] + 0.5*x[2][1];
+    coordinates[4][0] = 0.5*x[0][0] + 0.5*x[2][0];
+    coordinates[4][1] = 0.5*x[0][1] + 0.5*x[2][1];
+    coordinates[5][0] = 0.5*x[0][0] + 0.5*x[1][0];
+    coordinates[5][1] = 0.5*x[0][1] + 0.5*x[1][1];
+    coordinates[6][0] = x[0][0];
+    coordinates[6][1] = x[0][1];
+    coordinates[7][0] = x[1][0];
+    coordinates[7][1] = x[1][1];
+    coordinates[8][0] = x[2][0];
+    coordinates[8][1] = x[2][1];
+    coordinates[9][0] = 0.5*x[1][0] + 0.5*x[2][0];
+    coordinates[9][1] = 0.5*x[1][1] + 0.5*x[2][1];
+    coordinates[10][0] = 0.5*x[0][0] + 0.5*x[2][0];
+    coordinates[10][1] = 0.5*x[0][1] + 0.5*x[2][1];
+    coordinates[11][0] = 0.5*x[0][0] + 0.5*x[1][0];
+    coordinates[11][1] = 0.5*x[0][1] + 0.5*x[1][1];
+}
+
+/// Return the number of sub dof maps (for a mixed element)
+unsigned int magmaequations_0_dof_map_0::num_sub_dof_maps() const
+{
+    return 2;
+}
+
+/// Create a new dof_map for sub dof map i (for a mixed element)
+ufc::dof_map* magmaequations_0_dof_map_0::create_sub_dof_map(unsigned int i) const
+{
+    switch ( i )
+    {
+    case 0:
+      return new magmaequations_0_dof_map_0_0();
+      break;
+    case 1:
+      return new magmaequations_0_dof_map_0_1();
+      break;
+    }
+    return 0;
+}
+
+
+/// Constructor
+magmaequations_0_dof_map_1_0::magmaequations_0_dof_map_1_0() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+magmaequations_0_dof_map_1_0::~magmaequations_0_dof_map_1_0()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* magmaequations_0_dof_map_1_0::signature() const
+{
+    return "FFC dof map for FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool magmaequations_0_dof_map_1_0::needs_mesh_entities(unsigned int d) const
+{
+    switch ( d )
+    {
+    case 0:
+      return true;
+      break;
+    case 1:
+      return true;
+      break;
+    case 2:
+      return false;
+      break;
+    }
+    return false;
+}
+
+/// Initialize dof map for mesh (return true iff init_cell() is needed)
+bool magmaequations_0_dof_map_1_0::init_mesh(const ufc::mesh& m)
+{
+    __global_dimension = m.num_entities[0] + m.num_entities[1];
+    return false;
+}
+
+/// Initialize dof map for given cell
+void magmaequations_0_dof_map_1_0::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void magmaequations_0_dof_map_1_0::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int magmaequations_0_dof_map_1_0::global_dimension() const
+{
+    return __global_dimension;
+}
+
+/// Return the dimension of the local finite element function space for a cell
+unsigned int magmaequations_0_dof_map_1_0::local_dimension(const ufc::cell& c) const
+{
+    return 6;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int magmaequations_0_dof_map_1_0::max_local_dimension() const
+{
+    return 6;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int magmaequations_0_dof_map_1_0::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int magmaequations_0_dof_map_1_0::num_facet_dofs() const
+{
+    return 3;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int magmaequations_0_dof_map_1_0::num_entity_dofs(unsigned int d) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the local-to-global mapping of dofs on a cell
+void magmaequations_0_dof_map_1_0::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];
+    unsigned int offset = m.num_entities[0];
+    dofs[3] = offset + c.entity_indices[1][0];
+    dofs[4] = offset + c.entity_indices[1][1];
+    dofs[5] = offset + c.entity_indices[1][2];
+}
+
+/// Tabulate the local-to-local mapping from facet dofs to cell dofs
+void magmaequations_0_dof_map_1_0::tabulate_facet_dofs(unsigned int* dofs,
+                                        unsigned int facet) const
+{
+    switch ( facet )
+    {
+    case 0:
+      dofs[0] = 1;
+      dofs[1] = 2;
+      dofs[2] = 3;
+      break;
+    case 1:
+      dofs[0] = 0;
+      dofs[1] = 2;
+      dofs[2] = 4;
+      break;
+    case 2:
+      dofs[0] = 0;
+      dofs[1] = 1;
+      dofs[2] = 5;
+      break;
+    }
+}
+
+/// Tabulate the local-to-local mapping of dofs on entity (d, i)
+void magmaequations_0_dof_map_1_0::tabulate_entity_dofs(unsigned int* dofs,
+                                  unsigned int d, unsigned int i) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the coordinates of all dofs on a cell
+void magmaequations_0_dof_map_1_0::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];
+    coordinates[3][0] = 0.5*x[1][0] + 0.5*x[2][0];
+    coordinates[3][1] = 0.5*x[1][1] + 0.5*x[2][1];
+    coordinates[4][0] = 0.5*x[0][0] + 0.5*x[2][0];
+    coordinates[4][1] = 0.5*x[0][1] + 0.5*x[2][1];
+    coordinates[5][0] = 0.5*x[0][0] + 0.5*x[1][0];
+    coordinates[5][1] = 0.5*x[0][1] + 0.5*x[1][1];
+}
+
+/// Return the number of sub dof maps (for a mixed element)
+unsigned int magmaequations_0_dof_map_1_0::num_sub_dof_maps() const
+{
+    return 1;
+}
+
+/// Create a new dof_map for sub dof map i (for a mixed element)
+ufc::dof_map* magmaequations_0_dof_map_1_0::create_sub_dof_map(unsigned int i) const
+{
+    return new magmaequations_0_dof_map_1_0();
+}
+
+
+/// Constructor
+magmaequations_0_dof_map_1_1::magmaequations_0_dof_map_1_1() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+magmaequations_0_dof_map_1_1::~magmaequations_0_dof_map_1_1()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* magmaequations_0_dof_map_1_1::signature() const
+{
+    return "FFC dof map for FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool magmaequations_0_dof_map_1_1::needs_mesh_entities(unsigned int d) const
+{
+    switch ( d )
+    {
+    case 0:
+      return true;
+      break;
+    case 1:
+      return true;
+      break;
+    case 2:
+      return false;
+      break;
+    }
+    return false;
+}
+
+/// Initialize dof map for mesh (return true iff init_cell() is needed)
+bool magmaequations_0_dof_map_1_1::init_mesh(const ufc::mesh& m)
+{
+    __global_dimension = m.num_entities[0] + m.num_entities[1];
+    return false;
+}
+
+/// Initialize dof map for given cell
+void magmaequations_0_dof_map_1_1::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void magmaequations_0_dof_map_1_1::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int magmaequations_0_dof_map_1_1::global_dimension() const
+{
+    return __global_dimension;
+}
+
+/// Return the dimension of the local finite element function space for a cell
+unsigned int magmaequations_0_dof_map_1_1::local_dimension(const ufc::cell& c) const
+{
+    return 6;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int magmaequations_0_dof_map_1_1::max_local_dimension() const
+{
+    return 6;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int magmaequations_0_dof_map_1_1::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int magmaequations_0_dof_map_1_1::num_facet_dofs() const
+{
+    return 3;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int magmaequations_0_dof_map_1_1::num_entity_dofs(unsigned int d) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the local-to-global mapping of dofs on a cell
+void magmaequations_0_dof_map_1_1::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];
+    unsigned int offset = m.num_entities[0];
+    dofs[3] = offset + c.entity_indices[1][0];
+    dofs[4] = offset + c.entity_indices[1][1];
+    dofs[5] = offset + c.entity_indices[1][2];
+}
+
+/// Tabulate the local-to-local mapping from facet dofs to cell dofs
+void magmaequations_0_dof_map_1_1::tabulate_facet_dofs(unsigned int* dofs,
+                                        unsigned int facet) const
+{
+    switch ( facet )
+    {
+    case 0:
+      dofs[0] = 1;
+      dofs[1] = 2;
+      dofs[2] = 3;
+      break;
+    case 1:
+      dofs[0] = 0;
+      dofs[1] = 2;
+      dofs[2] = 4;
+      break;
+    case 2:
+      dofs[0] = 0;
+      dofs[1] = 1;
+      dofs[2] = 5;
+      break;
+    }
+}
+
+/// Tabulate the local-to-local mapping of dofs on entity (d, i)
+void magmaequations_0_dof_map_1_1::tabulate_entity_dofs(unsigned int* dofs,
+                                  unsigned int d, unsigned int i) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the coordinates of all dofs on a cell
+void magmaequations_0_dof_map_1_1::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];
+    coordinates[3][0] = 0.5*x[1][0] + 0.5*x[2][0];
+    coordinates[3][1] = 0.5*x[1][1] + 0.5*x[2][1];
+    coordinates[4][0] = 0.5*x[0][0] + 0.5*x[2][0];
+    coordinates[4][1] = 0.5*x[0][1] + 0.5*x[2][1];
+    coordinates[5][0] = 0.5*x[0][0] + 0.5*x[1][0];
+    coordinates[5][1] = 0.5*x[0][1] + 0.5*x[1][1];
+}
+
+/// Return the number of sub dof maps (for a mixed element)
+unsigned int magmaequations_0_dof_map_1_1::num_sub_dof_maps() const
+{
+    return 1;
+}
+
+/// Create a new dof_map for sub dof map i (for a mixed element)
+ufc::dof_map* magmaequations_0_dof_map_1_1::create_sub_dof_map(unsigned int i) const
+{
+    return new magmaequations_0_dof_map_1_1();
+}
+
+
+/// Constructor
+magmaequations_0_dof_map_1::magmaequations_0_dof_map_1() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+magmaequations_0_dof_map_1::~magmaequations_0_dof_map_1()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* magmaequations_0_dof_map_1::signature() const
+{
+    return "FFC dof map for MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)], **{'value_shape': (2,) })";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool magmaequations_0_dof_map_1::needs_mesh_entities(unsigned int d) const
+{
+    switch ( d )
+    {
+    case 0:
+      return true;
+      break;
+    case 1:
+      return true;
+      break;
+    case 2:
+      return false;
+      break;
+    }
+    return false;
+}
+
+/// Initialize dof map for mesh (return true iff init_cell() is needed)
+bool magmaequations_0_dof_map_1::init_mesh(const ufc::mesh& m)
+{
+    __global_dimension = 2*m.num_entities[0] + 2*m.num_entities[1];
+    return false;
+}
+
+/// Initialize dof map for given cell
+void magmaequations_0_dof_map_1::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void magmaequations_0_dof_map_1::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int magmaequations_0_dof_map_1::global_dimension() const
+{
+    return __global_dimension;
+}
+
+/// Return the dimension of the local finite element function space for a cell
+unsigned int magmaequations_0_dof_map_1::local_dimension(const ufc::cell& c) const
+{
+    return 12;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int magmaequations_0_dof_map_1::max_local_dimension() const
+{
+    return 12;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int magmaequations_0_dof_map_1::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int magmaequations_0_dof_map_1::num_facet_dofs() const
+{
+    return 6;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int magmaequations_0_dof_map_1::num_entity_dofs(unsigned int d) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the local-to-global mapping of dofs on a cell
+void magmaequations_0_dof_map_1::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];
+    unsigned int offset = m.num_entities[0];
+    dofs[3] = offset + c.entity_indices[1][0];
+    dofs[4] = offset + c.entity_indices[1][1];
+    dofs[5] = offset + c.entity_indices[1][2];
+    offset = offset + m.num_entities[1];
+    dofs[6] = offset + c.entity_indices[0][0];
+    dofs[7] = offset + c.entity_indices[0][1];
+    dofs[8] = offset + c.entity_indices[0][2];
+    offset = offset + m.num_entities[0];
+    dofs[9] = offset + c.entity_indices[1][0];
+    dofs[10] = offset + c.entity_indices[1][1];
+    dofs[11] = offset + c.entity_indices[1][2];
+}
+
+/// Tabulate the local-to-local mapping from facet dofs to cell dofs
+void magmaequations_0_dof_map_1::tabulate_facet_dofs(unsigned int* dofs,
+                                        unsigned int facet) const
+{
+    switch ( facet )
+    {
+    case 0:
+      dofs[0] = 1;
+      dofs[1] = 2;
+      dofs[2] = 3;
+      dofs[3] = 7;
+      dofs[4] = 8;
+      dofs[5] = 9;
+      break;
+    case 1:
+      dofs[0] = 0;
+      dofs[1] = 2;
+      dofs[2] = 4;
+      dofs[3] = 6;
+      dofs[4] = 8;
+      dofs[5] = 10;
+      break;
+    case 2:
+      dofs[0] = 0;
+      dofs[1] = 1;
+      dofs[2] = 5;
+      dofs[3] = 6;
+      dofs[4] = 7;
+      dofs[5] = 11;
+      break;
+    }
+}
+
+/// Tabulate the local-to-local mapping of dofs on entity (d, i)
+void magmaequations_0_dof_map_1::tabulate_entity_dofs(unsigned int* dofs,
+                                  unsigned int d, unsigned int i) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the coordinates of all dofs on a cell
+void magmaequations_0_dof_map_1::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];
+    coordinates[3][0] = 0.5*x[1][0] + 0.5*x[2][0];
+    coordinates[3][1] = 0.5*x[1][1] + 0.5*x[2][1];
+    coordinates[4][0] = 0.5*x[0][0] + 0.5*x[2][0];
+    coordinates[4][1] = 0.5*x[0][1] + 0.5*x[2][1];
+    coordinates[5][0] = 0.5*x[0][0] + 0.5*x[1][0];
+    coordinates[5][1] = 0.5*x[0][1] + 0.5*x[1][1];
+    coordinates[6][0] = x[0][0];
+    coordinates[6][1] = x[0][1];
+    coordinates[7][0] = x[1][0];
+    coordinates[7][1] = x[1][1];
+    coordinates[8][0] = x[2][0];
+    coordinates[8][1] = x[2][1];
+    coordinates[9][0] = 0.5*x[1][0] + 0.5*x[2][0];
+    coordinates[9][1] = 0.5*x[1][1] + 0.5*x[2][1];
+    coordinates[10][0] = 0.5*x[0][0] + 0.5*x[2][0];
+    coordinates[10][1] = 0.5*x[0][1] + 0.5*x[2][1];
+    coordinates[11][0] = 0.5*x[0][0] + 0.5*x[1][0];
+    coordinates[11][1] = 0.5*x[0][1] + 0.5*x[1][1];
+}
+
+/// Return the number of sub dof maps (for a mixed element)
+unsigned int magmaequations_0_dof_map_1::num_sub_dof_maps() const
+{
+    return 2;
+}
+
+/// Create a new dof_map for sub dof map i (for a mixed element)
+ufc::dof_map* magmaequations_0_dof_map_1::create_sub_dof_map(unsigned int i) const
+{
+    switch ( i )
+    {
+    case 0:
+      return new magmaequations_0_dof_map_1_0();
+      break;
+    case 1:
+      return new magmaequations_0_dof_map_1_1();
+      break;
+    }
+    return 0;
+}
+
+
+/// Constructor
+magmaequations_0_dof_map_2_0::magmaequations_0_dof_map_2_0() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+magmaequations_0_dof_map_2_0::~magmaequations_0_dof_map_2_0()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* magmaequations_0_dof_map_2_0::signature() const
+{
+    return "FFC dof map for FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool magmaequations_0_dof_map_2_0::needs_mesh_entities(unsigned int d) const
+{
+    switch ( d )
+    {
+    case 0:
+      return true;
+      break;
+    case 1:
+      return true;
+      break;
+    case 2:
+      return false;
+      break;
+    }
+    return false;
+}
+
+/// Initialize dof map for mesh (return true iff init_cell() is needed)
+bool magmaequations_0_dof_map_2_0::init_mesh(const ufc::mesh& m)
+{
+    __global_dimension = m.num_entities[0] + m.num_entities[1];
+    return false;
+}
+
+/// Initialize dof map for given cell
+void magmaequations_0_dof_map_2_0::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void magmaequations_0_dof_map_2_0::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int magmaequations_0_dof_map_2_0::global_dimension() const
+{
+    return __global_dimension;
+}
+
+/// Return the dimension of the local finite element function space for a cell
+unsigned int magmaequations_0_dof_map_2_0::local_dimension(const ufc::cell& c) const
+{
+    return 6;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int magmaequations_0_dof_map_2_0::max_local_dimension() const
+{
+    return 6;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int magmaequations_0_dof_map_2_0::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int magmaequations_0_dof_map_2_0::num_facet_dofs() const
+{
+    return 3;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int magmaequations_0_dof_map_2_0::num_entity_dofs(unsigned int d) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the local-to-global mapping of dofs on a cell
+void magmaequations_0_dof_map_2_0::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];
+    unsigned int offset = m.num_entities[0];
+    dofs[3] = offset + c.entity_indices[1][0];
+    dofs[4] = offset + c.entity_indices[1][1];
+    dofs[5] = offset + c.entity_indices[1][2];
+}
+
+/// Tabulate the local-to-local mapping from facet dofs to cell dofs
+void magmaequations_0_dof_map_2_0::tabulate_facet_dofs(unsigned int* dofs,
+                                        unsigned int facet) const
+{
+    switch ( facet )
+    {
+    case 0:
+      dofs[0] = 1;
+      dofs[1] = 2;
+      dofs[2] = 3;
+      break;
+    case 1:
+      dofs[0] = 0;
+      dofs[1] = 2;
+      dofs[2] = 4;
+      break;
+    case 2:
+      dofs[0] = 0;
+      dofs[1] = 1;
+      dofs[2] = 5;
+      break;
+    }
+}
+
+/// Tabulate the local-to-local mapping of dofs on entity (d, i)
+void magmaequations_0_dof_map_2_0::tabulate_entity_dofs(unsigned int* dofs,
+                                  unsigned int d, unsigned int i) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the coordinates of all dofs on a cell
+void magmaequations_0_dof_map_2_0::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];
+    coordinates[3][0] = 0.5*x[1][0] + 0.5*x[2][0];
+    coordinates[3][1] = 0.5*x[1][1] + 0.5*x[2][1];
+    coordinates[4][0] = 0.5*x[0][0] + 0.5*x[2][0];
+    coordinates[4][1] = 0.5*x[0][1] + 0.5*x[2][1];
+    coordinates[5][0] = 0.5*x[0][0] + 0.5*x[1][0];
+    coordinates[5][1] = 0.5*x[0][1] + 0.5*x[1][1];
+}
+
+/// Return the number of sub dof maps (for a mixed element)
+unsigned int magmaequations_0_dof_map_2_0::num_sub_dof_maps() const
+{
+    return 1;
+}
+
+/// Create a new dof_map for sub dof map i (for a mixed element)
+ufc::dof_map* magmaequations_0_dof_map_2_0::create_sub_dof_map(unsigned int i) const
+{
+    return new magmaequations_0_dof_map_2_0();
+}
+
+
+/// Constructor
+magmaequations_0_dof_map_2_1::magmaequations_0_dof_map_2_1() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+magmaequations_0_dof_map_2_1::~magmaequations_0_dof_map_2_1()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* magmaequations_0_dof_map_2_1::signature() const
+{
+    return "FFC dof map for FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool magmaequations_0_dof_map_2_1::needs_mesh_entities(unsigned int d) const
+{
+    switch ( d )
+    {
+    case 0:
+      return true;
+      break;
+    case 1:
+      return true;
+      break;
+    case 2:
+      return false;
+      break;
+    }
+    return false;
+}
+
+/// Initialize dof map for mesh (return true iff init_cell() is needed)
+bool magmaequations_0_dof_map_2_1::init_mesh(const ufc::mesh& m)
+{
+    __global_dimension = m.num_entities[0] + m.num_entities[1];
+    return false;
+}
+
+/// Initialize dof map for given cell
+void magmaequations_0_dof_map_2_1::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void magmaequations_0_dof_map_2_1::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int magmaequations_0_dof_map_2_1::global_dimension() const
+{
+    return __global_dimension;
+}
+
+/// Return the dimension of the local finite element function space for a cell
+unsigned int magmaequations_0_dof_map_2_1::local_dimension(const ufc::cell& c) const
+{
+    return 6;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int magmaequations_0_dof_map_2_1::max_local_dimension() const
+{
+    return 6;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int magmaequations_0_dof_map_2_1::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int magmaequations_0_dof_map_2_1::num_facet_dofs() const
+{
+    return 3;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int magmaequations_0_dof_map_2_1::num_entity_dofs(unsigned int d) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the local-to-global mapping of dofs on a cell
+void magmaequations_0_dof_map_2_1::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];
+    unsigned int offset = m.num_entities[0];
+    dofs[3] = offset + c.entity_indices[1][0];
+    dofs[4] = offset + c.entity_indices[1][1];
+    dofs[5] = offset + c.entity_indices[1][2];
+}
+
+/// Tabulate the local-to-local mapping from facet dofs to cell dofs
+void magmaequations_0_dof_map_2_1::tabulate_facet_dofs(unsigned int* dofs,
+                                        unsigned int facet) const
+{
+    switch ( facet )
+    {
+    case 0:
+      dofs[0] = 1;
+      dofs[1] = 2;
+      dofs[2] = 3;
+      break;
+    case 1:
+      dofs[0] = 0;
+      dofs[1] = 2;
+      dofs[2] = 4;
+      break;
+    case 2:
+      dofs[0] = 0;
+      dofs[1] = 1;
+      dofs[2] = 5;
+      break;
+    }
+}
+
+/// Tabulate the local-to-local mapping of dofs on entity (d, i)
+void magmaequations_0_dof_map_2_1::tabulate_entity_dofs(unsigned int* dofs,
+                                  unsigned int d, unsigned int i) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the coordinates of all dofs on a cell
+void magmaequations_0_dof_map_2_1::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];
+    coordinates[3][0] = 0.5*x[1][0] + 0.5*x[2][0];
+    coordinates[3][1] = 0.5*x[1][1] + 0.5*x[2][1];
+    coordinates[4][0] = 0.5*x[0][0] + 0.5*x[2][0];
+    coordinates[4][1] = 0.5*x[0][1] + 0.5*x[2][1];
+    coordinates[5][0] = 0.5*x[0][0] + 0.5*x[1][0];
+    coordinates[5][1] = 0.5*x[0][1] + 0.5*x[1][1];
+}
+
+/// Return the number of sub dof maps (for a mixed element)
+unsigned int magmaequations_0_dof_map_2_1::num_sub_dof_maps() const
+{
+    return 1;
+}
+
+/// Create a new dof_map for sub dof map i (for a mixed element)
+ufc::dof_map* magmaequations_0_dof_map_2_1::create_sub_dof_map(unsigned int i) const
+{
+    return new magmaequations_0_dof_map_2_1();
+}
+
+
+/// Constructor
+magmaequations_0_dof_map_2::magmaequations_0_dof_map_2() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+magmaequations_0_dof_map_2::~magmaequations_0_dof_map_2()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* magmaequations_0_dof_map_2::signature() const
+{
+    return "FFC dof map for MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)], **{'value_shape': (2,) })";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool magmaequations_0_dof_map_2::needs_mesh_entities(unsigned int d) const
+{
+    switch ( d )
+    {
+    case 0:
+      return true;
+      break;
+    case 1:
+      return true;
+      break;
+    case 2:
+      return false;
+      break;
+    }
+    return false;
+}
+
+/// Initialize dof map for mesh (return true iff init_cell() is needed)
+bool magmaequations_0_dof_map_2::init_mesh(const ufc::mesh& m)
+{
+    __global_dimension = 2*m.num_entities[0] + 2*m.num_entities[1];
+    return false;
+}
+
+/// Initialize dof map for given cell
+void magmaequations_0_dof_map_2::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void magmaequations_0_dof_map_2::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int magmaequations_0_dof_map_2::global_dimension() const
+{
+    return __global_dimension;
+}
+
+/// Return the dimension of the local finite element function space for a cell
+unsigned int magmaequations_0_dof_map_2::local_dimension(const ufc::cell& c) const
+{
+    return 12;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int magmaequations_0_dof_map_2::max_local_dimension() const
+{
+    return 12;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int magmaequations_0_dof_map_2::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int magmaequations_0_dof_map_2::num_facet_dofs() const
+{
+    return 6;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int magmaequations_0_dof_map_2::num_entity_dofs(unsigned int d) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the local-to-global mapping of dofs on a cell
+void magmaequations_0_dof_map_2::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];
+    unsigned int offset = m.num_entities[0];
+    dofs[3] = offset + c.entity_indices[1][0];
+    dofs[4] = offset + c.entity_indices[1][1];
+    dofs[5] = offset + c.entity_indices[1][2];
+    offset = offset + m.num_entities[1];
+    dofs[6] = offset + c.entity_indices[0][0];
+    dofs[7] = offset + c.entity_indices[0][1];
+    dofs[8] = offset + c.entity_indices[0][2];
+    offset = offset + m.num_entities[0];
+    dofs[9] = offset + c.entity_indices[1][0];
+    dofs[10] = offset + c.entity_indices[1][1];
+    dofs[11] = offset + c.entity_indices[1][2];
+}
+
+/// Tabulate the local-to-local mapping from facet dofs to cell dofs
+void magmaequations_0_dof_map_2::tabulate_facet_dofs(unsigned int* dofs,
+                                        unsigned int facet) const
+{
+    switch ( facet )
+    {
+    case 0:
+      dofs[0] = 1;
+      dofs[1] = 2;
+      dofs[2] = 3;
+      dofs[3] = 7;
+      dofs[4] = 8;
+      dofs[5] = 9;
+      break;
+    case 1:
+      dofs[0] = 0;
+      dofs[1] = 2;
+      dofs[2] = 4;
+      dofs[3] = 6;
+      dofs[4] = 8;
+      dofs[5] = 10;
+      break;
+    case 2:
+      dofs[0] = 0;
+      dofs[1] = 1;
+      dofs[2] = 5;
+      dofs[3] = 6;
+      dofs[4] = 7;
+      dofs[5] = 11;
+      break;
+    }
+}
+
+/// Tabulate the local-to-local mapping of dofs on entity (d, i)
+void magmaequations_0_dof_map_2::tabulate_entity_dofs(unsigned int* dofs,
+                                  unsigned int d, unsigned int i) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the coordinates of all dofs on a cell
+void magmaequations_0_dof_map_2::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];
+    coordinates[3][0] = 0.5*x[1][0] + 0.5*x[2][0];
+    coordinates[3][1] = 0.5*x[1][1] + 0.5*x[2][1];
+    coordinates[4][0] = 0.5*x[0][0] + 0.5*x[2][0];
+    coordinates[4][1] = 0.5*x[0][1] + 0.5*x[2][1];
+    coordinates[5][0] = 0.5*x[0][0] + 0.5*x[1][0];
+    coordinates[5][1] = 0.5*x[0][1] + 0.5*x[1][1];
+    coordinates[6][0] = x[0][0];
+    coordinates[6][1] = x[0][1];
+    coordinates[7][0] = x[1][0];
+    coordinates[7][1] = x[1][1];
+    coordinates[8][0] = x[2][0];
+    coordinates[8][1] = x[2][1];
+    coordinates[9][0] = 0.5*x[1][0] + 0.5*x[2][0];
+    coordinates[9][1] = 0.5*x[1][1] + 0.5*x[2][1];
+    coordinates[10][0] = 0.5*x[0][0] + 0.5*x[2][0];
+    coordinates[10][1] = 0.5*x[0][1] + 0.5*x[2][1];
+    coordinates[11][0] = 0.5*x[0][0] + 0.5*x[1][0];
+    coordinates[11][1] = 0.5*x[0][1] + 0.5*x[1][1];
+}
+
+/// Return the number of sub dof maps (for a mixed element)
+unsigned int magmaequations_0_dof_map_2::num_sub_dof_maps() const
+{
+    return 2;
+}
+
+/// Create a new dof_map for sub dof map i (for a mixed element)
+ufc::dof_map* magmaequations_0_dof_map_2::create_sub_dof_map(unsigned int i) const
+{
+    switch ( i )
+    {
+    case 0:
+      return new magmaequations_0_dof_map_2_0();
+      break;
+    case 1:
+      return new magmaequations_0_dof_map_2_1();
+      break;
+    }
+    return 0;
+}
+
+
+/// Constructor
+magmaequations_0_dof_map_3::magmaequations_0_dof_map_3() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+magmaequations_0_dof_map_3::~magmaequations_0_dof_map_3()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* magmaequations_0_dof_map_3::signature() const
+{
+    return "FFC dof map for FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 0)";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool magmaequations_0_dof_map_3::needs_mesh_entities(unsigned int d) const
+{
+    switch ( d )
+    {
+    case 0:
+      return false;
+      break;
+    case 1:
+      return false;
+      break;
+    case 2:
+      return true;
+      break;
+    }
+    return false;
+}
+
+/// Initialize dof map for mesh (return true iff init_cell() is needed)
+bool magmaequations_0_dof_map_3::init_mesh(const ufc::mesh& m)
+{
+    __global_dimension = m.num_entities[2];
+    return false;
+}
+
+/// Initialize dof map for given cell
+void magmaequations_0_dof_map_3::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void magmaequations_0_dof_map_3::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int magmaequations_0_dof_map_3::global_dimension() const
+{
+    return __global_dimension;
+}
+
+/// Return the dimension of the local finite element function space for a cell
+unsigned int magmaequations_0_dof_map_3::local_dimension(const ufc::cell& c) const
+{
+    return 1;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int magmaequations_0_dof_map_3::max_local_dimension() const
+{
+    return 1;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int magmaequations_0_dof_map_3::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int magmaequations_0_dof_map_3::num_facet_dofs() const
+{
+    return 0;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int magmaequations_0_dof_map_3::num_entity_dofs(unsigned int d) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the local-to-global mapping of dofs on a cell
+void magmaequations_0_dof_map_3::tabulate_dofs(unsigned int* dofs,
+                                  const ufc::mesh& m,
+                                  const ufc::cell& c) const
+{
+    dofs[0] = c.entity_indices[2][0];
+}
+
+/// Tabulate the local-to-local mapping from facet dofs to cell dofs
+void magmaequations_0_dof_map_3::tabulate_facet_dofs(unsigned int* dofs,
+                                        unsigned int facet) const
+{
+    switch ( facet )
+    {
+    case 0:
+      
+      break;
+    case 1:
+      
+      break;
+    case 2:
+      
+      break;
+    }
+}
+
+/// Tabulate the local-to-local mapping of dofs on entity (d, i)
+void magmaequations_0_dof_map_3::tabulate_entity_dofs(unsigned int* dofs,
+                                  unsigned int d, unsigned int i) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the coordinates of all dofs on a cell
+void magmaequations_0_dof_map_3::tabulate_coordinates(double** coordinates,
+                                         const ufc::cell& c) const
+{
+    const double * const * x = c.coordinates;
+    coordinates[0][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0];
+    coordinates[0][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1];
+}
+
+/// Return the number of sub dof maps (for a mixed element)
+unsigned int magmaequations_0_dof_map_3::num_sub_dof_maps() const
+{
+    return 1;
+}
+
+/// Create a new dof_map for sub dof map i (for a mixed element)
+ufc::dof_map* magmaequations_0_dof_map_3::create_sub_dof_map(unsigned int i) const
+{
+    return new magmaequations_0_dof_map_3();
+}
+
+
+/// Constructor
+magmaequations_0_dof_map_4::magmaequations_0_dof_map_4() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+magmaequations_0_dof_map_4::~magmaequations_0_dof_map_4()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* magmaequations_0_dof_map_4::signature() const
+{
+    return "FFC dof map for FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 0)";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool magmaequations_0_dof_map_4::needs_mesh_entities(unsigned int d) const
+{
+    switch ( d )
+    {
+    case 0:
+      return false;
+      break;
+    case 1:
+      return false;
+      break;
+    case 2:
+      return true;
+      break;
+    }
+    return false;
+}
+
+/// Initialize dof map for mesh (return true iff init_cell() is needed)
+bool magmaequations_0_dof_map_4::init_mesh(const ufc::mesh& m)
+{
+    __global_dimension = m.num_entities[2];
+    return false;
+}
+
+/// Initialize dof map for given cell
+void magmaequations_0_dof_map_4::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void magmaequations_0_dof_map_4::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int magmaequations_0_dof_map_4::global_dimension() const
+{
+    return __global_dimension;
+}
+
+/// Return the dimension of the local finite element function space for a cell
+unsigned int magmaequations_0_dof_map_4::local_dimension(const ufc::cell& c) const
+{
+    return 1;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int magmaequations_0_dof_map_4::max_local_dimension() const
+{
+    return 1;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int magmaequations_0_dof_map_4::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int magmaequations_0_dof_map_4::num_facet_dofs() const
+{
+    return 0;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int magmaequations_0_dof_map_4::num_entity_dofs(unsigned int d) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the local-to-global mapping of dofs on a cell
+void magmaequations_0_dof_map_4::tabulate_dofs(unsigned int* dofs,
+                                  const ufc::mesh& m,
+                                  const ufc::cell& c) const
+{
+    dofs[0] = c.entity_indices[2][0];
+}
+
+/// Tabulate the local-to-local mapping from facet dofs to cell dofs
+void magmaequations_0_dof_map_4::tabulate_facet_dofs(unsigned int* dofs,
+                                        unsigned int facet) const
+{
+    switch ( facet )
+    {
+    case 0:
+      
+      break;
+    case 1:
+      
+      break;
+    case 2:
+      
+      break;
+    }
+}
+
+/// Tabulate the local-to-local mapping of dofs on entity (d, i)
+void magmaequations_0_dof_map_4::tabulate_entity_dofs(unsigned int* dofs,
+                                  unsigned int d, unsigned int i) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the coordinates of all dofs on a cell
+void magmaequations_0_dof_map_4::tabulate_coordinates(double** coordinates,
+                                         const ufc::cell& c) const
+{
+    const double * const * x = c.coordinates;
+    coordinates[0][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0];
+    coordinates[0][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1];
+}
+
+/// Return the number of sub dof maps (for a mixed element)
+unsigned int magmaequations_0_dof_map_4::num_sub_dof_maps() const
+{
+    return 1;
+}
+
+/// Create a new dof_map for sub dof map i (for a mixed element)
+ufc::dof_map* magmaequations_0_dof_map_4::create_sub_dof_map(unsigned int i) const
+{
+    return new magmaequations_0_dof_map_4();
+}
+
+
+/// Constructor
+magmaequations_0_dof_map_5::magmaequations_0_dof_map_5() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+magmaequations_0_dof_map_5::~magmaequations_0_dof_map_5()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* magmaequations_0_dof_map_5::signature() const
+{
+    return "FFC dof map for FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool magmaequations_0_dof_map_5::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)
+bool magmaequations_0_dof_map_5::init_mesh(const ufc::mesh& m)
+{
+    __global_dimension = m.num_entities[0];
+    return false;
+}
+
+/// Initialize dof map for given cell
+void magmaequations_0_dof_map_5::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void magmaequations_0_dof_map_5::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int magmaequations_0_dof_map_5::global_dimension() const
+{
+    return __global_dimension;
+}
+
+/// Return the dimension of the local finite element function space for a cell
+unsigned int magmaequations_0_dof_map_5::local_dimension(const ufc::cell& c) const
+{
+    return 3;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int magmaequations_0_dof_map_5::max_local_dimension() const
+{
+    return 3;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int magmaequations_0_dof_map_5::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int magmaequations_0_dof_map_5::num_facet_dofs() const
+{
+    return 2;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int magmaequations_0_dof_map_5::num_entity_dofs(unsigned int d) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the local-to-global mapping of dofs on a cell
+void magmaequations_0_dof_map_5::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
+void magmaequations_0_dof_map_5::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)
+void magmaequations_0_dof_map_5::tabulate_entity_dofs(unsigned int* dofs,
+                                  unsigned int d, unsigned int i) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the coordinates of all dofs on a cell
+void magmaequations_0_dof_map_5::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)
+unsigned int magmaequations_0_dof_map_5::num_sub_dof_maps() const
+{
+    return 1;
+}
+
+/// Create a new dof_map for sub dof map i (for a mixed element)
+ufc::dof_map* magmaequations_0_dof_map_5::create_sub_dof_map(unsigned int i) const
+{
+    return new magmaequations_0_dof_map_5();
+}
+
+
+/// Constructor
+magmaequations_0_dof_map_6::magmaequations_0_dof_map_6() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+magmaequations_0_dof_map_6::~magmaequations_0_dof_map_6()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* magmaequations_0_dof_map_6::signature() const
+{
+    return "FFC dof map for FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool magmaequations_0_dof_map_6::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)
+bool magmaequations_0_dof_map_6::init_mesh(const ufc::mesh& m)
+{
+    __global_dimension = m.num_entities[0];
+    return false;
+}
+
+/// Initialize dof map for given cell
+void magmaequations_0_dof_map_6::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void magmaequations_0_dof_map_6::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int magmaequations_0_dof_map_6::global_dimension() const
+{
+    return __global_dimension;
+}
+
+/// Return the dimension of the local finite element function space for a cell
+unsigned int magmaequations_0_dof_map_6::local_dimension(const ufc::cell& c) const
+{
+    return 3;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int magmaequations_0_dof_map_6::max_local_dimension() const
+{
+    return 3;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int magmaequations_0_dof_map_6::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int magmaequations_0_dof_map_6::num_facet_dofs() const
+{
+    return 2;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int magmaequations_0_dof_map_6::num_entity_dofs(unsigned int d) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the local-to-global mapping of dofs on a cell
+void magmaequations_0_dof_map_6::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
+void magmaequations_0_dof_map_6::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)
+void magmaequations_0_dof_map_6::tabulate_entity_dofs(unsigned int* dofs,
+                                  unsigned int d, unsigned int i) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the coordinates of all dofs on a cell
+void magmaequations_0_dof_map_6::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)
+unsigned int magmaequations_0_dof_map_6::num_sub_dof_maps() const
+{
+    return 1;
+}
+
+/// Create a new dof_map for sub dof map i (for a mixed element)
+ufc::dof_map* magmaequations_0_dof_map_6::create_sub_dof_map(unsigned int i) const
+{
+    return new magmaequations_0_dof_map_6();
+}
+
+
+/// Constructor
+magmaequations_0_dof_map_7::magmaequations_0_dof_map_7() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+magmaequations_0_dof_map_7::~magmaequations_0_dof_map_7()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* magmaequations_0_dof_map_7::signature() const
+{
+    return "FFC dof map for FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 0)";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool magmaequations_0_dof_map_7::needs_mesh_entities(unsigned int d) const
+{
+    switch ( d )
+    {
+    case 0:
+      return false;
+      break;
+    case 1:
+      return false;
+      break;
+    case 2:
+      return true;
+      break;
+    }
+    return false;
+}
+
+/// Initialize dof map for mesh (return true iff init_cell() is needed)
+bool magmaequations_0_dof_map_7::init_mesh(const ufc::mesh& m)
+{
+    __global_dimension = m.num_entities[2];
+    return false;
+}
+
+/// Initialize dof map for given cell
+void magmaequations_0_dof_map_7::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void magmaequations_0_dof_map_7::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int magmaequations_0_dof_map_7::global_dimension() const
+{
+    return __global_dimension;
+}
+
+/// Return the dimension of the local finite element function space for a cell
+unsigned int magmaequations_0_dof_map_7::local_dimension(const ufc::cell& c) const
+{
+    return 1;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int magmaequations_0_dof_map_7::max_local_dimension() const
+{
+    return 1;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int magmaequations_0_dof_map_7::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int magmaequations_0_dof_map_7::num_facet_dofs() const
+{
+    return 0;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int magmaequations_0_dof_map_7::num_entity_dofs(unsigned int d) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the local-to-global mapping of dofs on a cell
+void magmaequations_0_dof_map_7::tabulate_dofs(unsigned int* dofs,
+                                  const ufc::mesh& m,
+                                  const ufc::cell& c) const
+{
+    dofs[0] = c.entity_indices[2][0];
+}
+
+/// Tabulate the local-to-local mapping from facet dofs to cell dofs
+void magmaequations_0_dof_map_7::tabulate_facet_dofs(unsigned int* dofs,
+                                        unsigned int facet) const
+{
+    switch ( facet )
+    {
+    case 0:
+      
+      break;
+    case 1:
+      
+      break;
+    case 2:
+      
+      break;
+    }
+}
+
+/// Tabulate the local-to-local mapping of dofs on entity (d, i)
+void magmaequations_0_dof_map_7::tabulate_entity_dofs(unsigned int* dofs,
+                                  unsigned int d, unsigned int i) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the coordinates of all dofs on a cell
+void magmaequations_0_dof_map_7::tabulate_coordinates(double** coordinates,
+                                         const ufc::cell& c) const
+{
+    const double * const * x = c.coordinates;
+    coordinates[0][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0];
+    coordinates[0][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1];
+}
+
+/// Return the number of sub dof maps (for a mixed element)
+unsigned int magmaequations_0_dof_map_7::num_sub_dof_maps() const
+{
+    return 1;
+}
+
+/// Create a new dof_map for sub dof map i (for a mixed element)
+ufc::dof_map* magmaequations_0_dof_map_7::create_sub_dof_map(unsigned int i) const
+{
+    return new magmaequations_0_dof_map_7();
+}
+
+
+/// Constructor
+magmaequations_0_cell_integral_0_quadrature::magmaequations_0_cell_integral_0_quadrature() : ufc::cell_integral()
+{
+    // Do nothing
+}
+
+/// Destructor
+magmaequations_0_cell_integral_0_quadrature::~magmaequations_0_cell_integral_0_quadrature()
+{
+    // Do nothing
+}
+
+/// Tabulate the tensor for the contribution from a local cell
+void magmaequations_0_cell_integral_0_quadrature::tabulate_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 Jinv_00 =  J_11 / detJ;
+    const double Jinv_01 = -J_01 / detJ;
+    const double Jinv_10 = -J_10 / detJ;
+    const double Jinv_11 =  J_00 / detJ;
+    
+    // Set scale factor
+    const double det = std::abs(detJ);
+    
+    
+    // Array of quadrature weights
+    static const double W16[16] = {0.0235683681933823, 0.0353880678980859, 0.0225840492823699, 0.00542322591052525, 0.0441850885223617, 0.0663442161070497, 0.0423397245217463, 0.0101672595644788, 0.0441850885223617, 0.0663442161070497, 0.0423397245217463, 0.0101672595644788, 0.0235683681933823, 0.0353880678980859, 0.0225840492823699, 0.00542322591052525};
+    // Quadrature points on the UFC reference element: (0.0654669945550145, 0.0571041961145177), (0.0502101232113698, 0.276843013638124), (0.028912084224389, 0.583590432368917), (0.00970378512694614, 0.860240135656219), (0.311164552244357, 0.0571041961145177), (0.238648659731443, 0.276843013638124), (0.137419104134574, 0.583590432368917), (0.0461220799064521, 0.860240135656219), (0.631731251641125, 0.0571041961145177), (0.484508326630433, 0.276843013638124), (0.278990463496509, 0.583590432368917), (0.0936377844373285, 0.860240135656219), (0.877428809330468, 0.0571041961145177), (0.672946863150506, 0.276843013638124), (0.387497483406694, 0.583590432368917), (0.130056079216834, 0.860240135656219)
+    
+    // Value of basis functions at quadrature points.
+    static const double FE0[16][3] = \
+    {{0.877428809330468, 0.0654669945550145, 0.0571041961145176},
+    {0.672946863150506, 0.0502101232113698, 0.276843013638124},
+    {0.387497483406694, 0.028912084224389, 0.583590432368917},
+    {0.130056079216834, 0.0097037851269462, 0.860240135656219},
+    {0.631731251641125, 0.311164552244357, 0.0571041961145176},
+    {0.484508326630433, 0.238648659731443, 0.276843013638124},
+    {0.278990463496509, 0.137419104134574, 0.583590432368917},
+    {0.0936377844373285, 0.0461220799064521, 0.860240135656219},
+    {0.311164552244357, 0.631731251641125, 0.0571041961145176},
+    {0.238648659731443, 0.484508326630433, 0.276843013638124},
+    {0.137419104134574, 0.278990463496509, 0.583590432368917},
+    {0.0461220799064521, 0.0936377844373286, 0.860240135656219},
+    {0.0654669945550145, 0.877428809330468, 0.0571041961145176},
+    {0.05021012321137, 0.672946863150506, 0.276843013638124},
+    {0.028912084224389, 0.387497483406694, 0.583590432368917},
+    {0.00970378512694609, 0.130056079216835, 0.860240135656219}};
+    
+    static const double FE0_D01[16][2] = \
+    {{-1, 1},
+    {-1, 1},
+    {-1, 1},
+    {-1, 1},
+    {-1, 1},
+    {-1, 1},
+    {-1, 1},
+    {-1, 1},
+    {-1, 1},
+    {-1, 1},
+    {-1, 1},
+    {-1, 1},
+    {-1, 1},
+    {-1, 1},
+    {-1, 1},
+    {-1, 1}};
+    
+    // Array of non-zero columns
+    static const unsigned int nzc1[2] = {0, 1};
+    // Array of non-zero columns
+    static const unsigned int nzc0[2] = {0, 2};
+    static const double FE2_C0[16][6] = \
+    {{0.662333821555697, -0.0568951398028818, -0.0505824176867471, 0.0149537603843903, 0.200419467218139, 0.229770508331402},
+    {0.232768098097707, -0.0451680102655679, -0.123558905237647, 0.0556012872999084, 0.745202550451633, 0.135154979653967},
+    {-0.0871888841136516, -0.0272402669959927, 0.0975651531361618, 0.0674912629327909, 0.904559295532719, 0.0448134395079726},
+    {-0.0962269117343233, -0.00951545823536616, 0.619786046331442, 0.0333903417359317, 0.447517836913622, 0.00504814498869312},
+    {0.166437496959, -0.117517795097495, -0.0505824176867471, 0.0710752064609913, 0.144298021141538, 0.786289488222712},
+    {-0.0150116894819879, -0.124742294148215, -0.123558905237647, 0.264272856643007, 0.536530981108534, 0.462509051116308},
+    {-0.123319106052515, -0.0996510837722763, 0.0975651531361618, 0.320785897590582, 0.651264660874928, 0.15335447822312},
+    {-0.0761017150886652, -0.0418675873966577, 0.619786046331442, 0.158704257101893, 0.322203921547661, 0.0172750775043265},
+    {-0.117517795097494, 0.166437496959, -0.0505824176867471, 0.144298021141538, 0.0710752064609913, 0.786289488222712},
+    {-0.124742294148215, -0.015011689481988, -0.123558905237647, 0.536530981108534, 0.264272856643007, 0.462509051116308},
+    {-0.0996510837722762, -0.123319106052515, 0.0975651531361618, 0.651264660874928, 0.320785897590582, 0.15335447822312},
+    {-0.0418675873966576, -0.0761017150886652, 0.619786046331442, 0.322203921547661, 0.158704257101893, 0.0172750775043265},
+    {-0.0568951398028817, 0.662333821555697, -0.0505824176867471, 0.200419467218139, 0.0149537603843903, 0.229770508331402},
+    {-0.0451680102655678, 0.232768098097706, -0.123558905237647, 0.745202550451633, 0.0556012872999086, 0.135154979653967},
+    {-0.0272402669959925, -0.0871888841136517, 0.0975651531361618, 0.904559295532719, 0.0674912629327908, 0.0448134395079726},
+    {-0.00951545823536599, -0.0962269117343234, 0.619786046331442, 0.447517836913623, 0.0333903417359313, 0.00504814498869309}};
+    
+    // Array of non-zero columns
+    static const unsigned int nzc2[6] = {0, 1, 2, 3, 4, 5};
+    // Array of non-zero columns
+    static const unsigned int nzc5[6] = {6, 7, 8, 9, 10, 11};
+    static const double FE2_C0_D01[16][5] = \
+    {{-2.50971523732187, -0.77158321554193, 0.261867978220058, 3.2812984528638, -0.261867978220058},
+    {-1.69178745260203, 0.107372054552496, 0.200840492845479, 1.58441539804953, -0.200840492845479},
+    {-0.549989933626777, 1.33436172947567, 0.115648336897556, -0.784371795848891, -0.115648336897556},
+    {0.479775683132663, 2.44096054262488, 0.0388151405077859, -2.92073622575754, -0.0388151405077846},
+    {-1.5269250065645, -0.77158321554193, 1.24465820897743, 2.29850822210643, -1.24465820897743},
+    {-0.938033306521733, 0.107372054552495, 0.954594638925771, 0.830661251969238, -0.954594638925771},
+    {-0.115961853986035, 1.33436172947567, 0.549676416538298, -1.21839987548963, -0.549676416538297},
+    {0.625448862250687, 2.44096054262488, 0.184488319625809, -3.06640940487556, -0.184488319625808},
+    {-0.244658208977428, -0.77158321554193, 2.5269250065645, 1.01624142451936, -2.5269250065645},
+    {0.0454053610742288, 0.107372054552495, 1.93803330652173, -0.152777415626724, -1.93803330652173},
+    {0.450323583461703, 1.33436172947567, 1.11596185398603, -1.78468531293737, -1.11596185398603},
+    {0.815511680374193, 2.44096054262488, 0.374551137749315, -3.25647222299907, -0.374551137749314},
+    {0.738132021779943, -0.771583215541929, 3.50971523732187, 0.0334511937619876, -3.50971523732187},
+    {0.799159507154521, 0.107372054552495, 2.69178745260202, -0.906531561707015, -2.69178745260203},
+    {0.884351663102445, 1.33436172947567, 1.54998993362678, -2.21871339257811, -1.54998993362678},
+    {0.961184859492217, 2.44096054262488, 0.520224316867339, -3.40214540211709, -0.520224316867338}};
+    
+    // Array of non-zero columns
+    static const unsigned int nzc3[5] = {0, 2, 3, 4, 5};
+    static const double FE2_C0_D10[16][5] = \
+    {{-2.50971523732187, -0.738132021779942, 0.22841678445807, -0.22841678445807, 3.24784725910181},
+    {-1.69178745260203, -0.79915950715452, 1.10737205455249, -1.10737205455249, 2.49094695975655},
+    {-0.549989933626777, -0.884351663102444, 2.33436172947567, -2.33436172947567, 1.43434159672922},
+    {0.479775683132664, -0.961184859492216, 3.44096054262488, -3.44096054262488, 0.481409176359552},
+    {-1.5269250065645, 0.244658208977428, 0.22841678445807, -0.22841678445807, 1.28226679758707},
+    {-0.938033306521733, -0.0454053610742281, 1.10737205455249, -1.10737205455249, 0.983438667595962},
+    {-0.115961853986035, -0.450323583461702, 2.33436172947567, -2.33436172947567, 0.566285437447738},
+    {0.625448862250687, -0.815511680374192, 3.44096054262488, -3.44096054262488, 0.190062818123505},
+    {-0.244658208977428, 1.5269250065645, 0.228416784458071, -0.228416784458071, -1.28226679758707},
+    {0.0454053610742284, 0.938033306521734, 1.10737205455249, -1.10737205455249, -0.983438667595961},
+    {0.450323583461703, 0.115961853986035, 2.33436172947567, -2.33436172947567, -0.566285437447738},
+    {0.815511680374193, -0.625448862250686, 3.44096054262488, -3.44096054262488, -0.190062818123506},
+    {0.738132021779942, 2.50971523732187, 0.228416784458071, -0.228416784458071, -3.24784725910181},
+    {0.79915950715452, 1.69178745260203, 1.10737205455249, -1.10737205455249, -2.49094695975655},
+    {0.884351663102444, 0.549989933626777, 2.33436172947567, -2.33436172947567, -1.43434159672922},
+    {0.961184859492217, -0.479775683132662, 3.44096054262488, -3.44096054262488, -0.481409176359554}};
+    
+    // Array of non-zero columns
+    static const unsigned int nzc4[5] = {0, 1, 3, 4, 5};
+    
+    // Number of operations to compute geometry constants: 77
+    const double G0 = -2*Jinv_11*det;
+    const double G1 = 2*det*(Jinv_00*Jinv_10 + Jinv_01*Jinv_11);
+    const double G2 = 2*det*(Jinv_10*Jinv_10 + Jinv_11*Jinv_11);
+    const double G3 = 2*det*w[5][0]*(Jinv_10*Jinv_10 + Jinv_11*Jinv_11);
+    const double G4 = 2*det*w[5][0]*(Jinv_00*Jinv_10 + Jinv_01*Jinv_11);
+    const double G5 = 2*det*w[5][0]*(Jinv_00*Jinv_00 + Jinv_01*Jinv_01);
+    const double G6 = det*(Jinv_00*Jinv_00 + Jinv_01*Jinv_01);
+    const double G7 = det*w[5][0]*w[5][0]*(Jinv_00*Jinv_00 + Jinv_01*Jinv_01);
+    const double G8 = det*(Jinv_10*Jinv_10 + Jinv_11*Jinv_11);
+    const double G9 = det*w[5][0]*w[5][0]*(Jinv_10*Jinv_10 + Jinv_11*Jinv_11);
+    const double G10 = det*w[2][0];
+    const double G11 = det*w[2][0]*w[5][0];
+    const double G12 = -0.5*det*w[1][0]*w[2][0];
+    const double G13 = -0.5*det*w[1][0]*w[2][0]*w[5][0];
+    const double G14 = det*(Jinv_00*Jinv_10 + Jinv_01*Jinv_11);
+    const double G15 = det*w[5][0]*w[5][0]*(Jinv_00*Jinv_10 + Jinv_01*Jinv_11);
+    const double G16 = -2*Jinv_01*det;
+    const double G17 = 2*det*(Jinv_00*Jinv_00 + Jinv_01*Jinv_01);
+    
+    // Compute element tensor using UFL quadrature representation
+    // Optimisations: ('simplify expressions', True), ('ignore zero tables', True), ('non zero columns', True), ('remove zero terms', True), ('ignore ones', True)
+    // Total number of operations to compute element tensor: 16461
+    
+    // Loop quadrature points for integral
+    // Number of operations to compute element tensor for following IP loop = 16384
+    for (unsigned int ip = 0; ip < 16; ip++)
+    {
+      
+      // Function declarations
+      double F0 = 0;
+      double F1 = 0;
+      double F2 = 0;
+      double F3 = 0;
+      double F4 = 0;
+      double F5 = 0;
+      double F6 = 0;
+      
+      // Total number of operations to compute function values = 8
+      for (unsigned int r = 0; r < 2; r++)
+      {
+        F3 += FE0_D01[ip][r]*w[4][nzc1[r]];
+        F4 += FE0_D01[ip][r]*w[4][nzc0[r]];
+      }// end loop over 'r'
+      
+      // Total number of operations to compute function values = 6
+      for (unsigned int r = 0; r < 3; r++)
+      {
+        F0 += FE0[ip][r]*w[3][r];
+      }// end loop over 'r'
+      
+      // Total number of operations to compute function values = 20
+      for (unsigned int r = 0; r < 5; r++)
+      {
+        F5 += FE2_C0_D10[ip][r]*w[0][nzc4[r]];
+        F6 += FE2_C0_D01[ip][r]*w[0][nzc3[r]];
+      }// end loop over 'r'
+      
+      // Total number of operations to compute function values = 24
+      for (unsigned int r = 0; r < 6; r++)
+      {
+        F1 += FE2_C0[ip][r]*w[0][nzc5[r]];
+        F2 += FE2_C0[ip][r]*w[0][nzc2[r]];
+      }// end loop over 'r'
+      
+      // Number of operations to compute ip constants: 54
+      // Number of operations: 12
+      const double Gip0 = W16[ip]*(F1*(G0 + G1*(F3 + F5) + G2*(F4 + F6)) + F5*G4 + F6*G3);
+      
+      // Number of operations: 5
+      const double Gip1 = W16[ip]*(G7 + F1*(G5 + F1*G6));
+      
+      // Number of operations: 5
+      const double Gip2 = W16[ip]*(G9 + F1*(G3 + F1*G8));
+      
+      // Number of operations: 4
+      const double Gip3 = F0*W16[ip]*(G11 + F1*G10);
+      
+      // Number of operations: 4
+      const double Gip4 = F0*W16[ip]*(G13 + F1*G12);
+      
+      // Number of operations: 4
+      const double Gip5 = W16[ip]*(det + F0*F2*G12);
+      
+      // Number of operations: 5
+      const double Gip6 = W16[ip]*(G15 + F1*(G4 + F1*G14));
+      
+      // Number of operations: 3
+      const double Gip7 = F0*F2*G10*W16[ip];
+      
+      // Number of operations: 12
+      const double Gip8 = W16[ip]*(F1*(G16 + G1*(F4 + F6) + G17*(F3 + F5)) + F5*G5 + F6*G4);
+      
+      
+      // Number of operations for primary indices: 432
+      for (unsigned int j = 0; j < 6; j++)
+      {
+        for (unsigned int k = 0; k < 6; k++)
+        {
+          // Number of operations to compute entry: 3
+          A[nzc2[j]*12 + nzc2[k]] += FE2_C0[ip][j]*FE2_C0[ip][k]*Gip3;
+          // Number of operations to compute entry: 3
+          A[nzc5[j]*12 + nzc2[k]] += FE2_C0[ip][j]*FE2_C0[ip][k]*Gip4;
+          // Number of operations to compute entry: 3
+          A[nzc5[j]*12 + nzc5[k]] += FE2_C0[ip][j]*FE2_C0[ip][k]*Gip5;
+          // Number of operations to compute entry: 3
+          A[nzc2[j]*12 + nzc5[k]] += FE2_C0[ip][j]*FE2_C0[ip][k]*Gip7;
+        }// end loop over 'k'
+      }// end loop over 'j'
+      
+      // Number of operations for primary indices: 180
+      for (unsigned int j = 0; j < 5; j++)
+      {
+        for (unsigned int k = 0; k < 6; k++)
+        {
+          // Number of operations to compute entry: 3
+          A[nzc3[j]*12 + nzc5[k]] += FE2_C0[ip][k]*FE2_C0_D01[ip][j]*Gip0;
+          // Number of operations to compute entry: 3
+          A[nzc4[j]*12 + nzc5[k]] += FE2_C0[ip][k]*FE2_C0_D10[ip][j]*Gip8;
+        }// end loop over 'k'
+      }// end loop over 'j'
+      
+      // Number of operations for primary indices: 300
+      for (unsigned int j = 0; j < 5; j++)
+      {
+        for (unsigned int k = 0; k < 5; k++)
+        {
+          // Number of operations to compute entry: 3
+          A[nzc4[j]*12 + nzc4[k]] += FE2_C0_D10[ip][j]*FE2_C0_D10[ip][k]*Gip1;
+          // Number of operations to compute entry: 3
+          A[nzc3[j]*12 + nzc3[k]] += FE2_C0_D01[ip][j]*FE2_C0_D01[ip][k]*Gip2;
+          // Number of operations to compute entry: 3
+          A[nzc3[j]*12 + nzc4[k]] += FE2_C0_D01[ip][j]*FE2_C0_D10[ip][k]*Gip6;
+          // Number of operations to compute entry: 3
+          A[nzc4[j]*12 + nzc3[k]] += FE2_C0_D01[ip][k]*FE2_C0_D10[ip][j]*Gip6;
+        }// end loop over 'k'
+      }// end loop over 'j'
+    }// end loop over 'ip'
+}
+
+/// Constructor
+magmaequations_0_cell_integral_0::magmaequations_0_cell_integral_0() : ufc::cell_integral()
+{
+    // Do nothing
+}
+
+/// Destructor
+magmaequations_0_cell_integral_0::~magmaequations_0_cell_integral_0()
+{
+    // Do nothing
+}
+
+/// Tabulate the tensor for the contribution from a local cell
+void magmaequations_0_cell_integral_0::tabulate_tensor(double* A,
+                                    const double * const * w,
+                                    const ufc::cell& c) const
+{
+    // Reset values of the element tensor block
+    for (unsigned int j = 0; j < 144; j++)
+      A[j] = 0;
+    
+    // Add all contributions to element tensor
+    integral_0_quadrature.tabulate_tensor(A, w, c);
+}
+
+/// Constructor
+magmaequations_0_exterior_facet_integral_0_quadrature::magmaequations_0_exterior_facet_integral_0_quadrature() : ufc::exterior_facet_integral()
+{
+    // Do nothing
+}
+
+/// Destructor
+magmaequations_0_exterior_facet_integral_0_quadrature::~magmaequations_0_exterior_facet_integral_0_quadrature()
+{
+    // Do nothing
+}
+
+/// Tabulate the tensor for the contribution from a local exterior facet
+void magmaequations_0_exterior_facet_integral_0_quadrature::tabulate_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
+    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 Jinv_00 =  J_11 / detJ;
+    const double Jinv_01 = -J_01 / detJ;
+    const double Jinv_10 = -J_10 / detJ;
+    const double Jinv_11 =  J_00 / detJ;
+    
+    // Vertices on edges
+    static unsigned int edge_vertices[3][2] = {{1, 2}, {0, 2}, {0, 1}};
+    
+    // Get vertices
+    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);
+    
+    const bool direction = dx1*(x[facet][0] - x[v0][0]) - dx0*(x[facet][1] - x[v0][1]) < 0;
+    
+    // Compute facet normals from the facet scale factor constants
+    const double n0 = direction ? dx1 / det : -dx1 / det;
+    const double n1 = direction ? -dx0 / det : dx0 / det;
+    
+    
+    // Array of quadrature weights
+    static const double W4[4] = {0.173927422568727, 0.326072577431273, 0.326072577431273, 0.173927422568727};
+    // Quadrature points on the UFC reference element: (0.0694318442029737), (0.330009478207572), (0.669990521792428), (0.930568155797026)
+    
+    // Value of basis functions at quadrature points.
+    static const double FE0_f0_D01[4][2] = \
+    {{-1, 1},
+    {-1, 1},
+    {-1, 1},
+    {-1, 1}};
+    
+    // Array of non-zero columns
+    static const unsigned int nzc1[2] = {0, 2};
+    // Array of non-zero columns
+    static const unsigned int nzc2[2] = {0, 1};
+    static const double FE1_f0_C0[4][3] = \
+    {{0.801346029369931, -0.0597902822241217, 0.258444252854191},
+    {0.227784076790952, -0.112196966793904, 0.884412890002952},
+    {-0.112196966793904, 0.227784076790952, 0.884412890002952},
+    {-0.0597902822241216, 0.801346029369931, 0.258444252854191}};
+    
+    // Array of non-zero columns
+    static const unsigned int nzc5[3] = {1, 2, 3};
+    // Array of non-zero columns
+    static const unsigned int nzc6[3] = {7, 8, 9};
+    // Array of non-zero columns
+    static const unsigned int nzc9[3] = {0, 1, 5};
+    // Array of non-zero columns
+    static const unsigned int nzc10[3] = {6, 7, 11};
+    // Array of non-zero columns
+    static const unsigned int nzc8[3] = {6, 8, 10};
+    // Array of non-zero columns
+    static const unsigned int nzc7[3] = {0, 2, 4};
+    
+    // Number of operations to compute geometry constants: 12
+    // Should be added to total operation count.
+    const double G0 = -2*det*(Jinv_00*n0 + Jinv_01*n1);
+    const double G1 = 2*det*n1;
+    const double G2 = -2*det*(Jinv_10*n0 + Jinv_11*n1);
+    
+    // Compute element tensor using UFL quadrature representation
+    // Optimisations: ('simplify expressions', True), ('ignore zero tables', True), ('non zero columns', True), ('remove zero terms', True), ('ignore ones', True)
+    switch ( facet )
+    {
+    case 0:
+      {
+      // Total number of operations to compute element tensor (from this point): 188
+      
+      // Loop quadrature points for integral
+      // Number of operations to compute element tensor for following IP loop = 188
+      for (unsigned int ip = 0; ip < 4; ip++)
+      {
+        
+        // Function declarations
+        double F0 = 0;
+        double F1 = 0;
+        double F2 = 0;
+        
+        // Total number of operations to compute function values = 8
+        for (unsigned int r = 0; r < 2; r++)
+        {
+          F1 += FE0_f0_D01[ip][r]*w[4][nzc2[r]];
+          F2 += FE0_f0_D01[ip][r]*w[4][nzc1[r]];
+        }// end loop over 'r'
+        
+        // Total number of operations to compute function values = 6
+        for (unsigned int r = 0; r < 3; r++)
+        {
+          F0 += FE1_f0_C0[ip][r]*w[0][nzc6[r]];
+        }// end loop over 'r'
+        
+        // Number of operations to compute ip constants: 6
+        // Number of operations: 6
+        const double Gip0 = F0*W4[ip]*(G1 + F1*G0 + F2*G2);
+        
+        
+        // Number of operations for primary indices: 27
+        for (unsigned int j = 0; j < 3; j++)
+        {
+          for (unsigned int k = 0; k < 3; k++)
+          {
+            // Number of operations to compute entry: 3
+            A[nzc5[j]*12 + nzc6[k]] += FE1_f0_C0[ip][j]*FE1_f0_C0[ip][k]*Gip0;
+          }// end loop over 'k'
+        }// end loop over 'j'
+      }// end loop over 'ip'
+      }
+      break;
+    case 1:
+      {
+      // Total number of operations to compute element tensor (from this point): 188
+      
+      // Loop quadrature points for integral
+      // Number of operations to compute element tensor for following IP loop = 188
+      for (unsigned int ip = 0; ip < 4; ip++)
+      {
+        
+        // Function declarations
+        double F0 = 0;
+        double F1 = 0;
+        double F2 = 0;
+        
+        // Total number of operations to compute function values = 8
+        for (unsigned int r = 0; r < 2; r++)
+        {
+          F1 += FE0_f0_D01[ip][r]*w[4][nzc2[r]];
+          F2 += FE0_f0_D01[ip][r]*w[4][nzc1[r]];
+        }// end loop over 'r'
+        
+        // Total number of operations to compute function values = 6
+        for (unsigned int r = 0; r < 3; r++)
+        {
+          F0 += FE1_f0_C0[ip][r]*w[0][nzc8[r]];
+        }// end loop over 'r'
+        
+        // Number of operations to compute ip constants: 6
+        // Number of operations: 6
+        const double Gip0 = F0*W4[ip]*(G1 + F1*G0 + F2*G2);
+        
+        
+        // Number of operations for primary indices: 27
+        for (unsigned int j = 0; j < 3; j++)
+        {
+          for (unsigned int k = 0; k < 3; k++)
+          {
+            // Number of operations to compute entry: 3
+            A[nzc7[j]*12 + nzc8[k]] += FE1_f0_C0[ip][j]*FE1_f0_C0[ip][k]*Gip0;
+          }// end loop over 'k'
+        }// end loop over 'j'
+      }// end loop over 'ip'
+      }
+      break;
+    case 2:
+      {
+      // Total number of operations to compute element tensor (from this point): 188
+      
+      // Loop quadrature points for integral
+      // Number of operations to compute element tensor for following IP loop = 188
+      for (unsigned int ip = 0; ip < 4; ip++)
+      {
+        
+        // Function declarations
+        double F0 = 0;
+        double F1 = 0;
+        double F2 = 0;
+        
+        // Total number of operations to compute function values = 8
+        for (unsigned int r = 0; r < 2; r++)
+        {
+          F1 += FE0_f0_D01[ip][r]*w[4][nzc2[r]];
+          F2 += FE0_f0_D01[ip][r]*w[4][nzc1[r]];
+        }// end loop over 'r'
+        
+        // Total number of operations to compute function values = 6
+        for (unsigned int r = 0; r < 3; r++)
+        {
+          F0 += FE1_f0_C0[ip][r]*w[0][nzc10[r]];
+        }// end loop over 'r'
+        
+        // Number of operations to compute ip constants: 6
+        // Number of operations: 6
+        const double Gip0 = F0*W4[ip]*(G1 + F1*G0 + F2*G2);
+        
+        
+        // Number of operations for primary indices: 27
+        for (unsigned int j = 0; j < 3; j++)
+        {
+          for (unsigned int k = 0; k < 3; k++)
+          {
+            // Number of operations to compute entry: 3
+            A[nzc9[j]*12 + nzc10[k]] += FE1_f0_C0[ip][j]*FE1_f0_C0[ip][k]*Gip0;
+          }// end loop over 'k'
+        }// end loop over 'j'
+      }// end loop over 'ip'
+      }
+      break;
+    }
+}
+
+/// Constructor
+magmaequations_0_exterior_facet_integral_0::magmaequations_0_exterior_facet_integral_0() : ufc::exterior_facet_integral()
+{
+    // Do nothing
+}
+
+/// Destructor
+magmaequations_0_exterior_facet_integral_0::~magmaequations_0_exterior_facet_integral_0()
+{
+    // Do nothing
+}
+
+/// Tabulate the tensor for the contribution from a local exterior facet
+void magmaequations_0_exterior_facet_integral_0::tabulate_tensor(double* A,
+                                    const double * const * w,
+                                    const ufc::cell& c,
+                                    unsigned int facet) const
+{
+    // Reset values of the element tensor block
+    for (unsigned int j = 0; j < 144; j++)
+      A[j] = 0;
+    
+    // Add all contributions to element tensor
+    integral_0_quadrature.tabulate_tensor(A, w, c, facet);
+}
+
+/// Constructor
+magmaequations_form_0::magmaequations_form_0() : ufc::form()
+{
+    // Do nothing
+}
+
+/// Destructor
+magmaequations_form_0::~magmaequations_form_0()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the form
+const char* magmaequations_form_0::signature() const
+{
+    return "Form([Integral(Sum(Product(Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})), Sum(Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)], **{'value_shape': (2,) }), 1), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})), Product(IntValue(-1, (), (), {}), Product(Product(FloatValue(0.5, (), (), {}), Constant(Cell('triangle', 1, Space(2)), 1)), Sum(Product(Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)], **{'value_shape': (2,) }), 1), MultiIndex((FixedIndex(0),), {FixedIndex(0): 2})), Product(Product(Constant(Cell('triangle', 1, Space(2)), 2), Function(FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), 3)), Sum(Constant(Cell('triangle', 1, Space(2)), 5), Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2}))))), Product(Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(0),), {FixedIndex(0): 2})), Product(Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)], **{'value_shape': (2,) }), 1), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})), Product(Constant(Cell('triangle', 1, Space(2)), 2), Function(FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), 3))))))))), Sum(Product(IndexSum(Product(Indexed(ComponentTensor(Indexed(SpatialDerivative(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((Index(0),), {Index(0): 2})), MultiIndex((FixedIndex(0),), {})), MultiIndex((Index(0),), {Index(0): 2})), MultiIndex((Index(1),), {Index(1): 2})), Indexed(ComponentTensor(SpatialDerivative(Function(FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), 4), MultiIndex((Index(2),), {Index(2): 2})), MultiIndex((Index(2),), {Index(2): 2})), MultiIndex((Index(1),), {Index(1): 2}))), MultiIndex((Index(1),), {Index(1): 2})), Product(Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})), Product(IntValue(2, (), (), {}), Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)], **{'value_shape': (2,) }), 1), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2}))))), Sum(Product(IntValue(-1, (), (), {}), Product(Indexed(SpatialDerivative(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})), MultiIndex((FixedIndex(0),), {FixedIndex(0): 2})), Product(Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})), Product(IntValue(2, (), (), {}), Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)], **{'value_shape': (2,) }), 1), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})))))), Sum(Sum(Product(IndexSum(Product(Indexed(ComponentTensor(Indexed(SpatialDerivative(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((Index(3),), {Index(3): 2})), MultiIndex((FixedIndex(0),), {})), MultiIndex((Index(3),), {Index(3): 2})), MultiIndex((Index(4),), {Index(4): 2})), Indexed(ComponentTensor(Indexed(SpatialDerivative(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)], **{'value_shape': (2,) }), 1), MultiIndex((Index(5),), {Index(5): 2})), MultiIndex((FixedIndex(0),), {})), MultiIndex((Index(5),), {Index(5): 2})), MultiIndex((Index(4),), {Index(4): 2}))), MultiIndex((Index(4),), {Index(4): 2})), Power(Sum(Constant(Cell('triangle', 1, Space(2)), 5), Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2}))), IntValue(2, (), (), {}))), Product(IndexSum(Product(Indexed(ComponentTensor(Indexed(SpatialDerivative(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((Index(3),), {Index(3): 2})), MultiIndex((FixedIndex(0),), {})), MultiIndex((Index(3),), {Index(3): 2})), MultiIndex((Index(4),), {Index(4): 2})), Indexed(ComponentTensor(Indexed(SpatialDerivative(Function(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((Index(5),), {Index(5): 2})), MultiIndex((FixedIndex(0),), {})), MultiIndex((Index(5),), {Index(5): 2})), MultiIndex((Index(4),), {Index(4): 2}))), MultiIndex((Index(4),), {Index(4): 2})), Product(Product(IntValue(2, (), (), {}), Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)], **{'value_shape': (2,) }), 1), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2}))), Sum(Constant(Cell('triangle', 1, Space(2)), 5), Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})))))), Sum(Product(Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)], **{'value_shape': (2,) }), 1), MultiIndex((FixedIndex(0),), {FixedIndex(0): 2})), Product(Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(0),), {FixedIndex(0): 2})), Product(Product(Constant(Cell('triangle', 1, Space(2)), 2), Function(FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), 3)), Sum(Constant(Cell('triangle', 1, Space(2)), 5), Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})))))), Product(Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(0),), {FixedIndex(0): 2})), Product(Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(0),), {FixedIndex(0): 2})), Product(Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)], **{'value_shape': (2,) }), 1), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})), Product(Constant(Cell('triangle', 1, Space(2)), 2), Function(FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), 3)))))))))), Measure('cell', 0, None)), Integral(Product(Product(Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(0),), {FixedIndex(0): 2})), Product(Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})), Product(IntValue(2, (), (), {}), Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)], **{'value_shape': (2,) }), 1), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2}))))), Sum(Indexed(FacetNormal(Cell('triangle', 1, Space(2))), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})), Product(IntValue(-1, (), (), {}), IndexSum(Product(Indexed(ComponentTensor(SpatialDerivative(Function(FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), 4), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(7),), {Index(7): 2})), Indexed(FacetNormal(Cell('triangle', 1, Space(2))), MultiIndex((Index(7),), {Index(7): 2}))), MultiIndex((Index(7),), {Index(7): 2}))))), Measure('exterior_facet', 0, None))])";
+}
+
+/// Return the rank of the global tensor (r)
+unsigned int magmaequations_form_0::rank() const
+{
+    return 2;
+}
+
+/// Return the number of coefficients (n)
+unsigned int magmaequations_form_0::num_coefficients() const
+{
+    return 6;
+}
+
+/// Return the number of cell integrals
+unsigned int magmaequations_form_0::num_cell_integrals() const
+{
+    return 1;
+}
+
+/// Return the number of exterior facet integrals
+unsigned int magmaequations_form_0::num_exterior_facet_integrals() const
+{
+    return 1;
+}
+
+/// Return the number of interior facet integrals
+unsigned int magmaequations_form_0::num_interior_facet_integrals() const
+{
+    return 0;
+}
+
+/// Create a new finite element for argument function i
+ufc::finite_element* magmaequations_form_0::create_finite_element(unsigned int i) const
+{
+    switch ( i )
+    {
+    case 0:
+      return new magmaequations_0_finite_element_0();
+      break;
+    case 1:
+      return new magmaequations_0_finite_element_1();
+      break;
+    case 2:
+      return new magmaequations_0_finite_element_2();
+      break;
+    case 3:
+      return new magmaequations_0_finite_element_3();
+      break;
+    case 4:
+      return new magmaequations_0_finite_element_4();
+      break;
+    case 5:
+      return new magmaequations_0_finite_element_5();
+      break;
+    case 6:
+      return new magmaequations_0_finite_element_6();
+      break;
+    case 7:
+      return new magmaequations_0_finite_element_7();
+      break;
+    }
+    return 0;
+}
+
+/// Create a new dof map for argument function i
+ufc::dof_map* magmaequations_form_0::create_dof_map(unsigned int i) const
+{
+    switch ( i )
+    {
+    case 0:
+      return new magmaequations_0_dof_map_0();
+      break;
+    case 1:
+      return new magmaequations_0_dof_map_1();
+      break;
+    case 2:
+      return new magmaequations_0_dof_map_2();
+      break;
+    case 3:
+      return new magmaequations_0_dof_map_3();
+      break;
+    case 4:
+      return new magmaequations_0_dof_map_4();
+      break;
+    case 5:
+      return new magmaequations_0_dof_map_5();
+      break;
+    case 6:
+      return new magmaequations_0_dof_map_6();
+      break;
+    case 7:
+      return new magmaequations_0_dof_map_7();
+      break;
+    }
+    return 0;
+}
+
+/// Create a new cell integral on sub domain i
+ufc::cell_integral* magmaequations_form_0::create_cell_integral(unsigned int i) const
+{
+    return new magmaequations_0_cell_integral_0();
+}
+
+/// Create a new exterior facet integral on sub domain i
+ufc::exterior_facet_integral* magmaequations_form_0::create_exterior_facet_integral(unsigned int i) const
+{
+    return new magmaequations_0_exterior_facet_integral_0();
+}
+
+/// Create a new interior facet integral on sub domain i
+ufc::interior_facet_integral* magmaequations_form_0::create_interior_facet_integral(unsigned int i) const
+{
+    return 0;
+}
+
+
+/// Constructor
+magmaequations_1_finite_element_0_0::magmaequations_1_finite_element_0_0() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+magmaequations_1_finite_element_0_0::~magmaequations_1_finite_element_0_0()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* magmaequations_1_finite_element_0_0::signature() const
+{
+    return "FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
+}
+
+/// Return the cell shape
+ufc::shape magmaequations_1_finite_element_0_0::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int magmaequations_1_finite_element_0_0::space_dimension() const
+{
+    return 6;
+}
+
+/// Return the rank of the value space
+unsigned int magmaequations_1_finite_element_0_0::value_rank() const
+{
+    return 0;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int magmaequations_1_finite_element_0_0::value_dimension(unsigned int i) const
+{
+    return 1;
+}
+
+/// Evaluate basis function i at given point in cell
+void magmaequations_1_finite_element_0_0::evaluate_basis(unsigned int i,
+                                   double* values,
+                                   const double* coordinates,
+                                   const ufc::cell& c) const
+{
+    // Extract vertex coordinates
+    const double * const * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Reset values
+    *values = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+    const double psitilde_bs_1_0 = 1;
+    const double psitilde_bs_1_1 = 2.5*y + 1.5;
+    const double psitilde_bs_2_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+    const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+    const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[6][6] = \
+    {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+    {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+    {0, 0, 0.2, 0, 0, 0.163299316185545},
+    {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+    {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+    {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+    // Extract relevant coefficients
+    const double coeff0_0 = coefficients0[dof][0];
+    const double coeff0_1 = coefficients0[dof][1];
+    const double coeff0_2 = coefficients0[dof][2];
+    const double coeff0_3 = coefficients0[dof][3];
+    const double coeff0_4 = coefficients0[dof][4];
+    const double coeff0_5 = coefficients0[dof][5];
+    
+    // Compute value(s)
+    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
+}
+
+/// Evaluate all basis functions at given point in cell
+void magmaequations_1_finite_element_0_0::evaluate_basis_all(double* values,
+                                       const double* coordinates,
+                                       const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
+}
+
+/// Evaluate order n derivatives of basis function i at given point in cell
+void magmaequations_1_finite_element_0_0::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 * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 2;
+    
+    
+    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
+    unsigned int **combinations = new unsigned int *[num_derivatives];
+    
+    for (unsigned int j = 0; j < num_derivatives; j++)
+    {
+      combinations[j] = new unsigned int [n];
+      for (unsigned int k = 0; k < n; k++)
+        combinations[j][k] = 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] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
+    
+    // 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
+    for (unsigned int j = 0; j < 1*num_derivatives; j++)
+      values[j] = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+    const double psitilde_bs_1_0 = 1;
+    const double psitilde_bs_1_1 = 2.5*y + 1.5;
+    const double psitilde_bs_2_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+    const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+    const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[6][6] = \
+    {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+    {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+    {0, 0, 0.2, 0, 0, 0.163299316185545},
+    {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+    {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+    {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+    // Interesting (new) part
+    // Tables of derivatives of the polynomial base (transpose)
+    static const double dmats0[6][6] = \
+    {{0, 0, 0, 0, 0, 0},
+    {4.89897948556636, 0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0},
+    {0, 9.48683298050514, 0, 0, 0, 0},
+    {4, 0, 7.07106781186548, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0}};
+    
+    static const double dmats1[6][6] = \
+    {{0, 0, 0, 0, 0, 0},
+    {2.44948974278318, 0, 0, 0, 0, 0},
+    {4.24264068711928, 0, 0, 0, 0, 0},
+    {2.58198889747161, 4.74341649025257, -0.912870929175277, 0, 0, 0},
+    {2, 6.12372435695795, 3.53553390593274, 0, 0, 0},
+    {-2.3094010767585, 0, 8.16496580927726, 0, 0, 0}};
+    
+    // Compute reference derivatives
+    // Declare pointer to array of derivatives on FIAT element
+    double *derivatives = new double [num_derivatives];
+    
+    // Declare coefficients
+    double coeff0_0 = 0;
+    double coeff0_1 = 0;
+    double coeff0_2 = 0;
+    double coeff0_3 = 0;
+    double coeff0_4 = 0;
+    double coeff0_5 = 0;
+    
+    // Declare new coefficients
+    double new_coeff0_0 = 0;
+    double new_coeff0_1 = 0;
+    double new_coeff0_2 = 0;
+    double new_coeff0_3 = 0;
+    double new_coeff0_4 = 0;
+    double new_coeff0_5 = 0;
+    
+    // Loop possible derivatives
+    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+    {
+      // Get values from coefficients array
+      new_coeff0_0 = coefficients0[dof][0];
+      new_coeff0_1 = coefficients0[dof][1];
+      new_coeff0_2 = coefficients0[dof][2];
+      new_coeff0_3 = coefficients0[dof][3];
+      new_coeff0_4 = coefficients0[dof][4];
+      new_coeff0_5 = coefficients0[dof][5];
+    
+      // Loop derivative order
+      for (unsigned int j = 0; j < n; j++)
+      {
+        // Update old coefficients
+        coeff0_0 = new_coeff0_0;
+        coeff0_1 = new_coeff0_1;
+        coeff0_2 = new_coeff0_2;
+        coeff0_3 = new_coeff0_3;
+        coeff0_4 = new_coeff0_4;
+        coeff0_5 = new_coeff0_5;
+    
+        if(combinations[deriv_num][j] == 0)
+        {
+          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
+          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
+          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
+          new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
+          new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
+          new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
+        }
+        if(combinations[deriv_num][j] == 1)
+        {
+          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
+          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
+          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
+          new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
+          new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
+          new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
+        }
+    
+      }
+      // Compute derivatives on reference element as dot product of coefficients and basisvalues
+      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
+    }
+    
+    // Transform derivatives back to physical element
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      for (unsigned int col = 0; col < num_derivatives; col++)
+      {
+        values[row] += transform[row][col]*derivatives[col];
+      }
+    }
+    // Delete pointer to array of derivatives on FIAT element
+    delete [] derivatives;
+    
+    // Delete pointer to array of combinations of derivatives and transform
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      delete [] combinations[row];
+      delete [] transform[row];
+    }
+    
+    delete [] combinations;
+    delete [] transform;
+}
+
+/// Evaluate order n derivatives of all basis functions at given point in cell
+void magmaequations_1_finite_element_0_0::evaluate_basis_derivatives_all(unsigned int n,
+                                                   double* values,
+                                                   const double* coordinates,
+                                                   const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
+}
+
+/// Evaluate linear functional for dof i on the function f
+double magmaequations_1_finite_element_0_0::evaluate_dof(unsigned int i,
+                                   const ufc::function& f,
+                                   const ufc::cell& c) const
+{
+    // The reference points, direction and weights:
+    static const double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}};
+    static const double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
+    static const double D[6][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}, {{1}}, {{1}}};
+    
+    const double * const * x = c.coordinates;
+    double result = 0.0;
+    // Iterate over the points:
+    // Evaluate basis functions for affine mapping
+    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    
+    // Compute affine mapping y = F(X)
+    double y[2];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
+    
+    // Evaluate function at physical points
+    double values[1];
+    f.evaluate(values, y, c);
+    
+    // Map function values using appropriate mapping
+    // Affine map: Do nothing
+    
+    // Note that we do not map the weights (yet).
+    
+    // Take directional components
+    for(int k = 0; k < 1; k++)
+      result += values[k]*D[i][0][k];
+    // Multiply by weights
+    result *= W[i][0];
+    
+    return result;
+}
+
+/// Evaluate linear functionals for all dofs on the function f
+void magmaequations_1_finite_element_0_0::evaluate_dofs(double* values,
+                                  const ufc::function& f,
+                                  const ufc::cell& c) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Interpolate vertex values from dof values
+void magmaequations_1_finite_element_0_0::interpolate_vertex_values(double* vertex_values,
+                                              const double* dof_values,
+                                              const ufc::cell& c) const
+{
+    // Evaluate at vertices and use affine mapping
+    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)
+unsigned int magmaequations_1_finite_element_0_0::num_sub_elements() const
+{
+    return 1;
+}
+
+/// Create a new finite element for sub element i (for a mixed element)
+ufc::finite_element* magmaequations_1_finite_element_0_0::create_sub_element(unsigned int i) const
+{
+    return new magmaequations_1_finite_element_0_0();
+}
+
+
+/// Constructor
+magmaequations_1_finite_element_0_1::magmaequations_1_finite_element_0_1() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+magmaequations_1_finite_element_0_1::~magmaequations_1_finite_element_0_1()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* magmaequations_1_finite_element_0_1::signature() const
+{
+    return "FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
+}
+
+/// Return the cell shape
+ufc::shape magmaequations_1_finite_element_0_1::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int magmaequations_1_finite_element_0_1::space_dimension() const
+{
+    return 6;
+}
+
+/// Return the rank of the value space
+unsigned int magmaequations_1_finite_element_0_1::value_rank() const
+{
+    return 0;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int magmaequations_1_finite_element_0_1::value_dimension(unsigned int i) const
+{
+    return 1;
+}
+
+/// Evaluate basis function i at given point in cell
+void magmaequations_1_finite_element_0_1::evaluate_basis(unsigned int i,
+                                   double* values,
+                                   const double* coordinates,
+                                   const ufc::cell& c) const
+{
+    // Extract vertex coordinates
+    const double * const * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Reset values
+    *values = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+    const double psitilde_bs_1_0 = 1;
+    const double psitilde_bs_1_1 = 2.5*y + 1.5;
+    const double psitilde_bs_2_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+    const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+    const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[6][6] = \
+    {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+    {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+    {0, 0, 0.2, 0, 0, 0.163299316185545},
+    {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+    {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+    {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+    // Extract relevant coefficients
+    const double coeff0_0 = coefficients0[dof][0];
+    const double coeff0_1 = coefficients0[dof][1];
+    const double coeff0_2 = coefficients0[dof][2];
+    const double coeff0_3 = coefficients0[dof][3];
+    const double coeff0_4 = coefficients0[dof][4];
+    const double coeff0_5 = coefficients0[dof][5];
+    
+    // Compute value(s)
+    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
+}
+
+/// Evaluate all basis functions at given point in cell
+void magmaequations_1_finite_element_0_1::evaluate_basis_all(double* values,
+                                       const double* coordinates,
+                                       const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
+}
+
+/// Evaluate order n derivatives of basis function i at given point in cell
+void magmaequations_1_finite_element_0_1::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 * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 2;
+    
+    
+    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
+    unsigned int **combinations = new unsigned int *[num_derivatives];
+    
+    for (unsigned int j = 0; j < num_derivatives; j++)
+    {
+      combinations[j] = new unsigned int [n];
+      for (unsigned int k = 0; k < n; k++)
+        combinations[j][k] = 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] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
+    
+    // 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
+    for (unsigned int j = 0; j < 1*num_derivatives; j++)
+      values[j] = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+    const double psitilde_bs_1_0 = 1;
+    const double psitilde_bs_1_1 = 2.5*y + 1.5;
+    const double psitilde_bs_2_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+    const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+    const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[6][6] = \
+    {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+    {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+    {0, 0, 0.2, 0, 0, 0.163299316185545},
+    {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+    {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+    {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+    // Interesting (new) part
+    // Tables of derivatives of the polynomial base (transpose)
+    static const double dmats0[6][6] = \
+    {{0, 0, 0, 0, 0, 0},
+    {4.89897948556636, 0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0},
+    {0, 9.48683298050514, 0, 0, 0, 0},
+    {4, 0, 7.07106781186548, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0}};
+    
+    static const double dmats1[6][6] = \
+    {{0, 0, 0, 0, 0, 0},
+    {2.44948974278318, 0, 0, 0, 0, 0},
+    {4.24264068711928, 0, 0, 0, 0, 0},
+    {2.58198889747161, 4.74341649025257, -0.912870929175277, 0, 0, 0},
+    {2, 6.12372435695795, 3.53553390593274, 0, 0, 0},
+    {-2.3094010767585, 0, 8.16496580927726, 0, 0, 0}};
+    
+    // Compute reference derivatives
+    // Declare pointer to array of derivatives on FIAT element
+    double *derivatives = new double [num_derivatives];
+    
+    // Declare coefficients
+    double coeff0_0 = 0;
+    double coeff0_1 = 0;
+    double coeff0_2 = 0;
+    double coeff0_3 = 0;
+    double coeff0_4 = 0;
+    double coeff0_5 = 0;
+    
+    // Declare new coefficients
+    double new_coeff0_0 = 0;
+    double new_coeff0_1 = 0;
+    double new_coeff0_2 = 0;
+    double new_coeff0_3 = 0;
+    double new_coeff0_4 = 0;
+    double new_coeff0_5 = 0;
+    
+    // Loop possible derivatives
+    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+    {
+      // Get values from coefficients array
+      new_coeff0_0 = coefficients0[dof][0];
+      new_coeff0_1 = coefficients0[dof][1];
+      new_coeff0_2 = coefficients0[dof][2];
+      new_coeff0_3 = coefficients0[dof][3];
+      new_coeff0_4 = coefficients0[dof][4];
+      new_coeff0_5 = coefficients0[dof][5];
+    
+      // Loop derivative order
+      for (unsigned int j = 0; j < n; j++)
+      {
+        // Update old coefficients
+        coeff0_0 = new_coeff0_0;
+        coeff0_1 = new_coeff0_1;
+        coeff0_2 = new_coeff0_2;
+        coeff0_3 = new_coeff0_3;
+        coeff0_4 = new_coeff0_4;
+        coeff0_5 = new_coeff0_5;
+    
+        if(combinations[deriv_num][j] == 0)
+        {
+          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
+          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
+          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
+          new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
+          new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
+          new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
+        }
+        if(combinations[deriv_num][j] == 1)
+        {
+          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
+          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
+          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
+          new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
+          new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
+          new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
+        }
+    
+      }
+      // Compute derivatives on reference element as dot product of coefficients and basisvalues
+      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
+    }
+    
+    // Transform derivatives back to physical element
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      for (unsigned int col = 0; col < num_derivatives; col++)
+      {
+        values[row] += transform[row][col]*derivatives[col];
+      }
+    }
+    // Delete pointer to array of derivatives on FIAT element
+    delete [] derivatives;
+    
+    // Delete pointer to array of combinations of derivatives and transform
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      delete [] combinations[row];
+      delete [] transform[row];
+    }
+    
+    delete [] combinations;
+    delete [] transform;
+}
+
+/// Evaluate order n derivatives of all basis functions at given point in cell
+void magmaequations_1_finite_element_0_1::evaluate_basis_derivatives_all(unsigned int n,
+                                                   double* values,
+                                                   const double* coordinates,
+                                                   const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
+}
+
+/// Evaluate linear functional for dof i on the function f
+double magmaequations_1_finite_element_0_1::evaluate_dof(unsigned int i,
+                                   const ufc::function& f,
+                                   const ufc::cell& c) const
+{
+    // The reference points, direction and weights:
+    static const double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}};
+    static const double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
+    static const double D[6][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}, {{1}}, {{1}}};
+    
+    const double * const * x = c.coordinates;
+    double result = 0.0;
+    // Iterate over the points:
+    // Evaluate basis functions for affine mapping
+    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    
+    // Compute affine mapping y = F(X)
+    double y[2];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
+    
+    // Evaluate function at physical points
+    double values[1];
+    f.evaluate(values, y, c);
+    
+    // Map function values using appropriate mapping
+    // Affine map: Do nothing
+    
+    // Note that we do not map the weights (yet).
+    
+    // Take directional components
+    for(int k = 0; k < 1; k++)
+      result += values[k]*D[i][0][k];
+    // Multiply by weights
+    result *= W[i][0];
+    
+    return result;
+}
+
+/// Evaluate linear functionals for all dofs on the function f
+void magmaequations_1_finite_element_0_1::evaluate_dofs(double* values,
+                                  const ufc::function& f,
+                                  const ufc::cell& c) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Interpolate vertex values from dof values
+void magmaequations_1_finite_element_0_1::interpolate_vertex_values(double* vertex_values,
+                                              const double* dof_values,
+                                              const ufc::cell& c) const
+{
+    // Evaluate at vertices and use affine mapping
+    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)
+unsigned int magmaequations_1_finite_element_0_1::num_sub_elements() const
+{
+    return 1;
+}
+
+/// Create a new finite element for sub element i (for a mixed element)
+ufc::finite_element* magmaequations_1_finite_element_0_1::create_sub_element(unsigned int i) const
+{
+    return new magmaequations_1_finite_element_0_1();
+}
+
+
+/// Constructor
+magmaequations_1_finite_element_0::magmaequations_1_finite_element_0() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+magmaequations_1_finite_element_0::~magmaequations_1_finite_element_0()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* magmaequations_1_finite_element_0::signature() const
+{
+    return "MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)], **{'value_shape': (2,) })";
+}
+
+/// Return the cell shape
+ufc::shape magmaequations_1_finite_element_0::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int magmaequations_1_finite_element_0::space_dimension() const
+{
+    return 12;
+}
+
+/// Return the rank of the value space
+unsigned int magmaequations_1_finite_element_0::value_rank() const
+{
+    return 1;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int magmaequations_1_finite_element_0::value_dimension(unsigned int i) const
+{
+    return 2;
+}
+
+/// Evaluate basis function i at given point in cell
+void magmaequations_1_finite_element_0::evaluate_basis(unsigned int i,
+                                   double* values,
+                                   const double* coordinates,
+                                   const ufc::cell& c) const
+{
+    // Extract vertex coordinates
+    const double * const * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Reset values
+    values[0] = 0;
+    values[1] = 0;
+    
+    if (0 <= i && i <= 5)
+    {
+      // Map degree of freedom to element degree of freedom
+      const unsigned int dof = i;
+    
+      // Generate scalings
+      const double scalings_y_0 = 1;
+      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+      const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+      // Compute psitilde_a
+      const double psitilde_a_0 = 1;
+      const double psitilde_a_1 = x;
+      const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+      // Compute psitilde_bs
+      const double psitilde_bs_0_0 = 1;
+      const double psitilde_bs_0_1 = 1.5*y + 0.5;
+      const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+      const double psitilde_bs_1_0 = 1;
+      const double psitilde_bs_1_1 = 2.5*y + 1.5;
+      const double psitilde_bs_2_0 = 1;
+    
+      // Compute basisvalues
+      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+      const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+      const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+      const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+      // Table(s) of coefficients
+      static const double coefficients0[6][6] =   \
+      {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+      {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+      {0, 0, 0.2, 0, 0, 0.163299316185545},
+      {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+      {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+      {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+      // Extract relevant coefficients
+      const double coeff0_0 =   coefficients0[dof][0];
+      const double coeff0_1 =   coefficients0[dof][1];
+      const double coeff0_2 =   coefficients0[dof][2];
+      const double coeff0_3 =   coefficients0[dof][3];
+      const double coeff0_4 =   coefficients0[dof][4];
+      const double coeff0_5 =   coefficients0[dof][5];
+    
+      // Compute value(s)
+      values[0] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
+    }
+    
+    if (6 <= i && i <= 11)
+    {
+      // Map degree of freedom to element degree of freedom
+      const unsigned int dof = i - 6;
+    
+      // Generate scalings
+      const double scalings_y_0 = 1;
+      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+      const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+      // Compute psitilde_a
+      const double psitilde_a_0 = 1;
+      const double psitilde_a_1 = x;
+      const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+      // Compute psitilde_bs
+      const double psitilde_bs_0_0 = 1;
+      const double psitilde_bs_0_1 = 1.5*y + 0.5;
+      const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+      const double psitilde_bs_1_0 = 1;
+      const double psitilde_bs_1_1 = 2.5*y + 1.5;
+      const double psitilde_bs_2_0 = 1;
+    
+      // Compute basisvalues
+      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+      const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+      const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+      const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+      // Table(s) of coefficients
+      static const double coefficients0[6][6] =   \
+      {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+      {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+      {0, 0, 0.2, 0, 0, 0.163299316185545},
+      {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+      {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+      {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+      // Extract relevant coefficients
+      const double coeff0_0 =   coefficients0[dof][0];
+      const double coeff0_1 =   coefficients0[dof][1];
+      const double coeff0_2 =   coefficients0[dof][2];
+      const double coeff0_3 =   coefficients0[dof][3];
+      const double coeff0_4 =   coefficients0[dof][4];
+      const double coeff0_5 =   coefficients0[dof][5];
+    
+      // Compute value(s)
+      values[1] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
+    }
+    
+}
+
+/// Evaluate all basis functions at given point in cell
+void magmaequations_1_finite_element_0::evaluate_basis_all(double* values,
+                                       const double* coordinates,
+                                       const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
+}
+
+/// Evaluate order n derivatives of basis function i at given point in cell
+void magmaequations_1_finite_element_0::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 * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 2;
+    
+    
+    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
+    unsigned int **combinations = new unsigned int *[num_derivatives];
+    
+    for (unsigned int j = 0; j < num_derivatives; j++)
+    {
+      combinations[j] = new unsigned int [n];
+      for (unsigned int k = 0; k < n; k++)
+        combinations[j][k] = 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] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
+    
+    // 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
+    for (unsigned int j = 0; j < 2*num_derivatives; j++)
+      values[j] = 0;
+    
+    if (0 <= i && i <= 5)
+    {
+      // Map degree of freedom to element degree of freedom
+      const unsigned int dof = i;
+    
+      // Generate scalings
+      const double scalings_y_0 = 1;
+      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+      const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+      // Compute psitilde_a
+      const double psitilde_a_0 = 1;
+      const double psitilde_a_1 = x;
+      const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+      // Compute psitilde_bs
+      const double psitilde_bs_0_0 = 1;
+      const double psitilde_bs_0_1 = 1.5*y + 0.5;
+      const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+      const double psitilde_bs_1_0 = 1;
+      const double psitilde_bs_1_1 = 2.5*y + 1.5;
+      const double psitilde_bs_2_0 = 1;
+    
+      // Compute basisvalues
+      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+      const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+      const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+      const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+      // Table(s) of coefficients
+      static const double coefficients0[6][6] =   \
+      {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+      {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+      {0, 0, 0.2, 0, 0, 0.163299316185545},
+      {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+      {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+      {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+      // Interesting (new) part
+      // Tables of derivatives of the polynomial base (transpose)
+      static const double dmats0[6][6] =   \
+      {{0, 0, 0, 0, 0, 0},
+      {4.89897948556636, 0, 0, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0},
+      {0, 9.48683298050514, 0, 0, 0, 0},
+      {4, 0, 7.07106781186548, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0}};
+    
+      static const double dmats1[6][6] =   \
+      {{0, 0, 0, 0, 0, 0},
+      {2.44948974278318, 0, 0, 0, 0, 0},
+      {4.24264068711928, 0, 0, 0, 0, 0},
+      {2.58198889747161, 4.74341649025257, -0.912870929175277, 0, 0, 0},
+      {2, 6.12372435695795, 3.53553390593274, 0, 0, 0},
+      {-2.3094010767585, 0, 8.16496580927726, 0, 0, 0}};
+    
+      // Compute reference derivatives
+      // Declare pointer to array of derivatives on FIAT element
+      double *derivatives = new double [num_derivatives];
+    
+      // Declare coefficients
+      double coeff0_0 = 0;
+      double coeff0_1 = 0;
+      double coeff0_2 = 0;
+      double coeff0_3 = 0;
+      double coeff0_4 = 0;
+      double coeff0_5 = 0;
+    
+      // Declare new coefficients
+      double new_coeff0_0 = 0;
+      double new_coeff0_1 = 0;
+      double new_coeff0_2 = 0;
+      double new_coeff0_3 = 0;
+      double new_coeff0_4 = 0;
+      double new_coeff0_5 = 0;
+    
+      // Loop possible derivatives
+      for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+      {
+        // Get values from coefficients array
+        new_coeff0_0 = coefficients0[dof][0];
+        new_coeff0_1 = coefficients0[dof][1];
+        new_coeff0_2 = coefficients0[dof][2];
+        new_coeff0_3 = coefficients0[dof][3];
+        new_coeff0_4 = coefficients0[dof][4];
+        new_coeff0_5 = coefficients0[dof][5];
+    
+        // Loop derivative order
+        for (unsigned int j = 0; j < n; j++)
+        {
+          // Update old coefficients
+          coeff0_0 = new_coeff0_0;
+          coeff0_1 = new_coeff0_1;
+          coeff0_2 = new_coeff0_2;
+          coeff0_3 = new_coeff0_3;
+          coeff0_4 = new_coeff0_4;
+          coeff0_5 = new_coeff0_5;
+    
+          if(combinations[deriv_num][j] == 0)
+          {
+            new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
+            new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
+            new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
+            new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
+            new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
+            new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
+          }
+          if(combinations[deriv_num][j] == 1)
+          {
+            new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
+            new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
+            new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
+            new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
+            new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
+            new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
+          }
+    
+        }
+        // Compute derivatives on reference element as dot product of coefficients and basisvalues
+        derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
+      }
+    
+      // Transform derivatives back to physical element
+      for (unsigned int row = 0; row < num_derivatives; row++)
+      {
+        for (unsigned int col = 0; col < num_derivatives; col++)
+        {
+          values[row] += transform[row][col]*derivatives[col];
+        }
+      }
+      // Delete pointer to array of derivatives on FIAT element
+      delete [] derivatives;
+    
+      // Delete pointer to array of combinations of derivatives and transform
+      for (unsigned int row = 0; row < num_derivatives; row++)
+      {
+        delete [] combinations[row];
+        delete [] transform[row];
+      }
+    
+      delete [] combinations;
+      delete [] transform;
+    }
+    
+    if (6 <= i && i <= 11)
+    {
+      // Map degree of freedom to element degree of freedom
+      const unsigned int dof = i - 6;
+    
+      // Generate scalings
+      const double scalings_y_0 = 1;
+      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+      const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+      // Compute psitilde_a
+      const double psitilde_a_0 = 1;
+      const double psitilde_a_1 = x;
+      const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+      // Compute psitilde_bs
+      const double psitilde_bs_0_0 = 1;
+      const double psitilde_bs_0_1 = 1.5*y + 0.5;
+      const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+      const double psitilde_bs_1_0 = 1;
+      const double psitilde_bs_1_1 = 2.5*y + 1.5;
+      const double psitilde_bs_2_0 = 1;
+    
+      // Compute basisvalues
+      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+      const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+      const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+      const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+      // Table(s) of coefficients
+      static const double coefficients0[6][6] =   \
+      {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+      {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+      {0, 0, 0.2, 0, 0, 0.163299316185545},
+      {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+      {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+      {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+      // Interesting (new) part
+      // Tables of derivatives of the polynomial base (transpose)
+      static const double dmats0[6][6] =   \
+      {{0, 0, 0, 0, 0, 0},
+      {4.89897948556636, 0, 0, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0},
+      {0, 9.48683298050514, 0, 0, 0, 0},
+      {4, 0, 7.07106781186548, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0}};
+    
+      static const double dmats1[6][6] =   \
+      {{0, 0, 0, 0, 0, 0},
+      {2.44948974278318, 0, 0, 0, 0, 0},
+      {4.24264068711928, 0, 0, 0, 0, 0},
+      {2.58198889747161, 4.74341649025257, -0.912870929175277, 0, 0, 0},
+      {2, 6.12372435695795, 3.53553390593274, 0, 0, 0},
+      {-2.3094010767585, 0, 8.16496580927726, 0, 0, 0}};
+    
+      // Compute reference derivatives
+      // Declare pointer to array of derivatives on FIAT element
+      double *derivatives = new double [num_derivatives];
+    
+      // Declare coefficients
+      double coeff0_0 = 0;
+      double coeff0_1 = 0;
+      double coeff0_2 = 0;
+      double coeff0_3 = 0;
+      double coeff0_4 = 0;
+      double coeff0_5 = 0;
+    
+      // Declare new coefficients
+      double new_coeff0_0 = 0;
+      double new_coeff0_1 = 0;
+      double new_coeff0_2 = 0;
+      double new_coeff0_3 = 0;
+      double new_coeff0_4 = 0;
+      double new_coeff0_5 = 0;
+    
+      // Loop possible derivatives
+      for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+      {
+        // Get values from coefficients array
+        new_coeff0_0 = coefficients0[dof][0];
+        new_coeff0_1 = coefficients0[dof][1];
+        new_coeff0_2 = coefficients0[dof][2];
+        new_coeff0_3 = coefficients0[dof][3];
+        new_coeff0_4 = coefficients0[dof][4];
+        new_coeff0_5 = coefficients0[dof][5];
+    
+        // Loop derivative order
+        for (unsigned int j = 0; j < n; j++)
+        {
+          // Update old coefficients
+          coeff0_0 = new_coeff0_0;
+          coeff0_1 = new_coeff0_1;
+          coeff0_2 = new_coeff0_2;
+          coeff0_3 = new_coeff0_3;
+          coeff0_4 = new_coeff0_4;
+          coeff0_5 = new_coeff0_5;
+    
+          if(combinations[deriv_num][j] == 0)
+          {
+            new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
+            new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
+            new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
+            new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
+            new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
+            new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
+          }
+          if(combinations[deriv_num][j] == 1)
+          {
+            new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
+            new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
+            new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
+            new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
+            new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
+            new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
+          }
+    
+        }
+        // Compute derivatives on reference element as dot product of coefficients and basisvalues
+        derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
+      }
+    
+      // Transform derivatives back to physical element
+      for (unsigned int row = 0; row < num_derivatives; row++)
+      {
+        for (unsigned int col = 0; col < num_derivatives; col++)
+        {
+          values[num_derivatives + row] += transform[row][col]*derivatives[col];
+        }
+      }
+      // Delete pointer to array of derivatives on FIAT element
+      delete [] derivatives;
+    
+      // Delete pointer to array of combinations of derivatives and transform
+      for (unsigned int row = 0; row < num_derivatives; row++)
+      {
+        delete [] combinations[row];
+        delete [] transform[row];
+      }
+    
+      delete [] combinations;
+      delete [] transform;
+    }
+    
+}
+
+/// Evaluate order n derivatives of all basis functions at given point in cell
+void magmaequations_1_finite_element_0::evaluate_basis_derivatives_all(unsigned int n,
+                                                   double* values,
+                                                   const double* coordinates,
+                                                   const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
+}
+
+/// Evaluate linear functional for dof i on the function f
+double magmaequations_1_finite_element_0::evaluate_dof(unsigned int i,
+                                   const ufc::function& f,
+                                   const ufc::cell& c) const
+{
+    // The reference points, direction and weights:
+    static const double X[12][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}, {{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}};
+    static const double W[12][1] = {{1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}};
+    static const double D[12][1][2] = {{{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{0, 1}}, {{0, 1}}, {{0, 1}}, {{0, 1}}, {{0, 1}}, {{0, 1}}};
+    
+    const double * const * x = c.coordinates;
+    double result = 0.0;
+    // Iterate over the points:
+    // Evaluate basis functions for affine mapping
+    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    
+    // Compute affine mapping y = F(X)
+    double y[2];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
+    
+    // Evaluate function at physical points
+    double values[2];
+    f.evaluate(values, y, c);
+    
+    // Map function values using appropriate mapping
+    // Affine map: Do nothing
+    
+    // Note that we do not map the weights (yet).
+    
+    // Take directional components
+    for(int k = 0; k < 2; k++)
+      result += values[k]*D[i][0][k];
+    // Multiply by weights
+    result *= W[i][0];
+    
+    return result;
+}
+
+/// Evaluate linear functionals for all dofs on the function f
+void magmaequations_1_finite_element_0::evaluate_dofs(double* values,
+                                  const ufc::function& f,
+                                  const ufc::cell& c) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Interpolate vertex values from dof values
+void magmaequations_1_finite_element_0::interpolate_vertex_values(double* vertex_values,
+                                              const double* dof_values,
+                                              const ufc::cell& c) const
+{
+    // Evaluate at vertices and use affine mapping
+    vertex_values[0] = dof_values[0];
+    vertex_values[2] = dof_values[1];
+    vertex_values[4] = dof_values[2];
+    // Evaluate at vertices and use affine mapping
+    vertex_values[1] = dof_values[6];
+    vertex_values[3] = dof_values[7];
+    vertex_values[5] = dof_values[8];
+}
+
+/// Return the number of sub elements (for a mixed element)
+unsigned int magmaequations_1_finite_element_0::num_sub_elements() const
+{
+    return 2;
+}
+
+/// Create a new finite element for sub element i (for a mixed element)
+ufc::finite_element* magmaequations_1_finite_element_0::create_sub_element(unsigned int i) const
+{
+    switch ( i )
+    {
+    case 0:
+      return new magmaequations_1_finite_element_0_0();
+      break;
+    case 1:
+      return new magmaequations_1_finite_element_0_1();
+      break;
+    }
+    return 0;
+}
+
+
+/// Constructor
+magmaequations_1_finite_element_1_0::magmaequations_1_finite_element_1_0() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+magmaequations_1_finite_element_1_0::~magmaequations_1_finite_element_1_0()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* magmaequations_1_finite_element_1_0::signature() const
+{
+    return "FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
+}
+
+/// Return the cell shape
+ufc::shape magmaequations_1_finite_element_1_0::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int magmaequations_1_finite_element_1_0::space_dimension() const
+{
+    return 6;
+}
+
+/// Return the rank of the value space
+unsigned int magmaequations_1_finite_element_1_0::value_rank() const
+{
+    return 0;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int magmaequations_1_finite_element_1_0::value_dimension(unsigned int i) const
+{
+    return 1;
+}
+
+/// Evaluate basis function i at given point in cell
+void magmaequations_1_finite_element_1_0::evaluate_basis(unsigned int i,
+                                   double* values,
+                                   const double* coordinates,
+                                   const ufc::cell& c) const
+{
+    // Extract vertex coordinates
+    const double * const * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Reset values
+    *values = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+    const double psitilde_bs_1_0 = 1;
+    const double psitilde_bs_1_1 = 2.5*y + 1.5;
+    const double psitilde_bs_2_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+    const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+    const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[6][6] = \
+    {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+    {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+    {0, 0, 0.2, 0, 0, 0.163299316185545},
+    {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+    {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+    {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+    // Extract relevant coefficients
+    const double coeff0_0 = coefficients0[dof][0];
+    const double coeff0_1 = coefficients0[dof][1];
+    const double coeff0_2 = coefficients0[dof][2];
+    const double coeff0_3 = coefficients0[dof][3];
+    const double coeff0_4 = coefficients0[dof][4];
+    const double coeff0_5 = coefficients0[dof][5];
+    
+    // Compute value(s)
+    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
+}
+
+/// Evaluate all basis functions at given point in cell
+void magmaequations_1_finite_element_1_0::evaluate_basis_all(double* values,
+                                       const double* coordinates,
+                                       const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
+}
+
+/// Evaluate order n derivatives of basis function i at given point in cell
+void magmaequations_1_finite_element_1_0::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 * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 2;
+    
+    
+    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
+    unsigned int **combinations = new unsigned int *[num_derivatives];
+    
+    for (unsigned int j = 0; j < num_derivatives; j++)
+    {
+      combinations[j] = new unsigned int [n];
+      for (unsigned int k = 0; k < n; k++)
+        combinations[j][k] = 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] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
+    
+    // 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
+    for (unsigned int j = 0; j < 1*num_derivatives; j++)
+      values[j] = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+    const double psitilde_bs_1_0 = 1;
+    const double psitilde_bs_1_1 = 2.5*y + 1.5;
+    const double psitilde_bs_2_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+    const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+    const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[6][6] = \
+    {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+    {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+    {0, 0, 0.2, 0, 0, 0.163299316185545},
+    {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+    {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+    {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+    // Interesting (new) part
+    // Tables of derivatives of the polynomial base (transpose)
+    static const double dmats0[6][6] = \
+    {{0, 0, 0, 0, 0, 0},
+    {4.89897948556636, 0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0},
+    {0, 9.48683298050514, 0, 0, 0, 0},
+    {4, 0, 7.07106781186548, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0}};
+    
+    static const double dmats1[6][6] = \
+    {{0, 0, 0, 0, 0, 0},
+    {2.44948974278318, 0, 0, 0, 0, 0},
+    {4.24264068711928, 0, 0, 0, 0, 0},
+    {2.58198889747161, 4.74341649025257, -0.912870929175277, 0, 0, 0},
+    {2, 6.12372435695795, 3.53553390593274, 0, 0, 0},
+    {-2.3094010767585, 0, 8.16496580927726, 0, 0, 0}};
+    
+    // Compute reference derivatives
+    // Declare pointer to array of derivatives on FIAT element
+    double *derivatives = new double [num_derivatives];
+    
+    // Declare coefficients
+    double coeff0_0 = 0;
+    double coeff0_1 = 0;
+    double coeff0_2 = 0;
+    double coeff0_3 = 0;
+    double coeff0_4 = 0;
+    double coeff0_5 = 0;
+    
+    // Declare new coefficients
+    double new_coeff0_0 = 0;
+    double new_coeff0_1 = 0;
+    double new_coeff0_2 = 0;
+    double new_coeff0_3 = 0;
+    double new_coeff0_4 = 0;
+    double new_coeff0_5 = 0;
+    
+    // Loop possible derivatives
+    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+    {
+      // Get values from coefficients array
+      new_coeff0_0 = coefficients0[dof][0];
+      new_coeff0_1 = coefficients0[dof][1];
+      new_coeff0_2 = coefficients0[dof][2];
+      new_coeff0_3 = coefficients0[dof][3];
+      new_coeff0_4 = coefficients0[dof][4];
+      new_coeff0_5 = coefficients0[dof][5];
+    
+      // Loop derivative order
+      for (unsigned int j = 0; j < n; j++)
+      {
+        // Update old coefficients
+        coeff0_0 = new_coeff0_0;
+        coeff0_1 = new_coeff0_1;
+        coeff0_2 = new_coeff0_2;
+        coeff0_3 = new_coeff0_3;
+        coeff0_4 = new_coeff0_4;
+        coeff0_5 = new_coeff0_5;
+    
+        if(combinations[deriv_num][j] == 0)
+        {
+          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
+          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
+          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
+          new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
+          new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
+          new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
+        }
+        if(combinations[deriv_num][j] == 1)
+        {
+          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
+          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
+          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
+          new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
+          new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
+          new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
+        }
+    
+      }
+      // Compute derivatives on reference element as dot product of coefficients and basisvalues
+      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
+    }
+    
+    // Transform derivatives back to physical element
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      for (unsigned int col = 0; col < num_derivatives; col++)
+      {
+        values[row] += transform[row][col]*derivatives[col];
+      }
+    }
+    // Delete pointer to array of derivatives on FIAT element
+    delete [] derivatives;
+    
+    // Delete pointer to array of combinations of derivatives and transform
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      delete [] combinations[row];
+      delete [] transform[row];
+    }
+    
+    delete [] combinations;
+    delete [] transform;
+}
+
+/// Evaluate order n derivatives of all basis functions at given point in cell
+void magmaequations_1_finite_element_1_0::evaluate_basis_derivatives_all(unsigned int n,
+                                                   double* values,
+                                                   const double* coordinates,
+                                                   const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
+}
+
+/// Evaluate linear functional for dof i on the function f
+double magmaequations_1_finite_element_1_0::evaluate_dof(unsigned int i,
+                                   const ufc::function& f,
+                                   const ufc::cell& c) const
+{
+    // The reference points, direction and weights:
+    static const double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}};
+    static const double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
+    static const double D[6][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}, {{1}}, {{1}}};
+    
+    const double * const * x = c.coordinates;
+    double result = 0.0;
+    // Iterate over the points:
+    // Evaluate basis functions for affine mapping
+    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    
+    // Compute affine mapping y = F(X)
+    double y[2];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
+    
+    // Evaluate function at physical points
+    double values[1];
+    f.evaluate(values, y, c);
+    
+    // Map function values using appropriate mapping
+    // Affine map: Do nothing
+    
+    // Note that we do not map the weights (yet).
+    
+    // Take directional components
+    for(int k = 0; k < 1; k++)
+      result += values[k]*D[i][0][k];
+    // Multiply by weights
+    result *= W[i][0];
+    
+    return result;
+}
+
+/// Evaluate linear functionals for all dofs on the function f
+void magmaequations_1_finite_element_1_0::evaluate_dofs(double* values,
+                                  const ufc::function& f,
+                                  const ufc::cell& c) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Interpolate vertex values from dof values
+void magmaequations_1_finite_element_1_0::interpolate_vertex_values(double* vertex_values,
+                                              const double* dof_values,
+                                              const ufc::cell& c) const
+{
+    // Evaluate at vertices and use affine mapping
+    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)
+unsigned int magmaequations_1_finite_element_1_0::num_sub_elements() const
+{
+    return 1;
+}
+
+/// Create a new finite element for sub element i (for a mixed element)
+ufc::finite_element* magmaequations_1_finite_element_1_0::create_sub_element(unsigned int i) const
+{
+    return new magmaequations_1_finite_element_1_0();
+}
+
+
+/// Constructor
+magmaequations_1_finite_element_1_1::magmaequations_1_finite_element_1_1() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+magmaequations_1_finite_element_1_1::~magmaequations_1_finite_element_1_1()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* magmaequations_1_finite_element_1_1::signature() const
+{
+    return "FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
+}
+
+/// Return the cell shape
+ufc::shape magmaequations_1_finite_element_1_1::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int magmaequations_1_finite_element_1_1::space_dimension() const
+{
+    return 6;
+}
+
+/// Return the rank of the value space
+unsigned int magmaequations_1_finite_element_1_1::value_rank() const
+{
+    return 0;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int magmaequations_1_finite_element_1_1::value_dimension(unsigned int i) const
+{
+    return 1;
+}
+
+/// Evaluate basis function i at given point in cell
+void magmaequations_1_finite_element_1_1::evaluate_basis(unsigned int i,
+                                   double* values,
+                                   const double* coordinates,
+                                   const ufc::cell& c) const
+{
+    // Extract vertex coordinates
+    const double * const * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Reset values
+    *values = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+    const double psitilde_bs_1_0 = 1;
+    const double psitilde_bs_1_1 = 2.5*y + 1.5;
+    const double psitilde_bs_2_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+    const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+    const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[6][6] = \
+    {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+    {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+    {0, 0, 0.2, 0, 0, 0.163299316185545},
+    {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+    {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+    {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+    // Extract relevant coefficients
+    const double coeff0_0 = coefficients0[dof][0];
+    const double coeff0_1 = coefficients0[dof][1];
+    const double coeff0_2 = coefficients0[dof][2];
+    const double coeff0_3 = coefficients0[dof][3];
+    const double coeff0_4 = coefficients0[dof][4];
+    const double coeff0_5 = coefficients0[dof][5];
+    
+    // Compute value(s)
+    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
+}
+
+/// Evaluate all basis functions at given point in cell
+void magmaequations_1_finite_element_1_1::evaluate_basis_all(double* values,
+                                       const double* coordinates,
+                                       const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
+}
+
+/// Evaluate order n derivatives of basis function i at given point in cell
+void magmaequations_1_finite_element_1_1::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 * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 2;
+    
+    
+    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
+    unsigned int **combinations = new unsigned int *[num_derivatives];
+    
+    for (unsigned int j = 0; j < num_derivatives; j++)
+    {
+      combinations[j] = new unsigned int [n];
+      for (unsigned int k = 0; k < n; k++)
+        combinations[j][k] = 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] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
+    
+    // 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
+    for (unsigned int j = 0; j < 1*num_derivatives; j++)
+      values[j] = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+    const double psitilde_bs_1_0 = 1;
+    const double psitilde_bs_1_1 = 2.5*y + 1.5;
+    const double psitilde_bs_2_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+    const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+    const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[6][6] = \
+    {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+    {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+    {0, 0, 0.2, 0, 0, 0.163299316185545},
+    {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+    {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+    {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+    // Interesting (new) part
+    // Tables of derivatives of the polynomial base (transpose)
+    static const double dmats0[6][6] = \
+    {{0, 0, 0, 0, 0, 0},
+    {4.89897948556636, 0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0},
+    {0, 9.48683298050514, 0, 0, 0, 0},
+    {4, 0, 7.07106781186548, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0}};
+    
+    static const double dmats1[6][6] = \
+    {{0, 0, 0, 0, 0, 0},
+    {2.44948974278318, 0, 0, 0, 0, 0},
+    {4.24264068711928, 0, 0, 0, 0, 0},
+    {2.58198889747161, 4.74341649025257, -0.912870929175277, 0, 0, 0},
+    {2, 6.12372435695795, 3.53553390593274, 0, 0, 0},
+    {-2.3094010767585, 0, 8.16496580927726, 0, 0, 0}};
+    
+    // Compute reference derivatives
+    // Declare pointer to array of derivatives on FIAT element
+    double *derivatives = new double [num_derivatives];
+    
+    // Declare coefficients
+    double coeff0_0 = 0;
+    double coeff0_1 = 0;
+    double coeff0_2 = 0;
+    double coeff0_3 = 0;
+    double coeff0_4 = 0;
+    double coeff0_5 = 0;
+    
+    // Declare new coefficients
+    double new_coeff0_0 = 0;
+    double new_coeff0_1 = 0;
+    double new_coeff0_2 = 0;
+    double new_coeff0_3 = 0;
+    double new_coeff0_4 = 0;
+    double new_coeff0_5 = 0;
+    
+    // Loop possible derivatives
+    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+    {
+      // Get values from coefficients array
+      new_coeff0_0 = coefficients0[dof][0];
+      new_coeff0_1 = coefficients0[dof][1];
+      new_coeff0_2 = coefficients0[dof][2];
+      new_coeff0_3 = coefficients0[dof][3];
+      new_coeff0_4 = coefficients0[dof][4];
+      new_coeff0_5 = coefficients0[dof][5];
+    
+      // Loop derivative order
+      for (unsigned int j = 0; j < n; j++)
+      {
+        // Update old coefficients
+        coeff0_0 = new_coeff0_0;
+        coeff0_1 = new_coeff0_1;
+        coeff0_2 = new_coeff0_2;
+        coeff0_3 = new_coeff0_3;
+        coeff0_4 = new_coeff0_4;
+        coeff0_5 = new_coeff0_5;
+    
+        if(combinations[deriv_num][j] == 0)
+        {
+          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
+          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
+          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
+          new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
+          new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
+          new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
+        }
+        if(combinations[deriv_num][j] == 1)
+        {
+          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
+          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
+          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
+          new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
+          new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
+          new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
+        }
+    
+      }
+      // Compute derivatives on reference element as dot product of coefficients and basisvalues
+      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
+    }
+    
+    // Transform derivatives back to physical element
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      for (unsigned int col = 0; col < num_derivatives; col++)
+      {
+        values[row] += transform[row][col]*derivatives[col];
+      }
+    }
+    // Delete pointer to array of derivatives on FIAT element
+    delete [] derivatives;
+    
+    // Delete pointer to array of combinations of derivatives and transform
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      delete [] combinations[row];
+      delete [] transform[row];
+    }
+    
+    delete [] combinations;
+    delete [] transform;
+}
+
+/// Evaluate order n derivatives of all basis functions at given point in cell
+void magmaequations_1_finite_element_1_1::evaluate_basis_derivatives_all(unsigned int n,
+                                                   double* values,
+                                                   const double* coordinates,
+                                                   const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
+}
+
+/// Evaluate linear functional for dof i on the function f
+double magmaequations_1_finite_element_1_1::evaluate_dof(unsigned int i,
+                                   const ufc::function& f,
+                                   const ufc::cell& c) const
+{
+    // The reference points, direction and weights:
+    static const double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}};
+    static const double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
+    static const double D[6][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}, {{1}}, {{1}}};
+    
+    const double * const * x = c.coordinates;
+    double result = 0.0;
+    // Iterate over the points:
+    // Evaluate basis functions for affine mapping
+    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    
+    // Compute affine mapping y = F(X)
+    double y[2];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
+    
+    // Evaluate function at physical points
+    double values[1];
+    f.evaluate(values, y, c);
+    
+    // Map function values using appropriate mapping
+    // Affine map: Do nothing
+    
+    // Note that we do not map the weights (yet).
+    
+    // Take directional components
+    for(int k = 0; k < 1; k++)
+      result += values[k]*D[i][0][k];
+    // Multiply by weights
+    result *= W[i][0];
+    
+    return result;
+}
+
+/// Evaluate linear functionals for all dofs on the function f
+void magmaequations_1_finite_element_1_1::evaluate_dofs(double* values,
+                                  const ufc::function& f,
+                                  const ufc::cell& c) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Interpolate vertex values from dof values
+void magmaequations_1_finite_element_1_1::interpolate_vertex_values(double* vertex_values,
+                                              const double* dof_values,
+                                              const ufc::cell& c) const
+{
+    // Evaluate at vertices and use affine mapping
+    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)
+unsigned int magmaequations_1_finite_element_1_1::num_sub_elements() const
+{
+    return 1;
+}
+
+/// Create a new finite element for sub element i (for a mixed element)
+ufc::finite_element* magmaequations_1_finite_element_1_1::create_sub_element(unsigned int i) const
+{
+    return new magmaequations_1_finite_element_1_1();
+}
+
+
+/// Constructor
+magmaequations_1_finite_element_1::magmaequations_1_finite_element_1() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+magmaequations_1_finite_element_1::~magmaequations_1_finite_element_1()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* magmaequations_1_finite_element_1::signature() const
+{
+    return "MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)], **{'value_shape': (2,) })";
+}
+
+/// Return the cell shape
+ufc::shape magmaequations_1_finite_element_1::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int magmaequations_1_finite_element_1::space_dimension() const
+{
+    return 12;
+}
+
+/// Return the rank of the value space
+unsigned int magmaequations_1_finite_element_1::value_rank() const
+{
+    return 1;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int magmaequations_1_finite_element_1::value_dimension(unsigned int i) const
+{
+    return 2;
+}
+
+/// Evaluate basis function i at given point in cell
+void magmaequations_1_finite_element_1::evaluate_basis(unsigned int i,
+                                   double* values,
+                                   const double* coordinates,
+                                   const ufc::cell& c) const
+{
+    // Extract vertex coordinates
+    const double * const * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Reset values
+    values[0] = 0;
+    values[1] = 0;
+    
+    if (0 <= i && i <= 5)
+    {
+      // Map degree of freedom to element degree of freedom
+      const unsigned int dof = i;
+    
+      // Generate scalings
+      const double scalings_y_0 = 1;
+      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+      const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+      // Compute psitilde_a
+      const double psitilde_a_0 = 1;
+      const double psitilde_a_1 = x;
+      const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+      // Compute psitilde_bs
+      const double psitilde_bs_0_0 = 1;
+      const double psitilde_bs_0_1 = 1.5*y + 0.5;
+      const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+      const double psitilde_bs_1_0 = 1;
+      const double psitilde_bs_1_1 = 2.5*y + 1.5;
+      const double psitilde_bs_2_0 = 1;
+    
+      // Compute basisvalues
+      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+      const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+      const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+      const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+      // Table(s) of coefficients
+      static const double coefficients0[6][6] =   \
+      {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+      {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+      {0, 0, 0.2, 0, 0, 0.163299316185545},
+      {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+      {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+      {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+      // Extract relevant coefficients
+      const double coeff0_0 =   coefficients0[dof][0];
+      const double coeff0_1 =   coefficients0[dof][1];
+      const double coeff0_2 =   coefficients0[dof][2];
+      const double coeff0_3 =   coefficients0[dof][3];
+      const double coeff0_4 =   coefficients0[dof][4];
+      const double coeff0_5 =   coefficients0[dof][5];
+    
+      // Compute value(s)
+      values[0] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
+    }
+    
+    if (6 <= i && i <= 11)
+    {
+      // Map degree of freedom to element degree of freedom
+      const unsigned int dof = i - 6;
+    
+      // Generate scalings
+      const double scalings_y_0 = 1;
+      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+      const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+      // Compute psitilde_a
+      const double psitilde_a_0 = 1;
+      const double psitilde_a_1 = x;
+      const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+      // Compute psitilde_bs
+      const double psitilde_bs_0_0 = 1;
+      const double psitilde_bs_0_1 = 1.5*y + 0.5;
+      const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+      const double psitilde_bs_1_0 = 1;
+      const double psitilde_bs_1_1 = 2.5*y + 1.5;
+      const double psitilde_bs_2_0 = 1;
+    
+      // Compute basisvalues
+      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+      const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+      const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+      const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+      // Table(s) of coefficients
+      static const double coefficients0[6][6] =   \
+      {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+      {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+      {0, 0, 0.2, 0, 0, 0.163299316185545},
+      {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+      {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+      {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+      // Extract relevant coefficients
+      const double coeff0_0 =   coefficients0[dof][0];
+      const double coeff0_1 =   coefficients0[dof][1];
+      const double coeff0_2 =   coefficients0[dof][2];
+      const double coeff0_3 =   coefficients0[dof][3];
+      const double coeff0_4 =   coefficients0[dof][4];
+      const double coeff0_5 =   coefficients0[dof][5];
+    
+      // Compute value(s)
+      values[1] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
+    }
+    
+}
+
+/// Evaluate all basis functions at given point in cell
+void magmaequations_1_finite_element_1::evaluate_basis_all(double* values,
+                                       const double* coordinates,
+                                       const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
+}
+
+/// Evaluate order n derivatives of basis function i at given point in cell
+void magmaequations_1_finite_element_1::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 * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 2;
+    
+    
+    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
+    unsigned int **combinations = new unsigned int *[num_derivatives];
+    
+    for (unsigned int j = 0; j < num_derivatives; j++)
+    {
+      combinations[j] = new unsigned int [n];
+      for (unsigned int k = 0; k < n; k++)
+        combinations[j][k] = 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] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
+    
+    // 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
+    for (unsigned int j = 0; j < 2*num_derivatives; j++)
+      values[j] = 0;
+    
+    if (0 <= i && i <= 5)
+    {
+      // Map degree of freedom to element degree of freedom
+      const unsigned int dof = i;
+    
+      // Generate scalings
+      const double scalings_y_0 = 1;
+      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+      const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+      // Compute psitilde_a
+      const double psitilde_a_0 = 1;
+      const double psitilde_a_1 = x;
+      const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+      // Compute psitilde_bs
+      const double psitilde_bs_0_0 = 1;
+      const double psitilde_bs_0_1 = 1.5*y + 0.5;
+      const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+      const double psitilde_bs_1_0 = 1;
+      const double psitilde_bs_1_1 = 2.5*y + 1.5;
+      const double psitilde_bs_2_0 = 1;
+    
+      // Compute basisvalues
+      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+      const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+      const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+      const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+      // Table(s) of coefficients
+      static const double coefficients0[6][6] =   \
+      {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+      {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+      {0, 0, 0.2, 0, 0, 0.163299316185545},
+      {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+      {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+      {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+      // Interesting (new) part
+      // Tables of derivatives of the polynomial base (transpose)
+      static const double dmats0[6][6] =   \
+      {{0, 0, 0, 0, 0, 0},
+      {4.89897948556636, 0, 0, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0},
+      {0, 9.48683298050514, 0, 0, 0, 0},
+      {4, 0, 7.07106781186548, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0}};
+    
+      static const double dmats1[6][6] =   \
+      {{0, 0, 0, 0, 0, 0},
+      {2.44948974278318, 0, 0, 0, 0, 0},
+      {4.24264068711928, 0, 0, 0, 0, 0},
+      {2.58198889747161, 4.74341649025257, -0.912870929175277, 0, 0, 0},
+      {2, 6.12372435695795, 3.53553390593274, 0, 0, 0},
+      {-2.3094010767585, 0, 8.16496580927726, 0, 0, 0}};
+    
+      // Compute reference derivatives
+      // Declare pointer to array of derivatives on FIAT element
+      double *derivatives = new double [num_derivatives];
+    
+      // Declare coefficients
+      double coeff0_0 = 0;
+      double coeff0_1 = 0;
+      double coeff0_2 = 0;
+      double coeff0_3 = 0;
+      double coeff0_4 = 0;
+      double coeff0_5 = 0;
+    
+      // Declare new coefficients
+      double new_coeff0_0 = 0;
+      double new_coeff0_1 = 0;
+      double new_coeff0_2 = 0;
+      double new_coeff0_3 = 0;
+      double new_coeff0_4 = 0;
+      double new_coeff0_5 = 0;
+    
+      // Loop possible derivatives
+      for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+      {
+        // Get values from coefficients array
+        new_coeff0_0 = coefficients0[dof][0];
+        new_coeff0_1 = coefficients0[dof][1];
+        new_coeff0_2 = coefficients0[dof][2];
+        new_coeff0_3 = coefficients0[dof][3];
+        new_coeff0_4 = coefficients0[dof][4];
+        new_coeff0_5 = coefficients0[dof][5];
+    
+        // Loop derivative order
+        for (unsigned int j = 0; j < n; j++)
+        {
+          // Update old coefficients
+          coeff0_0 = new_coeff0_0;
+          coeff0_1 = new_coeff0_1;
+          coeff0_2 = new_coeff0_2;
+          coeff0_3 = new_coeff0_3;
+          coeff0_4 = new_coeff0_4;
+          coeff0_5 = new_coeff0_5;
+    
+          if(combinations[deriv_num][j] == 0)
+          {
+            new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
+            new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
+            new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
+            new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
+            new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
+            new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
+          }
+          if(combinations[deriv_num][j] == 1)
+          {
+            new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
+            new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
+            new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
+            new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
+            new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
+            new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
+          }
+    
+        }
+        // Compute derivatives on reference element as dot product of coefficients and basisvalues
+        derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
+      }
+    
+      // Transform derivatives back to physical element
+      for (unsigned int row = 0; row < num_derivatives; row++)
+      {
+        for (unsigned int col = 0; col < num_derivatives; col++)
+        {
+          values[row] += transform[row][col]*derivatives[col];
+        }
+      }
+      // Delete pointer to array of derivatives on FIAT element
+      delete [] derivatives;
+    
+      // Delete pointer to array of combinations of derivatives and transform
+      for (unsigned int row = 0; row < num_derivatives; row++)
+      {
+        delete [] combinations[row];
+        delete [] transform[row];
+      }
+    
+      delete [] combinations;
+      delete [] transform;
+    }
+    
+    if (6 <= i && i <= 11)
+    {
+      // Map degree of freedom to element degree of freedom
+      const unsigned int dof = i - 6;
+    
+      // Generate scalings
+      const double scalings_y_0 = 1;
+      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+      const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+      // Compute psitilde_a
+      const double psitilde_a_0 = 1;
+      const double psitilde_a_1 = x;
+      const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+      // Compute psitilde_bs
+      const double psitilde_bs_0_0 = 1;
+      const double psitilde_bs_0_1 = 1.5*y + 0.5;
+      const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+      const double psitilde_bs_1_0 = 1;
+      const double psitilde_bs_1_1 = 2.5*y + 1.5;
+      const double psitilde_bs_2_0 = 1;
+    
+      // Compute basisvalues
+      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+      const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+      const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+      const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+      // Table(s) of coefficients
+      static const double coefficients0[6][6] =   \
+      {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+      {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+      {0, 0, 0.2, 0, 0, 0.163299316185545},
+      {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+      {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+      {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+      // Interesting (new) part
+      // Tables of derivatives of the polynomial base (transpose)
+      static const double dmats0[6][6] =   \
+      {{0, 0, 0, 0, 0, 0},
+      {4.89897948556636, 0, 0, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0},
+      {0, 9.48683298050514, 0, 0, 0, 0},
+      {4, 0, 7.07106781186548, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0}};
+    
+      static const double dmats1[6][6] =   \
+      {{0, 0, 0, 0, 0, 0},
+      {2.44948974278318, 0, 0, 0, 0, 0},
+      {4.24264068711928, 0, 0, 0, 0, 0},
+      {2.58198889747161, 4.74341649025257, -0.912870929175277, 0, 0, 0},
+      {2, 6.12372435695795, 3.53553390593274, 0, 0, 0},
+      {-2.3094010767585, 0, 8.16496580927726, 0, 0, 0}};
+    
+      // Compute reference derivatives
+      // Declare pointer to array of derivatives on FIAT element
+      double *derivatives = new double [num_derivatives];
+    
+      // Declare coefficients
+      double coeff0_0 = 0;
+      double coeff0_1 = 0;
+      double coeff0_2 = 0;
+      double coeff0_3 = 0;
+      double coeff0_4 = 0;
+      double coeff0_5 = 0;
+    
+      // Declare new coefficients
+      double new_coeff0_0 = 0;
+      double new_coeff0_1 = 0;
+      double new_coeff0_2 = 0;
+      double new_coeff0_3 = 0;
+      double new_coeff0_4 = 0;
+      double new_coeff0_5 = 0;
+    
+      // Loop possible derivatives
+      for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+      {
+        // Get values from coefficients array
+        new_coeff0_0 = coefficients0[dof][0];
+        new_coeff0_1 = coefficients0[dof][1];
+        new_coeff0_2 = coefficients0[dof][2];
+        new_coeff0_3 = coefficients0[dof][3];
+        new_coeff0_4 = coefficients0[dof][4];
+        new_coeff0_5 = coefficients0[dof][5];
+    
+        // Loop derivative order
+        for (unsigned int j = 0; j < n; j++)
+        {
+          // Update old coefficients
+          coeff0_0 = new_coeff0_0;
+          coeff0_1 = new_coeff0_1;
+          coeff0_2 = new_coeff0_2;
+          coeff0_3 = new_coeff0_3;
+          coeff0_4 = new_coeff0_4;
+          coeff0_5 = new_coeff0_5;
+    
+          if(combinations[deriv_num][j] == 0)
+          {
+            new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
+            new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
+            new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
+            new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
+            new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
+            new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
+          }
+          if(combinations[deriv_num][j] == 1)
+          {
+            new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
+            new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
+            new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
+            new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
+            new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
+            new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
+          }
+    
+        }
+        // Compute derivatives on reference element as dot product of coefficients and basisvalues
+        derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
+      }
+    
+      // Transform derivatives back to physical element
+      for (unsigned int row = 0; row < num_derivatives; row++)
+      {
+        for (unsigned int col = 0; col < num_derivatives; col++)
+        {
+          values[num_derivatives + row] += transform[row][col]*derivatives[col];
+        }
+      }
+      // Delete pointer to array of derivatives on FIAT element
+      delete [] derivatives;
+    
+      // Delete pointer to array of combinations of derivatives and transform
+      for (unsigned int row = 0; row < num_derivatives; row++)
+      {
+        delete [] combinations[row];
+        delete [] transform[row];
+      }
+    
+      delete [] combinations;
+      delete [] transform;
+    }
+    
+}
+
+/// Evaluate order n derivatives of all basis functions at given point in cell
+void magmaequations_1_finite_element_1::evaluate_basis_derivatives_all(unsigned int n,
+                                                   double* values,
+                                                   const double* coordinates,
+                                                   const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
+}
+
+/// Evaluate linear functional for dof i on the function f
+double magmaequations_1_finite_element_1::evaluate_dof(unsigned int i,
+                                   const ufc::function& f,
+                                   const ufc::cell& c) const
+{
+    // The reference points, direction and weights:
+    static const double X[12][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}, {{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}};
+    static const double W[12][1] = {{1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}};
+    static const double D[12][1][2] = {{{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{0, 1}}, {{0, 1}}, {{0, 1}}, {{0, 1}}, {{0, 1}}, {{0, 1}}};
+    
+    const double * const * x = c.coordinates;
+    double result = 0.0;
+    // Iterate over the points:
+    // Evaluate basis functions for affine mapping
+    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    
+    // Compute affine mapping y = F(X)
+    double y[2];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
+    
+    // Evaluate function at physical points
+    double values[2];
+    f.evaluate(values, y, c);
+    
+    // Map function values using appropriate mapping
+    // Affine map: Do nothing
+    
+    // Note that we do not map the weights (yet).
+    
+    // Take directional components
+    for(int k = 0; k < 2; k++)
+      result += values[k]*D[i][0][k];
+    // Multiply by weights
+    result *= W[i][0];
+    
+    return result;
+}
+
+/// Evaluate linear functionals for all dofs on the function f
+void magmaequations_1_finite_element_1::evaluate_dofs(double* values,
+                                  const ufc::function& f,
+                                  const ufc::cell& c) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Interpolate vertex values from dof values
+void magmaequations_1_finite_element_1::interpolate_vertex_values(double* vertex_values,
+                                              const double* dof_values,
+                                              const ufc::cell& c) const
+{
+    // Evaluate at vertices and use affine mapping
+    vertex_values[0] = dof_values[0];
+    vertex_values[2] = dof_values[1];
+    vertex_values[4] = dof_values[2];
+    // Evaluate at vertices and use affine mapping
+    vertex_values[1] = dof_values[6];
+    vertex_values[3] = dof_values[7];
+    vertex_values[5] = dof_values[8];
+}
+
+/// Return the number of sub elements (for a mixed element)
+unsigned int magmaequations_1_finite_element_1::num_sub_elements() const
+{
+    return 2;
+}
+
+/// Create a new finite element for sub element i (for a mixed element)
+ufc::finite_element* magmaequations_1_finite_element_1::create_sub_element(unsigned int i) const
+{
+    switch ( i )
+    {
+    case 0:
+      return new magmaequations_1_finite_element_1_0();
+      break;
+    case 1:
+      return new magmaequations_1_finite_element_1_1();
+      break;
+    }
+    return 0;
+}
+
+
+/// Constructor
+magmaequations_1_finite_element_2::magmaequations_1_finite_element_2() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+magmaequations_1_finite_element_2::~magmaequations_1_finite_element_2()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* magmaequations_1_finite_element_2::signature() const
+{
+    return "FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 0)";
+}
+
+/// Return the cell shape
+ufc::shape magmaequations_1_finite_element_2::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int magmaequations_1_finite_element_2::space_dimension() const
+{
+    return 1;
+}
+
+/// Return the rank of the value space
+unsigned int magmaequations_1_finite_element_2::value_rank() const
+{
+    return 0;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int magmaequations_1_finite_element_2::value_dimension(unsigned int i) const
+{
+    return 1;
+}
+
+/// Evaluate basis function i at given point in cell
+void magmaequations_1_finite_element_2::evaluate_basis(unsigned int i,
+                                   double* values,
+                                   const double* coordinates,
+                                   const ufc::cell& c) const
+{
+    // Extract vertex coordinates
+    const double * const * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Reset values
+    *values = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[1][1] = \
+    {{1.41421356237309}};
+    
+    // Extract relevant coefficients
+    const double coeff0_0 = coefficients0[dof][0];
+    
+    // Compute value(s)
+    *values = coeff0_0*basisvalue0;
+}
+
+/// Evaluate all basis functions at given point in cell
+void magmaequations_1_finite_element_2::evaluate_basis_all(double* values,
+                                       const double* coordinates,
+                                       const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
+}
+
+/// Evaluate order n derivatives of basis function i at given point in cell
+void magmaequations_1_finite_element_2::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 * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 2;
+    
+    
+    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
+    unsigned int **combinations = new unsigned int *[num_derivatives];
+    
+    for (unsigned int j = 0; j < num_derivatives; j++)
+    {
+      combinations[j] = new unsigned int [n];
+      for (unsigned int k = 0; k < n; k++)
+        combinations[j][k] = 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] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
+    
+    // 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
+    for (unsigned int j = 0; j < 1*num_derivatives; j++)
+      values[j] = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[1][1] = \
+    {{1.41421356237309}};
+    
+    // Interesting (new) part
+    // Tables of derivatives of the polynomial base (transpose)
+    static const double dmats0[1][1] = \
+    {{0}};
+    
+    static const double dmats1[1][1] = \
+    {{0}};
+    
+    // Compute reference derivatives
+    // Declare pointer to array of derivatives on FIAT element
+    double *derivatives = new double [num_derivatives];
+    
+    // Declare coefficients
+    double coeff0_0 = 0;
+    
+    // Declare new coefficients
+    double new_coeff0_0 = 0;
+    
+    // Loop possible derivatives
+    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+    {
+      // Get values from coefficients array
+      new_coeff0_0 = coefficients0[dof][0];
+    
+      // Loop derivative order
+      for (unsigned int j = 0; j < n; j++)
+      {
+        // Update old coefficients
+        coeff0_0 = new_coeff0_0;
+    
+        if(combinations[deriv_num][j] == 0)
+        {
+          new_coeff0_0 = coeff0_0*dmats0[0][0];
+        }
+        if(combinations[deriv_num][j] == 1)
+        {
+          new_coeff0_0 = coeff0_0*dmats1[0][0];
+        }
+    
+      }
+      // Compute derivatives on reference element as dot product of coefficients and basisvalues
+      derivatives[deriv_num] = new_coeff0_0*basisvalue0;
+    }
+    
+    // Transform derivatives back to physical element
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      for (unsigned int col = 0; col < num_derivatives; col++)
+      {
+        values[row] += transform[row][col]*derivatives[col];
+      }
+    }
+    // Delete pointer to array of derivatives on FIAT element
+    delete [] derivatives;
+    
+    // Delete pointer to array of combinations of derivatives and transform
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      delete [] combinations[row];
+      delete [] transform[row];
+    }
+    
+    delete [] combinations;
+    delete [] transform;
+}
+
+/// Evaluate order n derivatives of all basis functions at given point in cell
+void magmaequations_1_finite_element_2::evaluate_basis_derivatives_all(unsigned int n,
+                                                   double* values,
+                                                   const double* coordinates,
+                                                   const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
+}
+
+/// Evaluate linear functional for dof i on the function f
+double magmaequations_1_finite_element_2::evaluate_dof(unsigned int i,
+                                   const ufc::function& f,
+                                   const ufc::cell& c) const
+{
+    // The reference points, direction and weights:
+    static const double X[1][1][2] = {{{0.333333333333333, 0.333333333333333}}};
+    static const double W[1][1] = {{1}};
+    static const double D[1][1][1] = {{{1}}};
+    
+    const double * const * x = c.coordinates;
+    double result = 0.0;
+    // Iterate over the points:
+    // Evaluate basis functions for affine mapping
+    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    
+    // Compute affine mapping y = F(X)
+    double y[2];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
+    
+    // Evaluate function at physical points
+    double values[1];
+    f.evaluate(values, y, c);
+    
+    // Map function values using appropriate mapping
+    // Affine map: Do nothing
+    
+    // Note that we do not map the weights (yet).
+    
+    // Take directional components
+    for(int k = 0; k < 1; k++)
+      result += values[k]*D[i][0][k];
+    // Multiply by weights
+    result *= W[i][0];
+    
+    return result;
+}
+
+/// Evaluate linear functionals for all dofs on the function f
+void magmaequations_1_finite_element_2::evaluate_dofs(double* values,
+                                  const ufc::function& f,
+                                  const ufc::cell& c) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Interpolate vertex values from dof values
+void magmaequations_1_finite_element_2::interpolate_vertex_values(double* vertex_values,
+                                              const double* dof_values,
+                                              const ufc::cell& c) const
+{
+    // Evaluate at vertices and use affine mapping
+    vertex_values[0] = dof_values[0];
+    vertex_values[1] = dof_values[0];
+    vertex_values[2] = dof_values[0];
+}
+
+/// Return the number of sub elements (for a mixed element)
+unsigned int magmaequations_1_finite_element_2::num_sub_elements() const
+{
+    return 1;
+}
+
+/// Create a new finite element for sub element i (for a mixed element)
+ufc::finite_element* magmaequations_1_finite_element_2::create_sub_element(unsigned int i) const
+{
+    return new magmaequations_1_finite_element_2();
+}
+
+
+/// Constructor
+magmaequations_1_finite_element_3::magmaequations_1_finite_element_3() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+magmaequations_1_finite_element_3::~magmaequations_1_finite_element_3()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* magmaequations_1_finite_element_3::signature() const
+{
+    return "FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 0)";
+}
+
+/// Return the cell shape
+ufc::shape magmaequations_1_finite_element_3::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int magmaequations_1_finite_element_3::space_dimension() const
+{
+    return 1;
+}
+
+/// Return the rank of the value space
+unsigned int magmaequations_1_finite_element_3::value_rank() const
+{
+    return 0;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int magmaequations_1_finite_element_3::value_dimension(unsigned int i) const
+{
+    return 1;
+}
+
+/// Evaluate basis function i at given point in cell
+void magmaequations_1_finite_element_3::evaluate_basis(unsigned int i,
+                                   double* values,
+                                   const double* coordinates,
+                                   const ufc::cell& c) const
+{
+    // Extract vertex coordinates
+    const double * const * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Reset values
+    *values = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[1][1] = \
+    {{1.41421356237309}};
+    
+    // Extract relevant coefficients
+    const double coeff0_0 = coefficients0[dof][0];
+    
+    // Compute value(s)
+    *values = coeff0_0*basisvalue0;
+}
+
+/// Evaluate all basis functions at given point in cell
+void magmaequations_1_finite_element_3::evaluate_basis_all(double* values,
+                                       const double* coordinates,
+                                       const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
+}
+
+/// Evaluate order n derivatives of basis function i at given point in cell
+void magmaequations_1_finite_element_3::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 * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 2;
+    
+    
+    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
+    unsigned int **combinations = new unsigned int *[num_derivatives];
+    
+    for (unsigned int j = 0; j < num_derivatives; j++)
+    {
+      combinations[j] = new unsigned int [n];
+      for (unsigned int k = 0; k < n; k++)
+        combinations[j][k] = 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] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
+    
+    // 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
+    for (unsigned int j = 0; j < 1*num_derivatives; j++)
+      values[j] = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[1][1] = \
+    {{1.41421356237309}};
+    
+    // Interesting (new) part
+    // Tables of derivatives of the polynomial base (transpose)
+    static const double dmats0[1][1] = \
+    {{0}};
+    
+    static const double dmats1[1][1] = \
+    {{0}};
+    
+    // Compute reference derivatives
+    // Declare pointer to array of derivatives on FIAT element
+    double *derivatives = new double [num_derivatives];
+    
+    // Declare coefficients
+    double coeff0_0 = 0;
+    
+    // Declare new coefficients
+    double new_coeff0_0 = 0;
+    
+    // Loop possible derivatives
+    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+    {
+      // Get values from coefficients array
+      new_coeff0_0 = coefficients0[dof][0];
+    
+      // Loop derivative order
+      for (unsigned int j = 0; j < n; j++)
+      {
+        // Update old coefficients
+        coeff0_0 = new_coeff0_0;
+    
+        if(combinations[deriv_num][j] == 0)
+        {
+          new_coeff0_0 = coeff0_0*dmats0[0][0];
+        }
+        if(combinations[deriv_num][j] == 1)
+        {
+          new_coeff0_0 = coeff0_0*dmats1[0][0];
+        }
+    
+      }
+      // Compute derivatives on reference element as dot product of coefficients and basisvalues
+      derivatives[deriv_num] = new_coeff0_0*basisvalue0;
+    }
+    
+    // Transform derivatives back to physical element
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      for (unsigned int col = 0; col < num_derivatives; col++)
+      {
+        values[row] += transform[row][col]*derivatives[col];
+      }
+    }
+    // Delete pointer to array of derivatives on FIAT element
+    delete [] derivatives;
+    
+    // Delete pointer to array of combinations of derivatives and transform
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      delete [] combinations[row];
+      delete [] transform[row];
+    }
+    
+    delete [] combinations;
+    delete [] transform;
+}
+
+/// Evaluate order n derivatives of all basis functions at given point in cell
+void magmaequations_1_finite_element_3::evaluate_basis_derivatives_all(unsigned int n,
+                                                   double* values,
+                                                   const double* coordinates,
+                                                   const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
+}
+
+/// Evaluate linear functional for dof i on the function f
+double magmaequations_1_finite_element_3::evaluate_dof(unsigned int i,
+                                   const ufc::function& f,
+                                   const ufc::cell& c) const
+{
+    // The reference points, direction and weights:
+    static const double X[1][1][2] = {{{0.333333333333333, 0.333333333333333}}};
+    static const double W[1][1] = {{1}};
+    static const double D[1][1][1] = {{{1}}};
+    
+    const double * const * x = c.coordinates;
+    double result = 0.0;
+    // Iterate over the points:
+    // Evaluate basis functions for affine mapping
+    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    
+    // Compute affine mapping y = F(X)
+    double y[2];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
+    
+    // Evaluate function at physical points
+    double values[1];
+    f.evaluate(values, y, c);
+    
+    // Map function values using appropriate mapping
+    // Affine map: Do nothing
+    
+    // Note that we do not map the weights (yet).
+    
+    // Take directional components
+    for(int k = 0; k < 1; k++)
+      result += values[k]*D[i][0][k];
+    // Multiply by weights
+    result *= W[i][0];
+    
+    return result;
+}
+
+/// Evaluate linear functionals for all dofs on the function f
+void magmaequations_1_finite_element_3::evaluate_dofs(double* values,
+                                  const ufc::function& f,
+                                  const ufc::cell& c) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Interpolate vertex values from dof values
+void magmaequations_1_finite_element_3::interpolate_vertex_values(double* vertex_values,
+                                              const double* dof_values,
+                                              const ufc::cell& c) const
+{
+    // Evaluate at vertices and use affine mapping
+    vertex_values[0] = dof_values[0];
+    vertex_values[1] = dof_values[0];
+    vertex_values[2] = dof_values[0];
+}
+
+/// Return the number of sub elements (for a mixed element)
+unsigned int magmaequations_1_finite_element_3::num_sub_elements() const
+{
+    return 1;
+}
+
+/// Create a new finite element for sub element i (for a mixed element)
+ufc::finite_element* magmaequations_1_finite_element_3::create_sub_element(unsigned int i) const
+{
+    return new magmaequations_1_finite_element_3();
+}
+
+
+/// Constructor
+magmaequations_1_finite_element_4::magmaequations_1_finite_element_4() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+magmaequations_1_finite_element_4::~magmaequations_1_finite_element_4()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* magmaequations_1_finite_element_4::signature() const
+{
+    return "FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)";
+}
+
+/// Return the cell shape
+ufc::shape magmaequations_1_finite_element_4::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int magmaequations_1_finite_element_4::space_dimension() const
+{
+    return 3;
+}
+
+/// Return the rank of the value space
+unsigned int magmaequations_1_finite_element_4::value_rank() const
+{
+    return 0;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int magmaequations_1_finite_element_4::value_dimension(unsigned int i) const
+{
+    return 1;
+}
+
+/// Evaluate basis function i at given point in cell
+void magmaequations_1_finite_element_4::evaluate_basis(unsigned int i,
+                                   double* values,
+                                   const double* coordinates,
+                                   const ufc::cell& c) const
+{
+    // Extract vertex coordinates
+    const double * const * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Reset values
+    *values = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_1_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    
+    // 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, 0.333333333333333}};
+    
+    // Extract relevant coefficients
+    const double coeff0_0 = coefficients0[dof][0];
+    const double coeff0_1 = coefficients0[dof][1];
+    const double coeff0_2 = coefficients0[dof][2];
+    
+    // Compute value(s)
+    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
+}
+
+/// Evaluate all basis functions at given point in cell
+void magmaequations_1_finite_element_4::evaluate_basis_all(double* values,
+                                       const double* coordinates,
+                                       const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
+}
+
+/// Evaluate order n derivatives of basis function i at given point in cell
+void magmaequations_1_finite_element_4::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 * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 2;
+    
+    
+    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
+    unsigned int **combinations = new unsigned int *[num_derivatives];
+    
+    for (unsigned int j = 0; j < num_derivatives; j++)
+    {
+      combinations[j] = new unsigned int [n];
+      for (unsigned int k = 0; k < n; k++)
+        combinations[j][k] = 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] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
+    
+    // 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
+    for (unsigned int j = 0; j < 1*num_derivatives; j++)
+      values[j] = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_1_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    
+    // 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, 0.333333333333333}};
+    
+    // Interesting (new) part
+    // Tables of derivatives of the polynomial base (transpose)
+    static const double dmats0[3][3] = \
+    {{0, 0, 0},
+    {4.89897948556636, 0, 0},
+    {0, 0, 0}};
+    
+    static const double dmats1[3][3] = \
+    {{0, 0, 0},
+    {2.44948974278318, 0, 0},
+    {4.24264068711928, 0, 0}};
+    
+    // Compute reference derivatives
+    // Declare pointer to array of derivatives on FIAT element
+    double *derivatives = new double [num_derivatives];
+    
+    // Declare coefficients
+    double coeff0_0 = 0;
+    double coeff0_1 = 0;
+    double coeff0_2 = 0;
+    
+    // Declare new coefficients
+    double new_coeff0_0 = 0;
+    double new_coeff0_1 = 0;
+    double new_coeff0_2 = 0;
+    
+    // Loop possible derivatives
+    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+    {
+      // Get values from coefficients array
+      new_coeff0_0 = coefficients0[dof][0];
+      new_coeff0_1 = coefficients0[dof][1];
+      new_coeff0_2 = coefficients0[dof][2];
+    
+      // Loop derivative order
+      for (unsigned int j = 0; j < n; j++)
+      {
+        // Update old coefficients
+        coeff0_0 = new_coeff0_0;
+        coeff0_1 = new_coeff0_1;
+        coeff0_2 = new_coeff0_2;
+    
+        if(combinations[deriv_num][j] == 0)
+        {
+          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
+          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
+          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
+        }
+        if(combinations[deriv_num][j] == 1)
+        {
+          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
+          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
+          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
+        }
+    
+      }
+      // Compute derivatives on reference element as dot product of coefficients and basisvalues
+      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
+    }
+    
+    // Transform derivatives back to physical element
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      for (unsigned int col = 0; col < num_derivatives; col++)
+      {
+        values[row] += transform[row][col]*derivatives[col];
+      }
+    }
+    // Delete pointer to array of derivatives on FIAT element
+    delete [] derivatives;
+    
+    // Delete pointer to array of combinations of derivatives and transform
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      delete [] combinations[row];
+      delete [] transform[row];
+    }
+    
+    delete [] combinations;
+    delete [] transform;
+}
+
+/// Evaluate order n derivatives of all basis functions at given point in cell
+void magmaequations_1_finite_element_4::evaluate_basis_derivatives_all(unsigned int n,
+                                                   double* values,
+                                                   const double* coordinates,
+                                                   const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
+}
+
+/// Evaluate linear functional for dof i on the function f
+double magmaequations_1_finite_element_4::evaluate_dof(unsigned int i,
+                                   const ufc::function& f,
+                                   const ufc::cell& c) const
+{
+    // The reference points, direction and weights:
+    static const double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
+    static const double W[3][1] = {{1}, {1}, {1}};
+    static const double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
+    
+    const double * const * x = c.coordinates;
+    double result = 0.0;
+    // Iterate over the points:
+    // Evaluate basis functions for affine mapping
+    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    
+    // Compute affine mapping y = F(X)
+    double y[2];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
+    
+    // Evaluate function at physical points
+    double values[1];
+    f.evaluate(values, y, c);
+    
+    // Map function values using appropriate mapping
+    // Affine map: Do nothing
+    
+    // Note that we do not map the weights (yet).
+    
+    // Take directional components
+    for(int k = 0; k < 1; k++)
+      result += values[k]*D[i][0][k];
+    // Multiply by weights
+    result *= W[i][0];
+    
+    return result;
+}
+
+/// Evaluate linear functionals for all dofs on the function f
+void magmaequations_1_finite_element_4::evaluate_dofs(double* values,
+                                  const ufc::function& f,
+                                  const ufc::cell& c) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Interpolate vertex values from dof values
+void magmaequations_1_finite_element_4::interpolate_vertex_values(double* vertex_values,
+                                              const double* dof_values,
+                                              const ufc::cell& c) const
+{
+    // Evaluate at vertices and use affine mapping
+    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)
+unsigned int magmaequations_1_finite_element_4::num_sub_elements() const
+{
+    return 1;
+}
+
+/// Create a new finite element for sub element i (for a mixed element)
+ufc::finite_element* magmaequations_1_finite_element_4::create_sub_element(unsigned int i) const
+{
+    return new magmaequations_1_finite_element_4();
+}
+
+
+/// Constructor
+magmaequations_1_finite_element_5::magmaequations_1_finite_element_5() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+magmaequations_1_finite_element_5::~magmaequations_1_finite_element_5()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* magmaequations_1_finite_element_5::signature() const
+{
+    return "FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
+}
+
+/// Return the cell shape
+ufc::shape magmaequations_1_finite_element_5::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int magmaequations_1_finite_element_5::space_dimension() const
+{
+    return 6;
+}
+
+/// Return the rank of the value space
+unsigned int magmaequations_1_finite_element_5::value_rank() const
+{
+    return 0;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int magmaequations_1_finite_element_5::value_dimension(unsigned int i) const
+{
+    return 1;
+}
+
+/// Evaluate basis function i at given point in cell
+void magmaequations_1_finite_element_5::evaluate_basis(unsigned int i,
+                                   double* values,
+                                   const double* coordinates,
+                                   const ufc::cell& c) const
+{
+    // Extract vertex coordinates
+    const double * const * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Reset values
+    *values = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+    const double psitilde_bs_1_0 = 1;
+    const double psitilde_bs_1_1 = 2.5*y + 1.5;
+    const double psitilde_bs_2_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+    const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+    const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[6][6] = \
+    {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+    {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+    {0, 0, 0.2, 0, 0, 0.163299316185545},
+    {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+    {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+    {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+    // Extract relevant coefficients
+    const double coeff0_0 = coefficients0[dof][0];
+    const double coeff0_1 = coefficients0[dof][1];
+    const double coeff0_2 = coefficients0[dof][2];
+    const double coeff0_3 = coefficients0[dof][3];
+    const double coeff0_4 = coefficients0[dof][4];
+    const double coeff0_5 = coefficients0[dof][5];
+    
+    // Compute value(s)
+    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
+}
+
+/// Evaluate all basis functions at given point in cell
+void magmaequations_1_finite_element_5::evaluate_basis_all(double* values,
+                                       const double* coordinates,
+                                       const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
+}
+
+/// Evaluate order n derivatives of basis function i at given point in cell
+void magmaequations_1_finite_element_5::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 * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 2;
+    
+    
+    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
+    unsigned int **combinations = new unsigned int *[num_derivatives];
+    
+    for (unsigned int j = 0; j < num_derivatives; j++)
+    {
+      combinations[j] = new unsigned int [n];
+      for (unsigned int k = 0; k < n; k++)
+        combinations[j][k] = 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] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
+    
+    // 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
+    for (unsigned int j = 0; j < 1*num_derivatives; j++)
+      values[j] = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+    const double psitilde_bs_1_0 = 1;
+    const double psitilde_bs_1_1 = 2.5*y + 1.5;
+    const double psitilde_bs_2_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+    const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+    const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[6][6] = \
+    {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+    {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+    {0, 0, 0.2, 0, 0, 0.163299316185545},
+    {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+    {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+    {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+    // Interesting (new) part
+    // Tables of derivatives of the polynomial base (transpose)
+    static const double dmats0[6][6] = \
+    {{0, 0, 0, 0, 0, 0},
+    {4.89897948556636, 0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0},
+    {0, 9.48683298050514, 0, 0, 0, 0},
+    {4, 0, 7.07106781186548, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0}};
+    
+    static const double dmats1[6][6] = \
+    {{0, 0, 0, 0, 0, 0},
+    {2.44948974278318, 0, 0, 0, 0, 0},
+    {4.24264068711928, 0, 0, 0, 0, 0},
+    {2.58198889747161, 4.74341649025257, -0.912870929175277, 0, 0, 0},
+    {2, 6.12372435695795, 3.53553390593274, 0, 0, 0},
+    {-2.3094010767585, 0, 8.16496580927726, 0, 0, 0}};
+    
+    // Compute reference derivatives
+    // Declare pointer to array of derivatives on FIAT element
+    double *derivatives = new double [num_derivatives];
+    
+    // Declare coefficients
+    double coeff0_0 = 0;
+    double coeff0_1 = 0;
+    double coeff0_2 = 0;
+    double coeff0_3 = 0;
+    double coeff0_4 = 0;
+    double coeff0_5 = 0;
+    
+    // Declare new coefficients
+    double new_coeff0_0 = 0;
+    double new_coeff0_1 = 0;
+    double new_coeff0_2 = 0;
+    double new_coeff0_3 = 0;
+    double new_coeff0_4 = 0;
+    double new_coeff0_5 = 0;
+    
+    // Loop possible derivatives
+    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+    {
+      // Get values from coefficients array
+      new_coeff0_0 = coefficients0[dof][0];
+      new_coeff0_1 = coefficients0[dof][1];
+      new_coeff0_2 = coefficients0[dof][2];
+      new_coeff0_3 = coefficients0[dof][3];
+      new_coeff0_4 = coefficients0[dof][4];
+      new_coeff0_5 = coefficients0[dof][5];
+    
+      // Loop derivative order
+      for (unsigned int j = 0; j < n; j++)
+      {
+        // Update old coefficients
+        coeff0_0 = new_coeff0_0;
+        coeff0_1 = new_coeff0_1;
+        coeff0_2 = new_coeff0_2;
+        coeff0_3 = new_coeff0_3;
+        coeff0_4 = new_coeff0_4;
+        coeff0_5 = new_coeff0_5;
+    
+        if(combinations[deriv_num][j] == 0)
+        {
+          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
+          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
+          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
+          new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
+          new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
+          new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
+        }
+        if(combinations[deriv_num][j] == 1)
+        {
+          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
+          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
+          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
+          new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
+          new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
+          new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
+        }
+    
+      }
+      // Compute derivatives on reference element as dot product of coefficients and basisvalues
+      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
+    }
+    
+    // Transform derivatives back to physical element
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      for (unsigned int col = 0; col < num_derivatives; col++)
+      {
+        values[row] += transform[row][col]*derivatives[col];
+      }
+    }
+    // Delete pointer to array of derivatives on FIAT element
+    delete [] derivatives;
+    
+    // Delete pointer to array of combinations of derivatives and transform
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      delete [] combinations[row];
+      delete [] transform[row];
+    }
+    
+    delete [] combinations;
+    delete [] transform;
+}
+
+/// Evaluate order n derivatives of all basis functions at given point in cell
+void magmaequations_1_finite_element_5::evaluate_basis_derivatives_all(unsigned int n,
+                                                   double* values,
+                                                   const double* coordinates,
+                                                   const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
+}
+
+/// Evaluate linear functional for dof i on the function f
+double magmaequations_1_finite_element_5::evaluate_dof(unsigned int i,
+                                   const ufc::function& f,
+                                   const ufc::cell& c) const
+{
+    // The reference points, direction and weights:
+    static const double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}};
+    static const double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
+    static const double D[6][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}, {{1}}, {{1}}};
+    
+    const double * const * x = c.coordinates;
+    double result = 0.0;
+    // Iterate over the points:
+    // Evaluate basis functions for affine mapping
+    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    
+    // Compute affine mapping y = F(X)
+    double y[2];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
+    
+    // Evaluate function at physical points
+    double values[1];
+    f.evaluate(values, y, c);
+    
+    // Map function values using appropriate mapping
+    // Affine map: Do nothing
+    
+    // Note that we do not map the weights (yet).
+    
+    // Take directional components
+    for(int k = 0; k < 1; k++)
+      result += values[k]*D[i][0][k];
+    // Multiply by weights
+    result *= W[i][0];
+    
+    return result;
+}
+
+/// Evaluate linear functionals for all dofs on the function f
+void magmaequations_1_finite_element_5::evaluate_dofs(double* values,
+                                  const ufc::function& f,
+                                  const ufc::cell& c) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Interpolate vertex values from dof values
+void magmaequations_1_finite_element_5::interpolate_vertex_values(double* vertex_values,
+                                              const double* dof_values,
+                                              const ufc::cell& c) const
+{
+    // Evaluate at vertices and use affine mapping
+    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)
+unsigned int magmaequations_1_finite_element_5::num_sub_elements() const
+{
+    return 1;
+}
+
+/// Create a new finite element for sub element i (for a mixed element)
+ufc::finite_element* magmaequations_1_finite_element_5::create_sub_element(unsigned int i) const
+{
+    return new magmaequations_1_finite_element_5();
+}
+
+
+/// Constructor
+magmaequations_1_finite_element_6::magmaequations_1_finite_element_6() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+magmaequations_1_finite_element_6::~magmaequations_1_finite_element_6()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* magmaequations_1_finite_element_6::signature() const
+{
+    return "FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)";
+}
+
+/// Return the cell shape
+ufc::shape magmaequations_1_finite_element_6::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int magmaequations_1_finite_element_6::space_dimension() const
+{
+    return 3;
+}
+
+/// Return the rank of the value space
+unsigned int magmaequations_1_finite_element_6::value_rank() const
+{
+    return 0;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int magmaequations_1_finite_element_6::value_dimension(unsigned int i) const
+{
+    return 1;
+}
+
+/// Evaluate basis function i at given point in cell
+void magmaequations_1_finite_element_6::evaluate_basis(unsigned int i,
+                                   double* values,
+                                   const double* coordinates,
+                                   const ufc::cell& c) const
+{
+    // Extract vertex coordinates
+    const double * const * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Reset values
+    *values = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_1_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    
+    // 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, 0.333333333333333}};
+    
+    // Extract relevant coefficients
+    const double coeff0_0 = coefficients0[dof][0];
+    const double coeff0_1 = coefficients0[dof][1];
+    const double coeff0_2 = coefficients0[dof][2];
+    
+    // Compute value(s)
+    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
+}
+
+/// Evaluate all basis functions at given point in cell
+void magmaequations_1_finite_element_6::evaluate_basis_all(double* values,
+                                       const double* coordinates,
+                                       const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
+}
+
+/// Evaluate order n derivatives of basis function i at given point in cell
+void magmaequations_1_finite_element_6::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 * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 2;
+    
+    
+    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
+    unsigned int **combinations = new unsigned int *[num_derivatives];
+    
+    for (unsigned int j = 0; j < num_derivatives; j++)
+    {
+      combinations[j] = new unsigned int [n];
+      for (unsigned int k = 0; k < n; k++)
+        combinations[j][k] = 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] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
+    
+    // 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
+    for (unsigned int j = 0; j < 1*num_derivatives; j++)
+      values[j] = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_1_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    
+    // 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, 0.333333333333333}};
+    
+    // Interesting (new) part
+    // Tables of derivatives of the polynomial base (transpose)
+    static const double dmats0[3][3] = \
+    {{0, 0, 0},
+    {4.89897948556636, 0, 0},
+    {0, 0, 0}};
+    
+    static const double dmats1[3][3] = \
+    {{0, 0, 0},
+    {2.44948974278318, 0, 0},
+    {4.24264068711928, 0, 0}};
+    
+    // Compute reference derivatives
+    // Declare pointer to array of derivatives on FIAT element
+    double *derivatives = new double [num_derivatives];
+    
+    // Declare coefficients
+    double coeff0_0 = 0;
+    double coeff0_1 = 0;
+    double coeff0_2 = 0;
+    
+    // Declare new coefficients
+    double new_coeff0_0 = 0;
+    double new_coeff0_1 = 0;
+    double new_coeff0_2 = 0;
+    
+    // Loop possible derivatives
+    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+    {
+      // Get values from coefficients array
+      new_coeff0_0 = coefficients0[dof][0];
+      new_coeff0_1 = coefficients0[dof][1];
+      new_coeff0_2 = coefficients0[dof][2];
+    
+      // Loop derivative order
+      for (unsigned int j = 0; j < n; j++)
+      {
+        // Update old coefficients
+        coeff0_0 = new_coeff0_0;
+        coeff0_1 = new_coeff0_1;
+        coeff0_2 = new_coeff0_2;
+    
+        if(combinations[deriv_num][j] == 0)
+        {
+          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
+          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
+          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
+        }
+        if(combinations[deriv_num][j] == 1)
+        {
+          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
+          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
+          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
+        }
+    
+      }
+      // Compute derivatives on reference element as dot product of coefficients and basisvalues
+      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
+    }
+    
+    // Transform derivatives back to physical element
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      for (unsigned int col = 0; col < num_derivatives; col++)
+      {
+        values[row] += transform[row][col]*derivatives[col];
+      }
+    }
+    // Delete pointer to array of derivatives on FIAT element
+    delete [] derivatives;
+    
+    // Delete pointer to array of combinations of derivatives and transform
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      delete [] combinations[row];
+      delete [] transform[row];
+    }
+    
+    delete [] combinations;
+    delete [] transform;
+}
+
+/// Evaluate order n derivatives of all basis functions at given point in cell
+void magmaequations_1_finite_element_6::evaluate_basis_derivatives_all(unsigned int n,
+                                                   double* values,
+                                                   const double* coordinates,
+                                                   const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
+}
+
+/// Evaluate linear functional for dof i on the function f
+double magmaequations_1_finite_element_6::evaluate_dof(unsigned int i,
+                                   const ufc::function& f,
+                                   const ufc::cell& c) const
+{
+    // The reference points, direction and weights:
+    static const double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
+    static const double W[3][1] = {{1}, {1}, {1}};
+    static const double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
+    
+    const double * const * x = c.coordinates;
+    double result = 0.0;
+    // Iterate over the points:
+    // Evaluate basis functions for affine mapping
+    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    
+    // Compute affine mapping y = F(X)
+    double y[2];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
+    
+    // Evaluate function at physical points
+    double values[1];
+    f.evaluate(values, y, c);
+    
+    // Map function values using appropriate mapping
+    // Affine map: Do nothing
+    
+    // Note that we do not map the weights (yet).
+    
+    // Take directional components
+    for(int k = 0; k < 1; k++)
+      result += values[k]*D[i][0][k];
+    // Multiply by weights
+    result *= W[i][0];
+    
+    return result;
+}
+
+/// Evaluate linear functionals for all dofs on the function f
+void magmaequations_1_finite_element_6::evaluate_dofs(double* values,
+                                  const ufc::function& f,
+                                  const ufc::cell& c) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Interpolate vertex values from dof values
+void magmaequations_1_finite_element_6::interpolate_vertex_values(double* vertex_values,
+                                              const double* dof_values,
+                                              const ufc::cell& c) const
+{
+    // Evaluate at vertices and use affine mapping
+    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)
+unsigned int magmaequations_1_finite_element_6::num_sub_elements() const
+{
+    return 1;
+}
+
+/// Create a new finite element for sub element i (for a mixed element)
+ufc::finite_element* magmaequations_1_finite_element_6::create_sub_element(unsigned int i) const
+{
+    return new magmaequations_1_finite_element_6();
+}
+
+
+/// Constructor
+magmaequations_1_finite_element_7::magmaequations_1_finite_element_7() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+magmaequations_1_finite_element_7::~magmaequations_1_finite_element_7()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* magmaequations_1_finite_element_7::signature() const
+{
+    return "FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 0)";
+}
+
+/// Return the cell shape
+ufc::shape magmaequations_1_finite_element_7::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int magmaequations_1_finite_element_7::space_dimension() const
+{
+    return 1;
+}
+
+/// Return the rank of the value space
+unsigned int magmaequations_1_finite_element_7::value_rank() const
+{
+    return 0;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int magmaequations_1_finite_element_7::value_dimension(unsigned int i) const
+{
+    return 1;
+}
+
+/// Evaluate basis function i at given point in cell
+void magmaequations_1_finite_element_7::evaluate_basis(unsigned int i,
+                                   double* values,
+                                   const double* coordinates,
+                                   const ufc::cell& c) const
+{
+    // Extract vertex coordinates
+    const double * const * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Reset values
+    *values = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[1][1] = \
+    {{1.41421356237309}};
+    
+    // Extract relevant coefficients
+    const double coeff0_0 = coefficients0[dof][0];
+    
+    // Compute value(s)
+    *values = coeff0_0*basisvalue0;
+}
+
+/// Evaluate all basis functions at given point in cell
+void magmaequations_1_finite_element_7::evaluate_basis_all(double* values,
+                                       const double* coordinates,
+                                       const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
+}
+
+/// Evaluate order n derivatives of basis function i at given point in cell
+void magmaequations_1_finite_element_7::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 * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 2;
+    
+    
+    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
+    unsigned int **combinations = new unsigned int *[num_derivatives];
+    
+    for (unsigned int j = 0; j < num_derivatives; j++)
+    {
+      combinations[j] = new unsigned int [n];
+      for (unsigned int k = 0; k < n; k++)
+        combinations[j][k] = 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] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
+    
+    // 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
+    for (unsigned int j = 0; j < 1*num_derivatives; j++)
+      values[j] = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[1][1] = \
+    {{1.41421356237309}};
+    
+    // Interesting (new) part
+    // Tables of derivatives of the polynomial base (transpose)
+    static const double dmats0[1][1] = \
+    {{0}};
+    
+    static const double dmats1[1][1] = \
+    {{0}};
+    
+    // Compute reference derivatives
+    // Declare pointer to array of derivatives on FIAT element
+    double *derivatives = new double [num_derivatives];
+    
+    // Declare coefficients
+    double coeff0_0 = 0;
+    
+    // Declare new coefficients
+    double new_coeff0_0 = 0;
+    
+    // Loop possible derivatives
+    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+    {
+      // Get values from coefficients array
+      new_coeff0_0 = coefficients0[dof][0];
+    
+      // Loop derivative order
+      for (unsigned int j = 0; j < n; j++)
+      {
+        // Update old coefficients
+        coeff0_0 = new_coeff0_0;
+    
+        if(combinations[deriv_num][j] == 0)
+        {
+          new_coeff0_0 = coeff0_0*dmats0[0][0];
+        }
+        if(combinations[deriv_num][j] == 1)
+        {
+          new_coeff0_0 = coeff0_0*dmats1[0][0];
+        }
+    
+      }
+      // Compute derivatives on reference element as dot product of coefficients and basisvalues
+      derivatives[deriv_num] = new_coeff0_0*basisvalue0;
+    }
+    
+    // Transform derivatives back to physical element
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      for (unsigned int col = 0; col < num_derivatives; col++)
+      {
+        values[row] += transform[row][col]*derivatives[col];
+      }
+    }
+    // Delete pointer to array of derivatives on FIAT element
+    delete [] derivatives;
+    
+    // Delete pointer to array of combinations of derivatives and transform
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      delete [] combinations[row];
+      delete [] transform[row];
+    }
+    
+    delete [] combinations;
+    delete [] transform;
+}
+
+/// Evaluate order n derivatives of all basis functions at given point in cell
+void magmaequations_1_finite_element_7::evaluate_basis_derivatives_all(unsigned int n,
+                                                   double* values,
+                                                   const double* coordinates,
+                                                   const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
+}
+
+/// Evaluate linear functional for dof i on the function f
+double magmaequations_1_finite_element_7::evaluate_dof(unsigned int i,
+                                   const ufc::function& f,
+                                   const ufc::cell& c) const
+{
+    // The reference points, direction and weights:
+    static const double X[1][1][2] = {{{0.333333333333333, 0.333333333333333}}};
+    static const double W[1][1] = {{1}};
+    static const double D[1][1][1] = {{{1}}};
+    
+    const double * const * x = c.coordinates;
+    double result = 0.0;
+    // Iterate over the points:
+    // Evaluate basis functions for affine mapping
+    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    
+    // Compute affine mapping y = F(X)
+    double y[2];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
+    
+    // Evaluate function at physical points
+    double values[1];
+    f.evaluate(values, y, c);
+    
+    // Map function values using appropriate mapping
+    // Affine map: Do nothing
+    
+    // Note that we do not map the weights (yet).
+    
+    // Take directional components
+    for(int k = 0; k < 1; k++)
+      result += values[k]*D[i][0][k];
+    // Multiply by weights
+    result *= W[i][0];
+    
+    return result;
+}
+
+/// Evaluate linear functionals for all dofs on the function f
+void magmaequations_1_finite_element_7::evaluate_dofs(double* values,
+                                  const ufc::function& f,
+                                  const ufc::cell& c) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Interpolate vertex values from dof values
+void magmaequations_1_finite_element_7::interpolate_vertex_values(double* vertex_values,
+                                              const double* dof_values,
+                                              const ufc::cell& c) const
+{
+    // Evaluate at vertices and use affine mapping
+    vertex_values[0] = dof_values[0];
+    vertex_values[1] = dof_values[0];
+    vertex_values[2] = dof_values[0];
+}
+
+/// Return the number of sub elements (for a mixed element)
+unsigned int magmaequations_1_finite_element_7::num_sub_elements() const
+{
+    return 1;
+}
+
+/// Create a new finite element for sub element i (for a mixed element)
+ufc::finite_element* magmaequations_1_finite_element_7::create_sub_element(unsigned int i) const
+{
+    return new magmaequations_1_finite_element_7();
+}
+
+/// Constructor
+magmaequations_1_dof_map_0_0::magmaequations_1_dof_map_0_0() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+magmaequations_1_dof_map_0_0::~magmaequations_1_dof_map_0_0()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* magmaequations_1_dof_map_0_0::signature() const
+{
+    return "FFC dof map for FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool magmaequations_1_dof_map_0_0::needs_mesh_entities(unsigned int d) const
+{
+    switch ( d )
+    {
+    case 0:
+      return true;
+      break;
+    case 1:
+      return true;
+      break;
+    case 2:
+      return false;
+      break;
+    }
+    return false;
+}
+
+/// Initialize dof map for mesh (return true iff init_cell() is needed)
+bool magmaequations_1_dof_map_0_0::init_mesh(const ufc::mesh& m)
+{
+    __global_dimension = m.num_entities[0] + m.num_entities[1];
+    return false;
+}
+
+/// Initialize dof map for given cell
+void magmaequations_1_dof_map_0_0::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void magmaequations_1_dof_map_0_0::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int magmaequations_1_dof_map_0_0::global_dimension() const
+{
+    return __global_dimension;
+}
+
+/// Return the dimension of the local finite element function space for a cell
+unsigned int magmaequations_1_dof_map_0_0::local_dimension(const ufc::cell& c) const
+{
+    return 6;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int magmaequations_1_dof_map_0_0::max_local_dimension() const
+{
+    return 6;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int magmaequations_1_dof_map_0_0::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int magmaequations_1_dof_map_0_0::num_facet_dofs() const
+{
+    return 3;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int magmaequations_1_dof_map_0_0::num_entity_dofs(unsigned int d) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the local-to-global mapping of dofs on a cell
+void magmaequations_1_dof_map_0_0::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];
+    unsigned int offset = m.num_entities[0];
+    dofs[3] = offset + c.entity_indices[1][0];
+    dofs[4] = offset + c.entity_indices[1][1];
+    dofs[5] = offset + c.entity_indices[1][2];
+}
+
+/// Tabulate the local-to-local mapping from facet dofs to cell dofs
+void magmaequations_1_dof_map_0_0::tabulate_facet_dofs(unsigned int* dofs,
+                                        unsigned int facet) const
+{
+    switch ( facet )
+    {
+    case 0:
+      dofs[0] = 1;
+      dofs[1] = 2;
+      dofs[2] = 3;
+      break;
+    case 1:
+      dofs[0] = 0;
+      dofs[1] = 2;
+      dofs[2] = 4;
+      break;
+    case 2:
+      dofs[0] = 0;
+      dofs[1] = 1;
+      dofs[2] = 5;
+      break;
+    }
+}
+
+/// Tabulate the local-to-local mapping of dofs on entity (d, i)
+void magmaequations_1_dof_map_0_0::tabulate_entity_dofs(unsigned int* dofs,
+                                  unsigned int d, unsigned int i) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the coordinates of all dofs on a cell
+void magmaequations_1_dof_map_0_0::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];
+    coordinates[3][0] = 0.5*x[1][0] + 0.5*x[2][0];
+    coordinates[3][1] = 0.5*x[1][1] + 0.5*x[2][1];
+    coordinates[4][0] = 0.5*x[0][0] + 0.5*x[2][0];
+    coordinates[4][1] = 0.5*x[0][1] + 0.5*x[2][1];
+    coordinates[5][0] = 0.5*x[0][0] + 0.5*x[1][0];
+    coordinates[5][1] = 0.5*x[0][1] + 0.5*x[1][1];
+}
+
+/// Return the number of sub dof maps (for a mixed element)
+unsigned int magmaequations_1_dof_map_0_0::num_sub_dof_maps() const
+{
+    return 1;
+}
+
+/// Create a new dof_map for sub dof map i (for a mixed element)
+ufc::dof_map* magmaequations_1_dof_map_0_0::create_sub_dof_map(unsigned int i) const
+{
+    return new magmaequations_1_dof_map_0_0();
+}
+
+
+/// Constructor
+magmaequations_1_dof_map_0_1::magmaequations_1_dof_map_0_1() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+magmaequations_1_dof_map_0_1::~magmaequations_1_dof_map_0_1()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* magmaequations_1_dof_map_0_1::signature() const
+{
+    return "FFC dof map for FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool magmaequations_1_dof_map_0_1::needs_mesh_entities(unsigned int d) const
+{
+    switch ( d )
+    {
+    case 0:
+      return true;
+      break;
+    case 1:
+      return true;
+      break;
+    case 2:
+      return false;
+      break;
+    }
+    return false;
+}
+
+/// Initialize dof map for mesh (return true iff init_cell() is needed)
+bool magmaequations_1_dof_map_0_1::init_mesh(const ufc::mesh& m)
+{
+    __global_dimension = m.num_entities[0] + m.num_entities[1];
+    return false;
+}
+
+/// Initialize dof map for given cell
+void magmaequations_1_dof_map_0_1::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void magmaequations_1_dof_map_0_1::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int magmaequations_1_dof_map_0_1::global_dimension() const
+{
+    return __global_dimension;
+}
+
+/// Return the dimension of the local finite element function space for a cell
+unsigned int magmaequations_1_dof_map_0_1::local_dimension(const ufc::cell& c) const
+{
+    return 6;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int magmaequations_1_dof_map_0_1::max_local_dimension() const
+{
+    return 6;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int magmaequations_1_dof_map_0_1::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int magmaequations_1_dof_map_0_1::num_facet_dofs() const
+{
+    return 3;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int magmaequations_1_dof_map_0_1::num_entity_dofs(unsigned int d) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the local-to-global mapping of dofs on a cell
+void magmaequations_1_dof_map_0_1::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];
+    unsigned int offset = m.num_entities[0];
+    dofs[3] = offset + c.entity_indices[1][0];
+    dofs[4] = offset + c.entity_indices[1][1];
+    dofs[5] = offset + c.entity_indices[1][2];
+}
+
+/// Tabulate the local-to-local mapping from facet dofs to cell dofs
+void magmaequations_1_dof_map_0_1::tabulate_facet_dofs(unsigned int* dofs,
+                                        unsigned int facet) const
+{
+    switch ( facet )
+    {
+    case 0:
+      dofs[0] = 1;
+      dofs[1] = 2;
+      dofs[2] = 3;
+      break;
+    case 1:
+      dofs[0] = 0;
+      dofs[1] = 2;
+      dofs[2] = 4;
+      break;
+    case 2:
+      dofs[0] = 0;
+      dofs[1] = 1;
+      dofs[2] = 5;
+      break;
+    }
+}
+
+/// Tabulate the local-to-local mapping of dofs on entity (d, i)
+void magmaequations_1_dof_map_0_1::tabulate_entity_dofs(unsigned int* dofs,
+                                  unsigned int d, unsigned int i) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the coordinates of all dofs on a cell
+void magmaequations_1_dof_map_0_1::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];
+    coordinates[3][0] = 0.5*x[1][0] + 0.5*x[2][0];
+    coordinates[3][1] = 0.5*x[1][1] + 0.5*x[2][1];
+    coordinates[4][0] = 0.5*x[0][0] + 0.5*x[2][0];
+    coordinates[4][1] = 0.5*x[0][1] + 0.5*x[2][1];
+    coordinates[5][0] = 0.5*x[0][0] + 0.5*x[1][0];
+    coordinates[5][1] = 0.5*x[0][1] + 0.5*x[1][1];
+}
+
+/// Return the number of sub dof maps (for a mixed element)
+unsigned int magmaequations_1_dof_map_0_1::num_sub_dof_maps() const
+{
+    return 1;
+}
+
+/// Create a new dof_map for sub dof map i (for a mixed element)
+ufc::dof_map* magmaequations_1_dof_map_0_1::create_sub_dof_map(unsigned int i) const
+{
+    return new magmaequations_1_dof_map_0_1();
+}
+
+
+/// Constructor
+magmaequations_1_dof_map_0::magmaequations_1_dof_map_0() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+magmaequations_1_dof_map_0::~magmaequations_1_dof_map_0()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* magmaequations_1_dof_map_0::signature() const
+{
+    return "FFC dof map for MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)], **{'value_shape': (2,) })";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool magmaequations_1_dof_map_0::needs_mesh_entities(unsigned int d) const
+{
+    switch ( d )
+    {
+    case 0:
+      return true;
+      break;
+    case 1:
+      return true;
+      break;
+    case 2:
+      return false;
+      break;
+    }
+    return false;
+}
+
+/// Initialize dof map for mesh (return true iff init_cell() is needed)
+bool magmaequations_1_dof_map_0::init_mesh(const ufc::mesh& m)
+{
+    __global_dimension = 2*m.num_entities[0] + 2*m.num_entities[1];
+    return false;
+}
+
+/// Initialize dof map for given cell
+void magmaequations_1_dof_map_0::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void magmaequations_1_dof_map_0::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int magmaequations_1_dof_map_0::global_dimension() const
+{
+    return __global_dimension;
+}
+
+/// Return the dimension of the local finite element function space for a cell
+unsigned int magmaequations_1_dof_map_0::local_dimension(const ufc::cell& c) const
+{
+    return 12;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int magmaequations_1_dof_map_0::max_local_dimension() const
+{
+    return 12;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int magmaequations_1_dof_map_0::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int magmaequations_1_dof_map_0::num_facet_dofs() const
+{
+    return 6;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int magmaequations_1_dof_map_0::num_entity_dofs(unsigned int d) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the local-to-global mapping of dofs on a cell
+void magmaequations_1_dof_map_0::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];
+    unsigned int offset = m.num_entities[0];
+    dofs[3] = offset + c.entity_indices[1][0];
+    dofs[4] = offset + c.entity_indices[1][1];
+    dofs[5] = offset + c.entity_indices[1][2];
+    offset = offset + m.num_entities[1];
+    dofs[6] = offset + c.entity_indices[0][0];
+    dofs[7] = offset + c.entity_indices[0][1];
+    dofs[8] = offset + c.entity_indices[0][2];
+    offset = offset + m.num_entities[0];
+    dofs[9] = offset + c.entity_indices[1][0];
+    dofs[10] = offset + c.entity_indices[1][1];
+    dofs[11] = offset + c.entity_indices[1][2];
+}
+
+/// Tabulate the local-to-local mapping from facet dofs to cell dofs
+void magmaequations_1_dof_map_0::tabulate_facet_dofs(unsigned int* dofs,
+                                        unsigned int facet) const
+{
+    switch ( facet )
+    {
+    case 0:
+      dofs[0] = 1;
+      dofs[1] = 2;
+      dofs[2] = 3;
+      dofs[3] = 7;
+      dofs[4] = 8;
+      dofs[5] = 9;
+      break;
+    case 1:
+      dofs[0] = 0;
+      dofs[1] = 2;
+      dofs[2] = 4;
+      dofs[3] = 6;
+      dofs[4] = 8;
+      dofs[5] = 10;
+      break;
+    case 2:
+      dofs[0] = 0;
+      dofs[1] = 1;
+      dofs[2] = 5;
+      dofs[3] = 6;
+      dofs[4] = 7;
+      dofs[5] = 11;
+      break;
+    }
+}
+
+/// Tabulate the local-to-local mapping of dofs on entity (d, i)
+void magmaequations_1_dof_map_0::tabulate_entity_dofs(unsigned int* dofs,
+                                  unsigned int d, unsigned int i) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the coordinates of all dofs on a cell
+void magmaequations_1_dof_map_0::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];
+    coordinates[3][0] = 0.5*x[1][0] + 0.5*x[2][0];
+    coordinates[3][1] = 0.5*x[1][1] + 0.5*x[2][1];
+    coordinates[4][0] = 0.5*x[0][0] + 0.5*x[2][0];
+    coordinates[4][1] = 0.5*x[0][1] + 0.5*x[2][1];
+    coordinates[5][0] = 0.5*x[0][0] + 0.5*x[1][0];
+    coordinates[5][1] = 0.5*x[0][1] + 0.5*x[1][1];
+    coordinates[6][0] = x[0][0];
+    coordinates[6][1] = x[0][1];
+    coordinates[7][0] = x[1][0];
+    coordinates[7][1] = x[1][1];
+    coordinates[8][0] = x[2][0];
+    coordinates[8][1] = x[2][1];
+    coordinates[9][0] = 0.5*x[1][0] + 0.5*x[2][0];
+    coordinates[9][1] = 0.5*x[1][1] + 0.5*x[2][1];
+    coordinates[10][0] = 0.5*x[0][0] + 0.5*x[2][0];
+    coordinates[10][1] = 0.5*x[0][1] + 0.5*x[2][1];
+    coordinates[11][0] = 0.5*x[0][0] + 0.5*x[1][0];
+    coordinates[11][1] = 0.5*x[0][1] + 0.5*x[1][1];
+}
+
+/// Return the number of sub dof maps (for a mixed element)
+unsigned int magmaequations_1_dof_map_0::num_sub_dof_maps() const
+{
+    return 2;
+}
+
+/// Create a new dof_map for sub dof map i (for a mixed element)
+ufc::dof_map* magmaequations_1_dof_map_0::create_sub_dof_map(unsigned int i) const
+{
+    switch ( i )
+    {
+    case 0:
+      return new magmaequations_1_dof_map_0_0();
+      break;
+    case 1:
+      return new magmaequations_1_dof_map_0_1();
+      break;
+    }
+    return 0;
+}
+
+
+/// Constructor
+magmaequations_1_dof_map_1_0::magmaequations_1_dof_map_1_0() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+magmaequations_1_dof_map_1_0::~magmaequations_1_dof_map_1_0()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* magmaequations_1_dof_map_1_0::signature() const
+{
+    return "FFC dof map for FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool magmaequations_1_dof_map_1_0::needs_mesh_entities(unsigned int d) const
+{
+    switch ( d )
+    {
+    case 0:
+      return true;
+      break;
+    case 1:
+      return true;
+      break;
+    case 2:
+      return false;
+      break;
+    }
+    return false;
+}
+
+/// Initialize dof map for mesh (return true iff init_cell() is needed)
+bool magmaequations_1_dof_map_1_0::init_mesh(const ufc::mesh& m)
+{
+    __global_dimension = m.num_entities[0] + m.num_entities[1];
+    return false;
+}
+
+/// Initialize dof map for given cell
+void magmaequations_1_dof_map_1_0::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void magmaequations_1_dof_map_1_0::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int magmaequations_1_dof_map_1_0::global_dimension() const
+{
+    return __global_dimension;
+}
+
+/// Return the dimension of the local finite element function space for a cell
+unsigned int magmaequations_1_dof_map_1_0::local_dimension(const ufc::cell& c) const
+{
+    return 6;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int magmaequations_1_dof_map_1_0::max_local_dimension() const
+{
+    return 6;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int magmaequations_1_dof_map_1_0::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int magmaequations_1_dof_map_1_0::num_facet_dofs() const
+{
+    return 3;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int magmaequations_1_dof_map_1_0::num_entity_dofs(unsigned int d) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the local-to-global mapping of dofs on a cell
+void magmaequations_1_dof_map_1_0::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];
+    unsigned int offset = m.num_entities[0];
+    dofs[3] = offset + c.entity_indices[1][0];
+    dofs[4] = offset + c.entity_indices[1][1];
+    dofs[5] = offset + c.entity_indices[1][2];
+}
+
+/// Tabulate the local-to-local mapping from facet dofs to cell dofs
+void magmaequations_1_dof_map_1_0::tabulate_facet_dofs(unsigned int* dofs,
+                                        unsigned int facet) const
+{
+    switch ( facet )
+    {
+    case 0:
+      dofs[0] = 1;
+      dofs[1] = 2;
+      dofs[2] = 3;
+      break;
+    case 1:
+      dofs[0] = 0;
+      dofs[1] = 2;
+      dofs[2] = 4;
+      break;
+    case 2:
+      dofs[0] = 0;
+      dofs[1] = 1;
+      dofs[2] = 5;
+      break;
+    }
+}
+
+/// Tabulate the local-to-local mapping of dofs on entity (d, i)
+void magmaequations_1_dof_map_1_0::tabulate_entity_dofs(unsigned int* dofs,
+                                  unsigned int d, unsigned int i) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the coordinates of all dofs on a cell
+void magmaequations_1_dof_map_1_0::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];
+    coordinates[3][0] = 0.5*x[1][0] + 0.5*x[2][0];
+    coordinates[3][1] = 0.5*x[1][1] + 0.5*x[2][1];
+    coordinates[4][0] = 0.5*x[0][0] + 0.5*x[2][0];
+    coordinates[4][1] = 0.5*x[0][1] + 0.5*x[2][1];
+    coordinates[5][0] = 0.5*x[0][0] + 0.5*x[1][0];
+    coordinates[5][1] = 0.5*x[0][1] + 0.5*x[1][1];
+}
+
+/// Return the number of sub dof maps (for a mixed element)
+unsigned int magmaequations_1_dof_map_1_0::num_sub_dof_maps() const
+{
+    return 1;
+}
+
+/// Create a new dof_map for sub dof map i (for a mixed element)
+ufc::dof_map* magmaequations_1_dof_map_1_0::create_sub_dof_map(unsigned int i) const
+{
+    return new magmaequations_1_dof_map_1_0();
+}
+
+
+/// Constructor
+magmaequations_1_dof_map_1_1::magmaequations_1_dof_map_1_1() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+magmaequations_1_dof_map_1_1::~magmaequations_1_dof_map_1_1()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* magmaequations_1_dof_map_1_1::signature() const
+{
+    return "FFC dof map for FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool magmaequations_1_dof_map_1_1::needs_mesh_entities(unsigned int d) const
+{
+    switch ( d )
+    {
+    case 0:
+      return true;
+      break;
+    case 1:
+      return true;
+      break;
+    case 2:
+      return false;
+      break;
+    }
+    return false;
+}
+
+/// Initialize dof map for mesh (return true iff init_cell() is needed)
+bool magmaequations_1_dof_map_1_1::init_mesh(const ufc::mesh& m)
+{
+    __global_dimension = m.num_entities[0] + m.num_entities[1];
+    return false;
+}
+
+/// Initialize dof map for given cell
+void magmaequations_1_dof_map_1_1::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void magmaequations_1_dof_map_1_1::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int magmaequations_1_dof_map_1_1::global_dimension() const
+{
+    return __global_dimension;
+}
+
+/// Return the dimension of the local finite element function space for a cell
+unsigned int magmaequations_1_dof_map_1_1::local_dimension(const ufc::cell& c) const
+{
+    return 6;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int magmaequations_1_dof_map_1_1::max_local_dimension() const
+{
+    return 6;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int magmaequations_1_dof_map_1_1::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int magmaequations_1_dof_map_1_1::num_facet_dofs() const
+{
+    return 3;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int magmaequations_1_dof_map_1_1::num_entity_dofs(unsigned int d) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the local-to-global mapping of dofs on a cell
+void magmaequations_1_dof_map_1_1::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];
+    unsigned int offset = m.num_entities[0];
+    dofs[3] = offset + c.entity_indices[1][0];
+    dofs[4] = offset + c.entity_indices[1][1];
+    dofs[5] = offset + c.entity_indices[1][2];
+}
+
+/// Tabulate the local-to-local mapping from facet dofs to cell dofs
+void magmaequations_1_dof_map_1_1::tabulate_facet_dofs(unsigned int* dofs,
+                                        unsigned int facet) const
+{
+    switch ( facet )
+    {
+    case 0:
+      dofs[0] = 1;
+      dofs[1] = 2;
+      dofs[2] = 3;
+      break;
+    case 1:
+      dofs[0] = 0;
+      dofs[1] = 2;
+      dofs[2] = 4;
+      break;
+    case 2:
+      dofs[0] = 0;
+      dofs[1] = 1;
+      dofs[2] = 5;
+      break;
+    }
+}
+
+/// Tabulate the local-to-local mapping of dofs on entity (d, i)
+void magmaequations_1_dof_map_1_1::tabulate_entity_dofs(unsigned int* dofs,
+                                  unsigned int d, unsigned int i) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the coordinates of all dofs on a cell
+void magmaequations_1_dof_map_1_1::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];
+    coordinates[3][0] = 0.5*x[1][0] + 0.5*x[2][0];
+    coordinates[3][1] = 0.5*x[1][1] + 0.5*x[2][1];
+    coordinates[4][0] = 0.5*x[0][0] + 0.5*x[2][0];
+    coordinates[4][1] = 0.5*x[0][1] + 0.5*x[2][1];
+    coordinates[5][0] = 0.5*x[0][0] + 0.5*x[1][0];
+    coordinates[5][1] = 0.5*x[0][1] + 0.5*x[1][1];
+}
+
+/// Return the number of sub dof maps (for a mixed element)
+unsigned int magmaequations_1_dof_map_1_1::num_sub_dof_maps() const
+{
+    return 1;
+}
+
+/// Create a new dof_map for sub dof map i (for a mixed element)
+ufc::dof_map* magmaequations_1_dof_map_1_1::create_sub_dof_map(unsigned int i) const
+{
+    return new magmaequations_1_dof_map_1_1();
+}
+
+
+/// Constructor
+magmaequations_1_dof_map_1::magmaequations_1_dof_map_1() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+magmaequations_1_dof_map_1::~magmaequations_1_dof_map_1()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* magmaequations_1_dof_map_1::signature() const
+{
+    return "FFC dof map for MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)], **{'value_shape': (2,) })";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool magmaequations_1_dof_map_1::needs_mesh_entities(unsigned int d) const
+{
+    switch ( d )
+    {
+    case 0:
+      return true;
+      break;
+    case 1:
+      return true;
+      break;
+    case 2:
+      return false;
+      break;
+    }
+    return false;
+}
+
+/// Initialize dof map for mesh (return true iff init_cell() is needed)
+bool magmaequations_1_dof_map_1::init_mesh(const ufc::mesh& m)
+{
+    __global_dimension = 2*m.num_entities[0] + 2*m.num_entities[1];
+    return false;
+}
+
+/// Initialize dof map for given cell
+void magmaequations_1_dof_map_1::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void magmaequations_1_dof_map_1::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int magmaequations_1_dof_map_1::global_dimension() const
+{
+    return __global_dimension;
+}
+
+/// Return the dimension of the local finite element function space for a cell
+unsigned int magmaequations_1_dof_map_1::local_dimension(const ufc::cell& c) const
+{
+    return 12;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int magmaequations_1_dof_map_1::max_local_dimension() const
+{
+    return 12;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int magmaequations_1_dof_map_1::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int magmaequations_1_dof_map_1::num_facet_dofs() const
+{
+    return 6;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int magmaequations_1_dof_map_1::num_entity_dofs(unsigned int d) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the local-to-global mapping of dofs on a cell
+void magmaequations_1_dof_map_1::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];
+    unsigned int offset = m.num_entities[0];
+    dofs[3] = offset + c.entity_indices[1][0];
+    dofs[4] = offset + c.entity_indices[1][1];
+    dofs[5] = offset + c.entity_indices[1][2];
+    offset = offset + m.num_entities[1];
+    dofs[6] = offset + c.entity_indices[0][0];
+    dofs[7] = offset + c.entity_indices[0][1];
+    dofs[8] = offset + c.entity_indices[0][2];
+    offset = offset + m.num_entities[0];
+    dofs[9] = offset + c.entity_indices[1][0];
+    dofs[10] = offset + c.entity_indices[1][1];
+    dofs[11] = offset + c.entity_indices[1][2];
+}
+
+/// Tabulate the local-to-local mapping from facet dofs to cell dofs
+void magmaequations_1_dof_map_1::tabulate_facet_dofs(unsigned int* dofs,
+                                        unsigned int facet) const
+{
+    switch ( facet )
+    {
+    case 0:
+      dofs[0] = 1;
+      dofs[1] = 2;
+      dofs[2] = 3;
+      dofs[3] = 7;
+      dofs[4] = 8;
+      dofs[5] = 9;
+      break;
+    case 1:
+      dofs[0] = 0;
+      dofs[1] = 2;
+      dofs[2] = 4;
+      dofs[3] = 6;
+      dofs[4] = 8;
+      dofs[5] = 10;
+      break;
+    case 2:
+      dofs[0] = 0;
+      dofs[1] = 1;
+      dofs[2] = 5;
+      dofs[3] = 6;
+      dofs[4] = 7;
+      dofs[5] = 11;
+      break;
+    }
+}
+
+/// Tabulate the local-to-local mapping of dofs on entity (d, i)
+void magmaequations_1_dof_map_1::tabulate_entity_dofs(unsigned int* dofs,
+                                  unsigned int d, unsigned int i) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the coordinates of all dofs on a cell
+void magmaequations_1_dof_map_1::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];
+    coordinates[3][0] = 0.5*x[1][0] + 0.5*x[2][0];
+    coordinates[3][1] = 0.5*x[1][1] + 0.5*x[2][1];
+    coordinates[4][0] = 0.5*x[0][0] + 0.5*x[2][0];
+    coordinates[4][1] = 0.5*x[0][1] + 0.5*x[2][1];
+    coordinates[5][0] = 0.5*x[0][0] + 0.5*x[1][0];
+    coordinates[5][1] = 0.5*x[0][1] + 0.5*x[1][1];
+    coordinates[6][0] = x[0][0];
+    coordinates[6][1] = x[0][1];
+    coordinates[7][0] = x[1][0];
+    coordinates[7][1] = x[1][1];
+    coordinates[8][0] = x[2][0];
+    coordinates[8][1] = x[2][1];
+    coordinates[9][0] = 0.5*x[1][0] + 0.5*x[2][0];
+    coordinates[9][1] = 0.5*x[1][1] + 0.5*x[2][1];
+    coordinates[10][0] = 0.5*x[0][0] + 0.5*x[2][0];
+    coordinates[10][1] = 0.5*x[0][1] + 0.5*x[2][1];
+    coordinates[11][0] = 0.5*x[0][0] + 0.5*x[1][0];
+    coordinates[11][1] = 0.5*x[0][1] + 0.5*x[1][1];
+}
+
+/// Return the number of sub dof maps (for a mixed element)
+unsigned int magmaequations_1_dof_map_1::num_sub_dof_maps() const
+{
+    return 2;
+}
+
+/// Create a new dof_map for sub dof map i (for a mixed element)
+ufc::dof_map* magmaequations_1_dof_map_1::create_sub_dof_map(unsigned int i) const
+{
+    switch ( i )
+    {
+    case 0:
+      return new magmaequations_1_dof_map_1_0();
+      break;
+    case 1:
+      return new magmaequations_1_dof_map_1_1();
+      break;
+    }
+    return 0;
+}
+
+
+/// Constructor
+magmaequations_1_dof_map_2::magmaequations_1_dof_map_2() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+magmaequations_1_dof_map_2::~magmaequations_1_dof_map_2()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* magmaequations_1_dof_map_2::signature() const
+{
+    return "FFC dof map for FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 0)";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool magmaequations_1_dof_map_2::needs_mesh_entities(unsigned int d) const
+{
+    switch ( d )
+    {
+    case 0:
+      return false;
+      break;
+    case 1:
+      return false;
+      break;
+    case 2:
+      return true;
+      break;
+    }
+    return false;
+}
+
+/// Initialize dof map for mesh (return true iff init_cell() is needed)
+bool magmaequations_1_dof_map_2::init_mesh(const ufc::mesh& m)
+{
+    __global_dimension = m.num_entities[2];
+    return false;
+}
+
+/// Initialize dof map for given cell
+void magmaequations_1_dof_map_2::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void magmaequations_1_dof_map_2::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int magmaequations_1_dof_map_2::global_dimension() const
+{
+    return __global_dimension;
+}
+
+/// Return the dimension of the local finite element function space for a cell
+unsigned int magmaequations_1_dof_map_2::local_dimension(const ufc::cell& c) const
+{
+    return 1;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int magmaequations_1_dof_map_2::max_local_dimension() const
+{
+    return 1;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int magmaequations_1_dof_map_2::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int magmaequations_1_dof_map_2::num_facet_dofs() const
+{
+    return 0;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int magmaequations_1_dof_map_2::num_entity_dofs(unsigned int d) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the local-to-global mapping of dofs on a cell
+void magmaequations_1_dof_map_2::tabulate_dofs(unsigned int* dofs,
+                                  const ufc::mesh& m,
+                                  const ufc::cell& c) const
+{
+    dofs[0] = c.entity_indices[2][0];
+}
+
+/// Tabulate the local-to-local mapping from facet dofs to cell dofs
+void magmaequations_1_dof_map_2::tabulate_facet_dofs(unsigned int* dofs,
+                                        unsigned int facet) const
+{
+    switch ( facet )
+    {
+    case 0:
+      
+      break;
+    case 1:
+      
+      break;
+    case 2:
+      
+      break;
+    }
+}
+
+/// Tabulate the local-to-local mapping of dofs on entity (d, i)
+void magmaequations_1_dof_map_2::tabulate_entity_dofs(unsigned int* dofs,
+                                  unsigned int d, unsigned int i) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the coordinates of all dofs on a cell
+void magmaequations_1_dof_map_2::tabulate_coordinates(double** coordinates,
+                                         const ufc::cell& c) const
+{
+    const double * const * x = c.coordinates;
+    coordinates[0][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0];
+    coordinates[0][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1];
+}
+
+/// Return the number of sub dof maps (for a mixed element)
+unsigned int magmaequations_1_dof_map_2::num_sub_dof_maps() const
+{
+    return 1;
+}
+
+/// Create a new dof_map for sub dof map i (for a mixed element)
+ufc::dof_map* magmaequations_1_dof_map_2::create_sub_dof_map(unsigned int i) const
+{
+    return new magmaequations_1_dof_map_2();
+}
+
+
+/// Constructor
+magmaequations_1_dof_map_3::magmaequations_1_dof_map_3() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+magmaequations_1_dof_map_3::~magmaequations_1_dof_map_3()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* magmaequations_1_dof_map_3::signature() const
+{
+    return "FFC dof map for FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 0)";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool magmaequations_1_dof_map_3::needs_mesh_entities(unsigned int d) const
+{
+    switch ( d )
+    {
+    case 0:
+      return false;
+      break;
+    case 1:
+      return false;
+      break;
+    case 2:
+      return true;
+      break;
+    }
+    return false;
+}
+
+/// Initialize dof map for mesh (return true iff init_cell() is needed)
+bool magmaequations_1_dof_map_3::init_mesh(const ufc::mesh& m)
+{
+    __global_dimension = m.num_entities[2];
+    return false;
+}
+
+/// Initialize dof map for given cell
+void magmaequations_1_dof_map_3::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void magmaequations_1_dof_map_3::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int magmaequations_1_dof_map_3::global_dimension() const
+{
+    return __global_dimension;
+}
+
+/// Return the dimension of the local finite element function space for a cell
+unsigned int magmaequations_1_dof_map_3::local_dimension(const ufc::cell& c) const
+{
+    return 1;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int magmaequations_1_dof_map_3::max_local_dimension() const
+{
+    return 1;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int magmaequations_1_dof_map_3::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int magmaequations_1_dof_map_3::num_facet_dofs() const
+{
+    return 0;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int magmaequations_1_dof_map_3::num_entity_dofs(unsigned int d) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the local-to-global mapping of dofs on a cell
+void magmaequations_1_dof_map_3::tabulate_dofs(unsigned int* dofs,
+                                  const ufc::mesh& m,
+                                  const ufc::cell& c) const
+{
+    dofs[0] = c.entity_indices[2][0];
+}
+
+/// Tabulate the local-to-local mapping from facet dofs to cell dofs
+void magmaequations_1_dof_map_3::tabulate_facet_dofs(unsigned int* dofs,
+                                        unsigned int facet) const
+{
+    switch ( facet )
+    {
+    case 0:
+      
+      break;
+    case 1:
+      
+      break;
+    case 2:
+      
+      break;
+    }
+}
+
+/// Tabulate the local-to-local mapping of dofs on entity (d, i)
+void magmaequations_1_dof_map_3::tabulate_entity_dofs(unsigned int* dofs,
+                                  unsigned int d, unsigned int i) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the coordinates of all dofs on a cell
+void magmaequations_1_dof_map_3::tabulate_coordinates(double** coordinates,
+                                         const ufc::cell& c) const
+{
+    const double * const * x = c.coordinates;
+    coordinates[0][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0];
+    coordinates[0][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1];
+}
+
+/// Return the number of sub dof maps (for a mixed element)
+unsigned int magmaequations_1_dof_map_3::num_sub_dof_maps() const
+{
+    return 1;
+}
+
+/// Create a new dof_map for sub dof map i (for a mixed element)
+ufc::dof_map* magmaequations_1_dof_map_3::create_sub_dof_map(unsigned int i) const
+{
+    return new magmaequations_1_dof_map_3();
+}
+
+
+/// Constructor
+magmaequations_1_dof_map_4::magmaequations_1_dof_map_4() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+magmaequations_1_dof_map_4::~magmaequations_1_dof_map_4()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* magmaequations_1_dof_map_4::signature() const
+{
+    return "FFC dof map for FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool magmaequations_1_dof_map_4::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)
+bool magmaequations_1_dof_map_4::init_mesh(const ufc::mesh& m)
+{
+    __global_dimension = m.num_entities[0];
+    return false;
+}
+
+/// Initialize dof map for given cell
+void magmaequations_1_dof_map_4::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void magmaequations_1_dof_map_4::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int magmaequations_1_dof_map_4::global_dimension() const
+{
+    return __global_dimension;
+}
+
+/// Return the dimension of the local finite element function space for a cell
+unsigned int magmaequations_1_dof_map_4::local_dimension(const ufc::cell& c) const
+{
+    return 3;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int magmaequations_1_dof_map_4::max_local_dimension() const
+{
+    return 3;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int magmaequations_1_dof_map_4::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int magmaequations_1_dof_map_4::num_facet_dofs() const
+{
+    return 2;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int magmaequations_1_dof_map_4::num_entity_dofs(unsigned int d) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the local-to-global mapping of dofs on a cell
+void magmaequations_1_dof_map_4::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
+void magmaequations_1_dof_map_4::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)
+void magmaequations_1_dof_map_4::tabulate_entity_dofs(unsigned int* dofs,
+                                  unsigned int d, unsigned int i) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the coordinates of all dofs on a cell
+void magmaequations_1_dof_map_4::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)
+unsigned int magmaequations_1_dof_map_4::num_sub_dof_maps() const
+{
+    return 1;
+}
+
+/// Create a new dof_map for sub dof map i (for a mixed element)
+ufc::dof_map* magmaequations_1_dof_map_4::create_sub_dof_map(unsigned int i) const
+{
+    return new magmaequations_1_dof_map_4();
+}
+
+
+/// Constructor
+magmaequations_1_dof_map_5::magmaequations_1_dof_map_5() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+magmaequations_1_dof_map_5::~magmaequations_1_dof_map_5()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* magmaequations_1_dof_map_5::signature() const
+{
+    return "FFC dof map for FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool magmaequations_1_dof_map_5::needs_mesh_entities(unsigned int d) const
+{
+    switch ( d )
+    {
+    case 0:
+      return true;
+      break;
+    case 1:
+      return true;
+      break;
+    case 2:
+      return false;
+      break;
+    }
+    return false;
+}
+
+/// Initialize dof map for mesh (return true iff init_cell() is needed)
+bool magmaequations_1_dof_map_5::init_mesh(const ufc::mesh& m)
+{
+    __global_dimension = m.num_entities[0] + m.num_entities[1];
+    return false;
+}
+
+/// Initialize dof map for given cell
+void magmaequations_1_dof_map_5::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void magmaequations_1_dof_map_5::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int magmaequations_1_dof_map_5::global_dimension() const
+{
+    return __global_dimension;
+}
+
+/// Return the dimension of the local finite element function space for a cell
+unsigned int magmaequations_1_dof_map_5::local_dimension(const ufc::cell& c) const
+{
+    return 6;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int magmaequations_1_dof_map_5::max_local_dimension() const
+{
+    return 6;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int magmaequations_1_dof_map_5::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int magmaequations_1_dof_map_5::num_facet_dofs() const
+{
+    return 3;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int magmaequations_1_dof_map_5::num_entity_dofs(unsigned int d) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the local-to-global mapping of dofs on a cell
+void magmaequations_1_dof_map_5::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];
+    unsigned int offset = m.num_entities[0];
+    dofs[3] = offset + c.entity_indices[1][0];
+    dofs[4] = offset + c.entity_indices[1][1];
+    dofs[5] = offset + c.entity_indices[1][2];
+}
+
+/// Tabulate the local-to-local mapping from facet dofs to cell dofs
+void magmaequations_1_dof_map_5::tabulate_facet_dofs(unsigned int* dofs,
+                                        unsigned int facet) const
+{
+    switch ( facet )
+    {
+    case 0:
+      dofs[0] = 1;
+      dofs[1] = 2;
+      dofs[2] = 3;
+      break;
+    case 1:
+      dofs[0] = 0;
+      dofs[1] = 2;
+      dofs[2] = 4;
+      break;
+    case 2:
+      dofs[0] = 0;
+      dofs[1] = 1;
+      dofs[2] = 5;
+      break;
+    }
+}
+
+/// Tabulate the local-to-local mapping of dofs on entity (d, i)
+void magmaequations_1_dof_map_5::tabulate_entity_dofs(unsigned int* dofs,
+                                  unsigned int d, unsigned int i) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the coordinates of all dofs on a cell
+void magmaequations_1_dof_map_5::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];
+    coordinates[3][0] = 0.5*x[1][0] + 0.5*x[2][0];
+    coordinates[3][1] = 0.5*x[1][1] + 0.5*x[2][1];
+    coordinates[4][0] = 0.5*x[0][0] + 0.5*x[2][0];
+    coordinates[4][1] = 0.5*x[0][1] + 0.5*x[2][1];
+    coordinates[5][0] = 0.5*x[0][0] + 0.5*x[1][0];
+    coordinates[5][1] = 0.5*x[0][1] + 0.5*x[1][1];
+}
+
+/// Return the number of sub dof maps (for a mixed element)
+unsigned int magmaequations_1_dof_map_5::num_sub_dof_maps() const
+{
+    return 1;
+}
+
+/// Create a new dof_map for sub dof map i (for a mixed element)
+ufc::dof_map* magmaequations_1_dof_map_5::create_sub_dof_map(unsigned int i) const
+{
+    return new magmaequations_1_dof_map_5();
+}
+
+
+/// Constructor
+magmaequations_1_dof_map_6::magmaequations_1_dof_map_6() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+magmaequations_1_dof_map_6::~magmaequations_1_dof_map_6()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* magmaequations_1_dof_map_6::signature() const
+{
+    return "FFC dof map for FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool magmaequations_1_dof_map_6::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)
+bool magmaequations_1_dof_map_6::init_mesh(const ufc::mesh& m)
+{
+    __global_dimension = m.num_entities[0];
+    return false;
+}
+
+/// Initialize dof map for given cell
+void magmaequations_1_dof_map_6::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void magmaequations_1_dof_map_6::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int magmaequations_1_dof_map_6::global_dimension() const
+{
+    return __global_dimension;
+}
+
+/// Return the dimension of the local finite element function space for a cell
+unsigned int magmaequations_1_dof_map_6::local_dimension(const ufc::cell& c) const
+{
+    return 3;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int magmaequations_1_dof_map_6::max_local_dimension() const
+{
+    return 3;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int magmaequations_1_dof_map_6::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int magmaequations_1_dof_map_6::num_facet_dofs() const
+{
+    return 2;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int magmaequations_1_dof_map_6::num_entity_dofs(unsigned int d) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the local-to-global mapping of dofs on a cell
+void magmaequations_1_dof_map_6::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
+void magmaequations_1_dof_map_6::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)
+void magmaequations_1_dof_map_6::tabulate_entity_dofs(unsigned int* dofs,
+                                  unsigned int d, unsigned int i) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the coordinates of all dofs on a cell
+void magmaequations_1_dof_map_6::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)
+unsigned int magmaequations_1_dof_map_6::num_sub_dof_maps() const
+{
+    return 1;
+}
+
+/// Create a new dof_map for sub dof map i (for a mixed element)
+ufc::dof_map* magmaequations_1_dof_map_6::create_sub_dof_map(unsigned int i) const
+{
+    return new magmaequations_1_dof_map_6();
+}
+
+
+/// Constructor
+magmaequations_1_dof_map_7::magmaequations_1_dof_map_7() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+magmaequations_1_dof_map_7::~magmaequations_1_dof_map_7()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* magmaequations_1_dof_map_7::signature() const
+{
+    return "FFC dof map for FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 0)";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool magmaequations_1_dof_map_7::needs_mesh_entities(unsigned int d) const
+{
+    switch ( d )
+    {
+    case 0:
+      return false;
+      break;
+    case 1:
+      return false;
+      break;
+    case 2:
+      return true;
+      break;
+    }
+    return false;
+}
+
+/// Initialize dof map for mesh (return true iff init_cell() is needed)
+bool magmaequations_1_dof_map_7::init_mesh(const ufc::mesh& m)
+{
+    __global_dimension = m.num_entities[2];
+    return false;
+}
+
+/// Initialize dof map for given cell
+void magmaequations_1_dof_map_7::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void magmaequations_1_dof_map_7::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int magmaequations_1_dof_map_7::global_dimension() const
+{
+    return __global_dimension;
+}
+
+/// Return the dimension of the local finite element function space for a cell
+unsigned int magmaequations_1_dof_map_7::local_dimension(const ufc::cell& c) const
+{
+    return 1;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int magmaequations_1_dof_map_7::max_local_dimension() const
+{
+    return 1;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int magmaequations_1_dof_map_7::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int magmaequations_1_dof_map_7::num_facet_dofs() const
+{
+    return 0;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int magmaequations_1_dof_map_7::num_entity_dofs(unsigned int d) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the local-to-global mapping of dofs on a cell
+void magmaequations_1_dof_map_7::tabulate_dofs(unsigned int* dofs,
+                                  const ufc::mesh& m,
+                                  const ufc::cell& c) const
+{
+    dofs[0] = c.entity_indices[2][0];
+}
+
+/// Tabulate the local-to-local mapping from facet dofs to cell dofs
+void magmaequations_1_dof_map_7::tabulate_facet_dofs(unsigned int* dofs,
+                                        unsigned int facet) const
+{
+    switch ( facet )
+    {
+    case 0:
+      
+      break;
+    case 1:
+      
+      break;
+    case 2:
+      
+      break;
+    }
+}
+
+/// Tabulate the local-to-local mapping of dofs on entity (d, i)
+void magmaequations_1_dof_map_7::tabulate_entity_dofs(unsigned int* dofs,
+                                  unsigned int d, unsigned int i) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the coordinates of all dofs on a cell
+void magmaequations_1_dof_map_7::tabulate_coordinates(double** coordinates,
+                                         const ufc::cell& c) const
+{
+    const double * const * x = c.coordinates;
+    coordinates[0][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0];
+    coordinates[0][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1];
+}
+
+/// Return the number of sub dof maps (for a mixed element)
+unsigned int magmaequations_1_dof_map_7::num_sub_dof_maps() const
+{
+    return 1;
+}
+
+/// Create a new dof_map for sub dof map i (for a mixed element)
+ufc::dof_map* magmaequations_1_dof_map_7::create_sub_dof_map(unsigned int i) const
+{
+    return new magmaequations_1_dof_map_7();
+}
+
+
+/// Constructor
+magmaequations_1_cell_integral_0_quadrature::magmaequations_1_cell_integral_0_quadrature() : ufc::cell_integral()
+{
+    // Do nothing
+}
+
+/// Destructor
+magmaequations_1_cell_integral_0_quadrature::~magmaequations_1_cell_integral_0_quadrature()
+{
+    // Do nothing
+}
+
+/// Tabulate the tensor for the contribution from a local cell
+void magmaequations_1_cell_integral_0_quadrature::tabulate_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 Jinv_00 =  J_11 / detJ;
+    const double Jinv_01 = -J_01 / detJ;
+    const double Jinv_10 = -J_10 / detJ;
+    const double Jinv_11 =  J_00 / detJ;
+    
+    // Set scale factor
+    const double det = std::abs(detJ);
+    
+    
+    // Array of quadrature weights
+    static const double W16[16] = {0.0235683681933823, 0.0353880678980859, 0.0225840492823699, 0.00542322591052525, 0.0441850885223617, 0.0663442161070497, 0.0423397245217463, 0.0101672595644788, 0.0441850885223617, 0.0663442161070497, 0.0423397245217463, 0.0101672595644788, 0.0235683681933823, 0.0353880678980859, 0.0225840492823699, 0.00542322591052525};
+    // Quadrature points on the UFC reference element: (0.0654669945550145, 0.0571041961145177), (0.0502101232113698, 0.276843013638124), (0.028912084224389, 0.583590432368917), (0.00970378512694614, 0.860240135656219), (0.311164552244357, 0.0571041961145177), (0.238648659731443, 0.276843013638124), (0.137419104134574, 0.583590432368917), (0.0461220799064521, 0.860240135656219), (0.631731251641125, 0.0571041961145177), (0.484508326630433, 0.276843013638124), (0.278990463496509, 0.583590432368917), (0.0936377844373285, 0.860240135656219), (0.877428809330468, 0.0571041961145177), (0.672946863150506, 0.276843013638124), (0.387497483406694, 0.583590432368917), (0.130056079216834, 0.860240135656219)
+    
+    // Value of basis functions at quadrature points.
+    static const double FE0[16][3] = \
+    {{0.877428809330468, 0.0654669945550145, 0.0571041961145176},
+    {0.672946863150506, 0.0502101232113698, 0.276843013638124},
+    {0.387497483406694, 0.028912084224389, 0.583590432368917},
+    {0.130056079216834, 0.0097037851269462, 0.860240135656219},
+    {0.631731251641125, 0.311164552244357, 0.0571041961145176},
+    {0.484508326630433, 0.238648659731443, 0.276843013638124},
+    {0.278990463496509, 0.137419104134574, 0.583590432368917},
+    {0.0936377844373285, 0.0461220799064521, 0.860240135656219},
+    {0.311164552244357, 0.631731251641125, 0.0571041961145176},
+    {0.238648659731443, 0.484508326630433, 0.276843013638124},
+    {0.137419104134574, 0.278990463496509, 0.583590432368917},
+    {0.0461220799064521, 0.0936377844373286, 0.860240135656219},
+    {0.0654669945550145, 0.877428809330468, 0.0571041961145176},
+    {0.05021012321137, 0.672946863150506, 0.276843013638124},
+    {0.028912084224389, 0.387497483406694, 0.583590432368917},
+    {0.00970378512694609, 0.130056079216835, 0.860240135656219}};
+    
+    static const double FE0_D01[16][2] = \
+    {{-1, 1},
+    {-1, 1},
+    {-1, 1},
+    {-1, 1},
+    {-1, 1},
+    {-1, 1},
+    {-1, 1},
+    {-1, 1},
+    {-1, 1},
+    {-1, 1},
+    {-1, 1},
+    {-1, 1},
+    {-1, 1},
+    {-1, 1},
+    {-1, 1},
+    {-1, 1}};
+    
+    // Array of non-zero columns
+    static const unsigned int nzc1[2] = {0, 1};
+    // Array of non-zero columns
+    static const unsigned int nzc0[2] = {0, 2};
+    static const double FE1[16][6] = \
+    {{0.662333821555697, -0.0568951398028819, -0.0505824176867471, 0.0149537603843903, 0.200419467218139, 0.229770508331402},
+    {0.232768098097706, -0.0451680102655679, -0.123558905237647, 0.0556012872999084, 0.745202550451633, 0.135154979653967},
+    {-0.0871888841136517, -0.0272402669959927, 0.0975651531361618, 0.0674912629327909, 0.904559295532719, 0.0448134395079726},
+    {-0.0962269117343234, -0.00951545823536622, 0.619786046331442, 0.0333903417359317, 0.447517836913622, 0.00504814498869313},
+    {0.166437496959, -0.117517795097495, -0.0505824176867471, 0.0710752064609913, 0.144298021141538, 0.786289488222712},
+    {-0.015011689481988, -0.124742294148215, -0.123558905237647, 0.264272856643007, 0.536530981108534, 0.462509051116308},
+    {-0.123319106052515, -0.0996510837722764, 0.0975651531361618, 0.320785897590582, 0.651264660874928, 0.15335447822312},
+    {-0.0761017150886653, -0.0418675873966577, 0.619786046331442, 0.158704257101893, 0.322203921547661, 0.0172750775043265},
+    {-0.117517795097495, 0.166437496959, -0.0505824176867471, 0.144298021141538, 0.0710752064609913, 0.786289488222712},
+    {-0.124742294148215, -0.0150116894819881, -0.123558905237647, 0.536530981108534, 0.264272856643007, 0.462509051116308},
+    {-0.0996510837722764, -0.123319106052515, 0.0975651531361618, 0.651264660874928, 0.320785897590582, 0.15335447822312},
+    {-0.0418675873966577, -0.0761017150886653, 0.619786046331442, 0.322203921547661, 0.158704257101893, 0.0172750775043265},
+    {-0.0568951398028819, 0.662333821555697, -0.0505824176867471, 0.200419467218139, 0.0149537603843903, 0.229770508331402},
+    {-0.0451680102655679, 0.232768098097706, -0.123558905237647, 0.745202550451633, 0.0556012872999086, 0.135154979653967},
+    {-0.0272402669959926, -0.0871888841136517, 0.0975651531361618, 0.904559295532719, 0.0674912629327908, 0.0448134395079726},
+    {-0.00951545823536611, -0.0962269117343234, 0.619786046331442, 0.447517836913623, 0.0333903417359313, 0.00504814498869308}};
+    
+    // Array of non-zero columns
+    static const unsigned int nzc2[6] = {0, 1, 2, 3, 4, 5};
+    // Array of non-zero columns
+    static const unsigned int nzc5[6] = {6, 7, 8, 9, 10, 11};
+    static const double FE3_C0_D01[16][5] = \
+    {{-2.50971523732187, -0.77158321554193, 0.261867978220058, 3.2812984528638, -0.261867978220058},
+    {-1.69178745260203, 0.107372054552496, 0.200840492845479, 1.58441539804953, -0.200840492845479},
+    {-0.549989933626777, 1.33436172947567, 0.115648336897556, -0.784371795848891, -0.115648336897556},
+    {0.479775683132663, 2.44096054262488, 0.0388151405077859, -2.92073622575754, -0.0388151405077848},
+    {-1.5269250065645, -0.77158321554193, 1.24465820897743, 2.29850822210643, -1.24465820897743},
+    {-0.938033306521733, 0.107372054552495, 0.954594638925771, 0.830661251969238, -0.954594638925771},
+    {-0.115961853986035, 1.33436172947567, 0.549676416538298, -1.21839987548963, -0.549676416538297},
+    {0.625448862250687, 2.44096054262488, 0.184488319625809, -3.06640940487556, -0.184488319625808},
+    {-0.244658208977428, -0.77158321554193, 2.5269250065645, 1.01624142451936, -2.5269250065645},
+    {0.0454053610742288, 0.107372054552495, 1.93803330652173, -0.152777415626724, -1.93803330652173},
+    {0.450323583461703, 1.33436172947567, 1.11596185398603, -1.78468531293737, -1.11596185398603},
+    {0.815511680374193, 2.44096054262488, 0.374551137749315, -3.25647222299907, -0.374551137749314},
+    {0.738132021779943, -0.771583215541929, 3.50971523732187, 0.0334511937619876, -3.50971523732187},
+    {0.799159507154521, 0.107372054552495, 2.69178745260202, -0.906531561707015, -2.69178745260203},
+    {0.884351663102445, 1.33436172947567, 1.54998993362678, -2.21871339257811, -1.54998993362678},
+    {0.961184859492217, 2.44096054262488, 0.520224316867339, -3.40214540211709, -0.520224316867338}};
+    
+    // Array of non-zero columns
+    static const unsigned int nzc3[5] = {0, 2, 3, 4, 5};
+    static const double FE3_C0_D10[16][5] = \
+    {{-2.50971523732187, -0.738132021779942, 0.22841678445807, -0.22841678445807, 3.24784725910181},
+    {-1.69178745260203, -0.79915950715452, 1.10737205455249, -1.10737205455249, 2.49094695975655},
+    {-0.549989933626777, -0.884351663102444, 2.33436172947567, -2.33436172947567, 1.43434159672922},
+    {0.479775683132664, -0.961184859492216, 3.44096054262488, -3.44096054262488, 0.481409176359552},
+    {-1.5269250065645, 0.244658208977428, 0.22841678445807, -0.22841678445807, 1.28226679758707},
+    {-0.938033306521733, -0.0454053610742281, 1.10737205455249, -1.10737205455249, 0.983438667595962},
+    {-0.115961853986035, -0.450323583461702, 2.33436172947567, -2.33436172947567, 0.566285437447737},
+    {0.625448862250687, -0.815511680374192, 3.44096054262488, -3.44096054262488, 0.190062818123505},
+    {-0.244658208977428, 1.5269250065645, 0.228416784458071, -0.228416784458071, -1.28226679758707},
+    {0.0454053610742284, 0.938033306521734, 1.10737205455249, -1.10737205455249, -0.983438667595961},
+    {0.450323583461703, 0.115961853986035, 2.33436172947567, -2.33436172947567, -0.566285437447738},
+    {0.815511680374193, -0.625448862250686, 3.44096054262488, -3.44096054262488, -0.190062818123507},
+    {0.738132021779942, 2.50971523732187, 0.228416784458071, -0.228416784458071, -3.24784725910181},
+    {0.79915950715452, 1.69178745260203, 1.10737205455249, -1.10737205455249, -2.49094695975655},
+    {0.884351663102444, 0.549989933626777, 2.33436172947567, -2.33436172947567, -1.43434159672922},
+    {0.961184859492217, -0.479775683132662, 3.44096054262488, -3.44096054262488, -0.481409176359554}};
+    
+    // Array of non-zero columns
+    static const unsigned int nzc4[5] = {0, 1, 3, 4, 5};
+    
+    // Number of operations to compute geometry constants: 62
+    const double G0 = 2*det*w[6][0]*(Jinv_00*Jinv_10 + Jinv_01*Jinv_11);
+    const double G1 = 2*det*w[6][0]*(Jinv_10*Jinv_10 + Jinv_11*Jinv_11);
+    const double G2 = -Jinv_11*det;
+    const double G3 = det*(Jinv_00*Jinv_10 + Jinv_01*Jinv_11);
+    const double G4 = det*w[6][0]*w[6][0]*(Jinv_10*Jinv_10 + Jinv_11*Jinv_11);
+    const double G5 = det*(Jinv_10*Jinv_10 + Jinv_11*Jinv_11);
+    const double G6 = det*w[6][0]*w[6][0]*(Jinv_00*Jinv_10 + Jinv_01*Jinv_11);
+    const double G7 = -0.5*det*w[1][0];
+    const double G8 = -0.5*det*w[1][0]*w[2][0]*w[6][0];
+    const double G9 = -0.5*det*w[1][0]*w[2][0];
+    const double G10 = 2*det*w[6][0]*(Jinv_00*Jinv_00 + Jinv_01*Jinv_01);
+    const double G11 = -Jinv_01*det;
+    const double G12 = det*(Jinv_00*Jinv_00 + Jinv_01*Jinv_01);
+    const double G13 = det*w[6][0]*w[6][0]*(Jinv_00*Jinv_00 + Jinv_01*Jinv_01);
+    const double G14 = det*w[2][0]*w[6][0];
+    const double G15 = det*w[2][0];
+    
+    // Compute element tensor using UFL quadrature representation
+    // Optimisations: ('simplify expressions', True), ('ignore zero tables', True), ('non zero columns', True), ('remove zero terms', True), ('ignore ones', True)
+    // Total number of operations to compute element tensor: 2718
+    
+    // Loop quadrature points for integral
+    // Number of operations to compute element tensor for following IP loop = 2656
+    for (unsigned int ip = 0; ip < 16; ip++)
+    {
+      
+      // Function declarations
+      double F0 = 0;
+      double F1 = 0;
+      double F2 = 0;
+      double F3 = 0;
+      double F4 = 0;
+      double F5 = 0;
+      double F6 = 0;
+      double F7 = 0;
+      
+      // Total number of operations to compute function values = 8
+      for (unsigned int r = 0; r < 2; r++)
+      {
+        F4 += FE0_D01[ip][r]*w[5][nzc1[r]];
+        F5 += FE0_D01[ip][r]*w[5][nzc0[r]];
+      }// end loop over 'r'
+      
+      // Total number of operations to compute function values = 6
+      for (unsigned int r = 0; r < 3; r++)
+      {
+        F3 += FE0[ip][r]*w[3][r];
+      }// end loop over 'r'
+      
+      // Total number of operations to compute function values = 20
+      for (unsigned int r = 0; r < 5; r++)
+      {
+        F6 += FE3_C0_D10[ip][r]*w[0][nzc4[r]];
+        F7 += FE3_C0_D01[ip][r]*w[0][nzc3[r]];
+      }// end loop over 'r'
+      
+      // Total number of operations to compute function values = 36
+      for (unsigned int r = 0; r < 6; r++)
+      {
+        F0 += FE1[ip][r]*w[0][nzc5[r]];
+        F1 += FE1[ip][r]*w[4][r];
+        F2 += FE1[ip][r]*w[0][nzc2[r]];
+      }// end loop over 'r'
+      
+      // Number of operations to compute ip constants: 52
+      // Number of operations: 19
+      const double Gip0 = (F0*F0*W16[ip]*(G2 + G3*(F4 + F6) + G5*(F5 + F7)) + W16[ip]*(F0*(F6*G0 + F7*G1) + F6*G6 + F7*G4));
+      
+      // Number of operations: 9
+      const double Gip1 = W16[ip]*(F0*det + F1*G7 + F2*F3*(G8 + F0*G9));
+      
+      // Number of operations: 19
+      const double Gip2 = (F0*F0*W16[ip]*(G11 + G12*(F4 + F6) + G3*(F5 + F7)) + W16[ip]*(F0*(F6*G10 + F7*G0) + F6*G13 + F7*G6));
+      
+      // Number of operations: 5
+      const double Gip3 = F2*F3*W16[ip]*(G14 + F0*G15);
+      
+      
+      // Number of operations for primary indices: 20
+      for (unsigned int j = 0; j < 5; j++)
+      {
+        // Number of operations to compute entry: 2
+        A[nzc3[j]] += FE3_C0_D01[ip][j]*Gip0;
+        // Number of operations to compute entry: 2
+        A[nzc4[j]] += FE3_C0_D10[ip][j]*Gip2;
+      }// end loop over 'j'
+      
+      // Number of operations for primary indices: 24
+      for (unsigned int j = 0; j < 6; j++)
+      {
+        // Number of operations to compute entry: 2
+        A[nzc5[j]] += FE1[ip][j]*Gip1;
+        // Number of operations to compute entry: 2
+        A[nzc2[j]] += FE1[ip][j]*Gip3;
+      }// end loop over 'j'
+    }// end loop over 'ip'
+}
+
+/// Constructor
+magmaequations_1_cell_integral_0::magmaequations_1_cell_integral_0() : ufc::cell_integral()
+{
+    // Do nothing
+}
+
+/// Destructor
+magmaequations_1_cell_integral_0::~magmaequations_1_cell_integral_0()
+{
+    // Do nothing
+}
+
+/// Tabulate the tensor for the contribution from a local cell
+void magmaequations_1_cell_integral_0::tabulate_tensor(double* A,
+                                    const double * const * w,
+                                    const ufc::cell& c) const
+{
+    // Reset values of the element tensor block
+    for (unsigned int j = 0; j < 12; j++)
+      A[j] = 0;
+    
+    // Add all contributions to element tensor
+    integral_0_quadrature.tabulate_tensor(A, w, c);
+}
+
+/// Constructor
+magmaequations_1_exterior_facet_integral_0_quadrature::magmaequations_1_exterior_facet_integral_0_quadrature() : ufc::exterior_facet_integral()
+{
+    // Do nothing
+}
+
+/// Destructor
+magmaequations_1_exterior_facet_integral_0_quadrature::~magmaequations_1_exterior_facet_integral_0_quadrature()
+{
+    // Do nothing
+}
+
+/// Tabulate the tensor for the contribution from a local exterior facet
+void magmaequations_1_exterior_facet_integral_0_quadrature::tabulate_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
+    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 Jinv_00 =  J_11 / detJ;
+    const double Jinv_01 = -J_01 / detJ;
+    const double Jinv_10 = -J_10 / detJ;
+    const double Jinv_11 =  J_00 / detJ;
+    
+    // Vertices on edges
+    static unsigned int edge_vertices[3][2] = {{1, 2}, {0, 2}, {0, 1}};
+    
+    // Get vertices
+    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);
+    
+    const bool direction = dx1*(x[facet][0] - x[v0][0]) - dx0*(x[facet][1] - x[v0][1]) < 0;
+    
+    // Compute facet normals from the facet scale factor constants
+    const double n0 = direction ? dx1 / det : -dx1 / det;
+    const double n1 = direction ? -dx0 / det : dx0 / det;
+    
+    
+    // Array of quadrature weights
+    static const double W4[4] = {0.173927422568727, 0.326072577431273, 0.326072577431273, 0.173927422568727};
+    // Quadrature points on the UFC reference element: (0.0694318442029737), (0.330009478207572), (0.669990521792428), (0.930568155797026)
+    
+    // Value of basis functions at quadrature points.
+    static const double FE0_f0_D01[4][2] = \
+    {{-1, 1},
+    {-1, 1},
+    {-1, 1},
+    {-1, 1}};
+    
+    // Array of non-zero columns
+    static const unsigned int nzc1[2] = {0, 2};
+    // Array of non-zero columns
+    static const unsigned int nzc2[2] = {0, 1};
+    static const double FE1_f0_C0[4][3] = \
+    {{0.801346029369931, -0.0597902822241217, 0.258444252854191},
+    {0.227784076790952, -0.112196966793904, 0.884412890002952},
+    {-0.112196966793904, 0.227784076790952, 0.884412890002952},
+    {-0.0597902822241216, 0.801346029369931, 0.258444252854191}};
+    
+    // Array of non-zero columns
+    static const unsigned int nzc5[3] = {1, 2, 3};
+    // Array of non-zero columns
+    static const unsigned int nzc6[3] = {7, 8, 9};
+    // Array of non-zero columns
+    static const unsigned int nzc9[3] = {0, 1, 5};
+    // Array of non-zero columns
+    static const unsigned int nzc10[3] = {6, 7, 11};
+    // Array of non-zero columns
+    static const unsigned int nzc8[3] = {6, 8, 10};
+    // Array of non-zero columns
+    static const unsigned int nzc7[3] = {0, 2, 4};
+    
+    // Number of operations to compute geometry constants: 9
+    // Should be added to total operation count.
+    const double G0 = det*n1;
+    const double G1 = -det*(Jinv_10*n0 + Jinv_11*n1);
+    const double G2 = -det*(Jinv_00*n0 + Jinv_01*n1);
+    
+    // Compute element tensor using UFL quadrature representation
+    // Optimisations: ('simplify expressions', True), ('ignore zero tables', True), ('non zero columns', True), ('remove zero terms', True), ('ignore ones', True)
+    switch ( facet )
+    {
+    case 0:
+      {
+      // Total number of operations to compute element tensor (from this point): 108
+      
+      // Loop quadrature points for integral
+      // Number of operations to compute element tensor for following IP loop = 108
+      for (unsigned int ip = 0; ip < 4; ip++)
+      {
+        
+        // Function declarations
+        double F0 = 0;
+        double F1 = 0;
+        double F2 = 0;
+        
+        // Total number of operations to compute function values = 8
+        for (unsigned int r = 0; r < 2; r++)
+        {
+          F1 += FE0_f0_D01[ip][r]*w[5][nzc2[r]];
+          F2 += FE0_f0_D01[ip][r]*w[5][nzc1[r]];
+        }// end loop over 'r'
+        
+        // Total number of operations to compute function values = 6
+        for (unsigned int r = 0; r < 3; r++)
+        {
+          F0 += FE1_f0_C0[ip][r]*w[0][nzc6[r]];
+        }// end loop over 'r'
+        
+        // Number of operations to compute ip constants: 7
+        // Number of operations: 7
+        const double Gip0 = F0*F0*W4[ip]*(G0 + F1*G2 + F2*G1);
+        
+        
+        // Number of operations for primary indices: 6
+        for (unsigned int j = 0; j < 3; j++)
+        {
+          // Number of operations to compute entry: 2
+          A[nzc5[j]] += FE1_f0_C0[ip][j]*Gip0;
+        }// end loop over 'j'
+      }// end loop over 'ip'
+      }
+      break;
+    case 1:
+      {
+      // Total number of operations to compute element tensor (from this point): 108
+      
+      // Loop quadrature points for integral
+      // Number of operations to compute element tensor for following IP loop = 108
+      for (unsigned int ip = 0; ip < 4; ip++)
+      {
+        
+        // Function declarations
+        double F0 = 0;
+        double F1 = 0;
+        double F2 = 0;
+        
+        // Total number of operations to compute function values = 8
+        for (unsigned int r = 0; r < 2; r++)
+        {
+          F1 += FE0_f0_D01[ip][r]*w[5][nzc2[r]];
+          F2 += FE0_f0_D01[ip][r]*w[5][nzc1[r]];
+        }// end loop over 'r'
+        
+        // Total number of operations to compute function values = 6
+        for (unsigned int r = 0; r < 3; r++)
+        {
+          F0 += FE1_f0_C0[ip][r]*w[0][nzc8[r]];
+        }// end loop over 'r'
+        
+        // Number of operations to compute ip constants: 7
+        // Number of operations: 7
+        const double Gip0 = F0*F0*W4[ip]*(G0 + F1*G2 + F2*G1);
+        
+        
+        // Number of operations for primary indices: 6
+        for (unsigned int j = 0; j < 3; j++)
+        {
+          // Number of operations to compute entry: 2
+          A[nzc7[j]] += FE1_f0_C0[ip][j]*Gip0;
+        }// end loop over 'j'
+      }// end loop over 'ip'
+      }
+      break;
+    case 2:
+      {
+      // Total number of operations to compute element tensor (from this point): 108
+      
+      // Loop quadrature points for integral
+      // Number of operations to compute element tensor for following IP loop = 108
+      for (unsigned int ip = 0; ip < 4; ip++)
+      {
+        
+        // Function declarations
+        double F0 = 0;
+        double F1 = 0;
+        double F2 = 0;
+        
+        // Total number of operations to compute function values = 8
+        for (unsigned int r = 0; r < 2; r++)
+        {
+          F1 += FE0_f0_D01[ip][r]*w[5][nzc2[r]];
+          F2 += FE0_f0_D01[ip][r]*w[5][nzc1[r]];
+        }// end loop over 'r'
+        
+        // Total number of operations to compute function values = 6
+        for (unsigned int r = 0; r < 3; r++)
+        {
+          F0 += FE1_f0_C0[ip][r]*w[0][nzc10[r]];
+        }// end loop over 'r'
+        
+        // Number of operations to compute ip constants: 7
+        // Number of operations: 7
+        const double Gip0 = F0*F0*W4[ip]*(G0 + F1*G2 + F2*G1);
+        
+        
+        // Number of operations for primary indices: 6
+        for (unsigned int j = 0; j < 3; j++)
+        {
+          // Number of operations to compute entry: 2
+          A[nzc9[j]] += FE1_f0_C0[ip][j]*Gip0;
+        }// end loop over 'j'
+      }// end loop over 'ip'
+      }
+      break;
+    }
+}
+
+/// Constructor
+magmaequations_1_exterior_facet_integral_0::magmaequations_1_exterior_facet_integral_0() : ufc::exterior_facet_integral()
+{
+    // Do nothing
+}
+
+/// Destructor
+magmaequations_1_exterior_facet_integral_0::~magmaequations_1_exterior_facet_integral_0()
+{
+    // Do nothing
+}
+
+/// Tabulate the tensor for the contribution from a local exterior facet
+void magmaequations_1_exterior_facet_integral_0::tabulate_tensor(double* A,
+                                    const double * const * w,
+                                    const ufc::cell& c,
+                                    unsigned int facet) const
+{
+    // Reset values of the element tensor block
+    for (unsigned int j = 0; j < 12; j++)
+      A[j] = 0;
+    
+    // Add all contributions to element tensor
+    integral_0_quadrature.tabulate_tensor(A, w, c, facet);
+}
+
+/// Constructor
+magmaequations_form_1::magmaequations_form_1() : ufc::form()
+{
+    // Do nothing
+}
+
+/// Destructor
+magmaequations_form_1::~magmaequations_form_1()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the form
+const char* magmaequations_form_1::signature() const
+{
+    return "Form([Integral(Sum(Product(Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})), Sum(Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})), Product(IntValue(-1, (), (), {}), Product(Product(FloatValue(0.5, (), (), {}), Constant(Cell('triangle', 1, Space(2)), 1)), Sum(Function(FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2), 4), Product(Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(0),), {FixedIndex(0): 2})), Product(Product(Constant(Cell('triangle', 1, Space(2)), 2), Function(FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), 3)), Sum(Constant(Cell('triangle', 1, Space(2)), 6), Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})))))))))), Sum(Product(IndexSum(Product(Indexed(ComponentTensor(Indexed(SpatialDerivative(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((Index(0),), {Index(0): 2})), MultiIndex((FixedIndex(0),), {})), MultiIndex((Index(0),), {Index(0): 2})), MultiIndex((Index(1),), {Index(1): 2})), Indexed(ComponentTensor(SpatialDerivative(Function(FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), 5), MultiIndex((Index(2),), {Index(2): 2})), MultiIndex((Index(2),), {Index(2): 2})), MultiIndex((Index(1),), {Index(1): 2}))), MultiIndex((Index(1),), {Index(1): 2})), Power(Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})), IntValue(2, (), (), {}))), Sum(Product(IntValue(-1, (), (), {}), Product(Indexed(SpatialDerivative(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})), MultiIndex((FixedIndex(0),), {FixedIndex(0): 2})), Power(Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})), IntValue(2, (), (), {})))), Sum(Product(IndexSum(Product(Indexed(ComponentTensor(Indexed(SpatialDerivative(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((Index(3),), {Index(3): 2})), MultiIndex((FixedIndex(0),), {})), MultiIndex((Index(3),), {Index(3): 2})), MultiIndex((Index(4),), {Index(4): 2})), Indexed(ComponentTensor(Indexed(SpatialDerivative(Function(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((Index(5),), {Index(5): 2})), MultiIndex((FixedIndex(0),), {})), MultiIndex((Index(5),), {Index(5): 2})), MultiIndex((Index(4),), {Index(4): 2}))), MultiIndex((Index(4),), {Index(4): 2})), Power(Sum(Constant(Cell('triangle', 1, Space(2)), 6), Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2}))), IntValue(2, (), (), {}))), Product(Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(0),), {FixedIndex(0): 2})), Product(Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(0),), {FixedIndex(0): 2})), Product(Product(Constant(Cell('triangle', 1, Space(2)), 2), Function(FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), 3)), Sum(Constant(Cell('triangle', 1, Space(2)), 6), Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})))))))))), Measure('cell', 0, None)), Integral(Product(Product(Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(0),), {FixedIndex(0): 2})), Power(Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})), IntValue(2, (), (), {}))), Sum(Indexed(FacetNormal(Cell('triangle', 1, Space(2))), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})), Product(IntValue(-1, (), (), {}), IndexSum(Product(Indexed(ComponentTensor(SpatialDerivative(Function(FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), 5), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(6),), {Index(6): 2})), MultiIndex((Index(7),), {Index(7): 2})), Indexed(FacetNormal(Cell('triangle', 1, Space(2))), MultiIndex((Index(7),), {Index(7): 2}))), MultiIndex((Index(7),), {Index(7): 2}))))), Measure('exterior_facet', 0, None))])";
+}
+
+/// Return the rank of the global tensor (r)
+unsigned int magmaequations_form_1::rank() const
+{
+    return 1;
+}
+
+/// Return the number of coefficients (n)
+unsigned int magmaequations_form_1::num_coefficients() const
+{
+    return 7;
+}
+
+/// Return the number of cell integrals
+unsigned int magmaequations_form_1::num_cell_integrals() const
+{
+    return 1;
+}
+
+/// Return the number of exterior facet integrals
+unsigned int magmaequations_form_1::num_exterior_facet_integrals() const
+{
+    return 1;
+}
+
+/// Return the number of interior facet integrals
+unsigned int magmaequations_form_1::num_interior_facet_integrals() const
+{
+    return 0;
+}
+
+/// Create a new finite element for argument function i
+ufc::finite_element* magmaequations_form_1::create_finite_element(unsigned int i) const
+{
+    switch ( i )
+    {
+    case 0:
+      return new magmaequations_1_finite_element_0();
+      break;
+    case 1:
+      return new magmaequations_1_finite_element_1();
+      break;
+    case 2:
+      return new magmaequations_1_finite_element_2();
+      break;
+    case 3:
+      return new magmaequations_1_finite_element_3();
+      break;
+    case 4:
+      return new magmaequations_1_finite_element_4();
+      break;
+    case 5:
+      return new magmaequations_1_finite_element_5();
+      break;
+    case 6:
+      return new magmaequations_1_finite_element_6();
+      break;
+    case 7:
+      return new magmaequations_1_finite_element_7();
+      break;
+    }
+    return 0;
+}
+
+/// Create a new dof map for argument function i
+ufc::dof_map* magmaequations_form_1::create_dof_map(unsigned int i) const
+{
+    switch ( i )
+    {
+    case 0:
+      return new magmaequations_1_dof_map_0();
+      break;
+    case 1:
+      return new magmaequations_1_dof_map_1();
+      break;
+    case 2:
+      return new magmaequations_1_dof_map_2();
+      break;
+    case 3:
+      return new magmaequations_1_dof_map_3();
+      break;
+    case 4:
+      return new magmaequations_1_dof_map_4();
+      break;
+    case 5:
+      return new magmaequations_1_dof_map_5();
+      break;
+    case 6:
+      return new magmaequations_1_dof_map_6();
+      break;
+    case 7:
+      return new magmaequations_1_dof_map_7();
+      break;
+    }
+    return 0;
+}
+
+/// Create a new cell integral on sub domain i
+ufc::cell_integral* magmaequations_form_1::create_cell_integral(unsigned int i) const
+{
+    return new magmaequations_1_cell_integral_0();
+}
+
+/// Create a new exterior facet integral on sub domain i
+ufc::exterior_facet_integral* magmaequations_form_1::create_exterior_facet_integral(unsigned int i) const
+{
+    return new magmaequations_1_exterior_facet_integral_0();
+}
+
+/// Create a new interior facet integral on sub domain i
+ufc::interior_facet_integral* magmaequations_form_1::create_interior_facet_integral(unsigned int i) const
+{
+    return 0;
+}
+
diff -r 18d756141ac1 -r 137baa77335a MADDs-5/MADDs-5a/cpp/MagmaEquations.ufl
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MADDs-5/MADDs-5a/cpp/MagmaEquations.ufl	Tue Dec 08 23:31:34 2009 -0500
@@ -0,0 +1,1 @@
+forms/MagmaEquations_P2.ufl
\ No newline at end of file
diff -r 18d756141ac1 -r 137baa77335a MADDs-5/MADDs-5a/cpp/MeltFlux.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MADDs-5/MADDs-5a/cpp/MeltFlux.cpp	Tue Dec 08 23:31:34 2009 -0500
@@ -0,0 +1,10803 @@
+#include "MeltFlux.h"
+
+/// Constructor
+meltflux_0_finite_element_0_0::meltflux_0_finite_element_0_0() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+meltflux_0_finite_element_0_0::~meltflux_0_finite_element_0_0()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* meltflux_0_finite_element_0_0::signature() const
+{
+    return "FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)";
+}
+
+/// Return the cell shape
+ufc::shape meltflux_0_finite_element_0_0::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int meltflux_0_finite_element_0_0::space_dimension() const
+{
+    return 3;
+}
+
+/// Return the rank of the value space
+unsigned int meltflux_0_finite_element_0_0::value_rank() const
+{
+    return 0;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int meltflux_0_finite_element_0_0::value_dimension(unsigned int i) const
+{
+    return 1;
+}
+
+/// Evaluate basis function i at given point in cell
+void meltflux_0_finite_element_0_0::evaluate_basis(unsigned int i,
+                                   double* values,
+                                   const double* coordinates,
+                                   const ufc::cell& c) const
+{
+    // Extract vertex coordinates
+    const double * const * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Reset values
+    *values = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_1_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    
+    // 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, 0.333333333333333}};
+    
+    // Extract relevant coefficients
+    const double coeff0_0 = coefficients0[dof][0];
+    const double coeff0_1 = coefficients0[dof][1];
+    const double coeff0_2 = coefficients0[dof][2];
+    
+    // Compute value(s)
+    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
+}
+
+/// Evaluate all basis functions at given point in cell
+void meltflux_0_finite_element_0_0::evaluate_basis_all(double* values,
+                                       const double* coordinates,
+                                       const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
+}
+
+/// Evaluate order n derivatives of basis function i at given point in cell
+void meltflux_0_finite_element_0_0::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 * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 2;
+    
+    
+    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
+    unsigned int **combinations = new unsigned int *[num_derivatives];
+    
+    for (unsigned int j = 0; j < num_derivatives; j++)
+    {
+      combinations[j] = new unsigned int [n];
+      for (unsigned int k = 0; k < n; k++)
+        combinations[j][k] = 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] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
+    
+    // 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
+    for (unsigned int j = 0; j < 1*num_derivatives; j++)
+      values[j] = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_1_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    
+    // 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, 0.333333333333333}};
+    
+    // Interesting (new) part
+    // Tables of derivatives of the polynomial base (transpose)
+    static const double dmats0[3][3] = \
+    {{0, 0, 0},
+    {4.89897948556636, 0, 0},
+    {0, 0, 0}};
+    
+    static const double dmats1[3][3] = \
+    {{0, 0, 0},
+    {2.44948974278318, 0, 0},
+    {4.24264068711928, 0, 0}};
+    
+    // Compute reference derivatives
+    // Declare pointer to array of derivatives on FIAT element
+    double *derivatives = new double [num_derivatives];
+    
+    // Declare coefficients
+    double coeff0_0 = 0;
+    double coeff0_1 = 0;
+    double coeff0_2 = 0;
+    
+    // Declare new coefficients
+    double new_coeff0_0 = 0;
+    double new_coeff0_1 = 0;
+    double new_coeff0_2 = 0;
+    
+    // Loop possible derivatives
+    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+    {
+      // Get values from coefficients array
+      new_coeff0_0 = coefficients0[dof][0];
+      new_coeff0_1 = coefficients0[dof][1];
+      new_coeff0_2 = coefficients0[dof][2];
+    
+      // Loop derivative order
+      for (unsigned int j = 0; j < n; j++)
+      {
+        // Update old coefficients
+        coeff0_0 = new_coeff0_0;
+        coeff0_1 = new_coeff0_1;
+        coeff0_2 = new_coeff0_2;
+    
+        if(combinations[deriv_num][j] == 0)
+        {
+          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
+          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
+          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
+        }
+        if(combinations[deriv_num][j] == 1)
+        {
+          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
+          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
+          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
+        }
+    
+      }
+      // Compute derivatives on reference element as dot product of coefficients and basisvalues
+      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
+    }
+    
+    // Transform derivatives back to physical element
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      for (unsigned int col = 0; col < num_derivatives; col++)
+      {
+        values[row] += transform[row][col]*derivatives[col];
+      }
+    }
+    // Delete pointer to array of derivatives on FIAT element
+    delete [] derivatives;
+    
+    // Delete pointer to array of combinations of derivatives and transform
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      delete [] combinations[row];
+      delete [] transform[row];
+    }
+    
+    delete [] combinations;
+    delete [] transform;
+}
+
+/// Evaluate order n derivatives of all basis functions at given point in cell
+void meltflux_0_finite_element_0_0::evaluate_basis_derivatives_all(unsigned int n,
+                                                   double* values,
+                                                   const double* coordinates,
+                                                   const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
+}
+
+/// Evaluate linear functional for dof i on the function f
+double meltflux_0_finite_element_0_0::evaluate_dof(unsigned int i,
+                                   const ufc::function& f,
+                                   const ufc::cell& c) const
+{
+    // The reference points, direction and weights:
+    static const double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
+    static const double W[3][1] = {{1}, {1}, {1}};
+    static const double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
+    
+    const double * const * x = c.coordinates;
+    double result = 0.0;
+    // Iterate over the points:
+    // Evaluate basis functions for affine mapping
+    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    
+    // Compute affine mapping y = F(X)
+    double y[2];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
+    
+    // Evaluate function at physical points
+    double values[1];
+    f.evaluate(values, y, c);
+    
+    // Map function values using appropriate mapping
+    // Affine map: Do nothing
+    
+    // Note that we do not map the weights (yet).
+    
+    // Take directional components
+    for(int k = 0; k < 1; k++)
+      result += values[k]*D[i][0][k];
+    // Multiply by weights
+    result *= W[i][0];
+    
+    return result;
+}
+
+/// Evaluate linear functionals for all dofs on the function f
+void meltflux_0_finite_element_0_0::evaluate_dofs(double* values,
+                                  const ufc::function& f,
+                                  const ufc::cell& c) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Interpolate vertex values from dof values
+void meltflux_0_finite_element_0_0::interpolate_vertex_values(double* vertex_values,
+                                              const double* dof_values,
+                                              const ufc::cell& c) const
+{
+    // Evaluate at vertices and use affine mapping
+    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)
+unsigned int meltflux_0_finite_element_0_0::num_sub_elements() const
+{
+    return 1;
+}
+
+/// Create a new finite element for sub element i (for a mixed element)
+ufc::finite_element* meltflux_0_finite_element_0_0::create_sub_element(unsigned int i) const
+{
+    return new meltflux_0_finite_element_0_0();
+}
+
+
+/// Constructor
+meltflux_0_finite_element_0_1::meltflux_0_finite_element_0_1() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+meltflux_0_finite_element_0_1::~meltflux_0_finite_element_0_1()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* meltflux_0_finite_element_0_1::signature() const
+{
+    return "FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)";
+}
+
+/// Return the cell shape
+ufc::shape meltflux_0_finite_element_0_1::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int meltflux_0_finite_element_0_1::space_dimension() const
+{
+    return 3;
+}
+
+/// Return the rank of the value space
+unsigned int meltflux_0_finite_element_0_1::value_rank() const
+{
+    return 0;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int meltflux_0_finite_element_0_1::value_dimension(unsigned int i) const
+{
+    return 1;
+}
+
+/// Evaluate basis function i at given point in cell
+void meltflux_0_finite_element_0_1::evaluate_basis(unsigned int i,
+                                   double* values,
+                                   const double* coordinates,
+                                   const ufc::cell& c) const
+{
+    // Extract vertex coordinates
+    const double * const * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Reset values
+    *values = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_1_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    
+    // 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, 0.333333333333333}};
+    
+    // Extract relevant coefficients
+    const double coeff0_0 = coefficients0[dof][0];
+    const double coeff0_1 = coefficients0[dof][1];
+    const double coeff0_2 = coefficients0[dof][2];
+    
+    // Compute value(s)
+    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
+}
+
+/// Evaluate all basis functions at given point in cell
+void meltflux_0_finite_element_0_1::evaluate_basis_all(double* values,
+                                       const double* coordinates,
+                                       const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
+}
+
+/// Evaluate order n derivatives of basis function i at given point in cell
+void meltflux_0_finite_element_0_1::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 * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 2;
+    
+    
+    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
+    unsigned int **combinations = new unsigned int *[num_derivatives];
+    
+    for (unsigned int j = 0; j < num_derivatives; j++)
+    {
+      combinations[j] = new unsigned int [n];
+      for (unsigned int k = 0; k < n; k++)
+        combinations[j][k] = 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] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
+    
+    // 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
+    for (unsigned int j = 0; j < 1*num_derivatives; j++)
+      values[j] = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_1_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    
+    // 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, 0.333333333333333}};
+    
+    // Interesting (new) part
+    // Tables of derivatives of the polynomial base (transpose)
+    static const double dmats0[3][3] = \
+    {{0, 0, 0},
+    {4.89897948556636, 0, 0},
+    {0, 0, 0}};
+    
+    static const double dmats1[3][3] = \
+    {{0, 0, 0},
+    {2.44948974278318, 0, 0},
+    {4.24264068711928, 0, 0}};
+    
+    // Compute reference derivatives
+    // Declare pointer to array of derivatives on FIAT element
+    double *derivatives = new double [num_derivatives];
+    
+    // Declare coefficients
+    double coeff0_0 = 0;
+    double coeff0_1 = 0;
+    double coeff0_2 = 0;
+    
+    // Declare new coefficients
+    double new_coeff0_0 = 0;
+    double new_coeff0_1 = 0;
+    double new_coeff0_2 = 0;
+    
+    // Loop possible derivatives
+    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+    {
+      // Get values from coefficients array
+      new_coeff0_0 = coefficients0[dof][0];
+      new_coeff0_1 = coefficients0[dof][1];
+      new_coeff0_2 = coefficients0[dof][2];
+    
+      // Loop derivative order
+      for (unsigned int j = 0; j < n; j++)
+      {
+        // Update old coefficients
+        coeff0_0 = new_coeff0_0;
+        coeff0_1 = new_coeff0_1;
+        coeff0_2 = new_coeff0_2;
+    
+        if(combinations[deriv_num][j] == 0)
+        {
+          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
+          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
+          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
+        }
+        if(combinations[deriv_num][j] == 1)
+        {
+          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
+          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
+          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
+        }
+    
+      }
+      // Compute derivatives on reference element as dot product of coefficients and basisvalues
+      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
+    }
+    
+    // Transform derivatives back to physical element
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      for (unsigned int col = 0; col < num_derivatives; col++)
+      {
+        values[row] += transform[row][col]*derivatives[col];
+      }
+    }
+    // Delete pointer to array of derivatives on FIAT element
+    delete [] derivatives;
+    
+    // Delete pointer to array of combinations of derivatives and transform
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      delete [] combinations[row];
+      delete [] transform[row];
+    }
+    
+    delete [] combinations;
+    delete [] transform;
+}
+
+/// Evaluate order n derivatives of all basis functions at given point in cell
+void meltflux_0_finite_element_0_1::evaluate_basis_derivatives_all(unsigned int n,
+                                                   double* values,
+                                                   const double* coordinates,
+                                                   const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
+}
+
+/// Evaluate linear functional for dof i on the function f
+double meltflux_0_finite_element_0_1::evaluate_dof(unsigned int i,
+                                   const ufc::function& f,
+                                   const ufc::cell& c) const
+{
+    // The reference points, direction and weights:
+    static const double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
+    static const double W[3][1] = {{1}, {1}, {1}};
+    static const double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
+    
+    const double * const * x = c.coordinates;
+    double result = 0.0;
+    // Iterate over the points:
+    // Evaluate basis functions for affine mapping
+    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    
+    // Compute affine mapping y = F(X)
+    double y[2];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
+    
+    // Evaluate function at physical points
+    double values[1];
+    f.evaluate(values, y, c);
+    
+    // Map function values using appropriate mapping
+    // Affine map: Do nothing
+    
+    // Note that we do not map the weights (yet).
+    
+    // Take directional components
+    for(int k = 0; k < 1; k++)
+      result += values[k]*D[i][0][k];
+    // Multiply by weights
+    result *= W[i][0];
+    
+    return result;
+}
+
+/// Evaluate linear functionals for all dofs on the function f
+void meltflux_0_finite_element_0_1::evaluate_dofs(double* values,
+                                  const ufc::function& f,
+                                  const ufc::cell& c) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Interpolate vertex values from dof values
+void meltflux_0_finite_element_0_1::interpolate_vertex_values(double* vertex_values,
+                                              const double* dof_values,
+                                              const ufc::cell& c) const
+{
+    // Evaluate at vertices and use affine mapping
+    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)
+unsigned int meltflux_0_finite_element_0_1::num_sub_elements() const
+{
+    return 1;
+}
+
+/// Create a new finite element for sub element i (for a mixed element)
+ufc::finite_element* meltflux_0_finite_element_0_1::create_sub_element(unsigned int i) const
+{
+    return new meltflux_0_finite_element_0_1();
+}
+
+
+/// Constructor
+meltflux_0_finite_element_0::meltflux_0_finite_element_0() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+meltflux_0_finite_element_0::~meltflux_0_finite_element_0()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* meltflux_0_finite_element_0::signature() const
+{
+    return "VectorElement('Lagrange', Cell('triangle', 1, Space(2)), 1, 2)";
+}
+
+/// Return the cell shape
+ufc::shape meltflux_0_finite_element_0::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int meltflux_0_finite_element_0::space_dimension() const
+{
+    return 6;
+}
+
+/// Return the rank of the value space
+unsigned int meltflux_0_finite_element_0::value_rank() const
+{
+    return 1;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int meltflux_0_finite_element_0::value_dimension(unsigned int i) const
+{
+    return 2;
+}
+
+/// Evaluate basis function i at given point in cell
+void meltflux_0_finite_element_0::evaluate_basis(unsigned int i,
+                                   double* values,
+                                   const double* coordinates,
+                                   const ufc::cell& c) const
+{
+    // Extract vertex coordinates
+    const double * const * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Reset values
+    values[0] = 0;
+    values[1] = 0;
+    
+    if (0 <= i && i <= 2)
+    {
+      // Map degree of freedom to element degree of freedom
+      const unsigned int dof = i;
+    
+      // Generate scalings
+      const double scalings_y_0 = 1;
+      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    
+      // Compute psitilde_a
+      const double psitilde_a_0 = 1;
+      const double psitilde_a_1 = x;
+    
+      // Compute psitilde_bs
+      const double psitilde_bs_0_0 = 1;
+      const double psitilde_bs_0_1 = 1.5*y + 0.5;
+      const double psitilde_bs_1_0 = 1;
+    
+      // Compute basisvalues
+      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    
+      // 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, 0.333333333333333}};
+    
+      // Extract relevant coefficients
+      const double coeff0_0 =   coefficients0[dof][0];
+      const double coeff0_1 =   coefficients0[dof][1];
+      const double coeff0_2 =   coefficients0[dof][2];
+    
+      // Compute value(s)
+      values[0] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
+    }
+    
+    if (3 <= i && i <= 5)
+    {
+      // Map degree of freedom to element degree of freedom
+      const unsigned int dof = i - 3;
+    
+      // Generate scalings
+      const double scalings_y_0 = 1;
+      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    
+      // Compute psitilde_a
+      const double psitilde_a_0 = 1;
+      const double psitilde_a_1 = x;
+    
+      // Compute psitilde_bs
+      const double psitilde_bs_0_0 = 1;
+      const double psitilde_bs_0_1 = 1.5*y + 0.5;
+      const double psitilde_bs_1_0 = 1;
+    
+      // Compute basisvalues
+      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    
+      // 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, 0.333333333333333}};
+    
+      // Extract relevant coefficients
+      const double coeff0_0 =   coefficients0[dof][0];
+      const double coeff0_1 =   coefficients0[dof][1];
+      const double coeff0_2 =   coefficients0[dof][2];
+    
+      // Compute value(s)
+      values[1] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
+    }
+    
+}
+
+/// Evaluate all basis functions at given point in cell
+void meltflux_0_finite_element_0::evaluate_basis_all(double* values,
+                                       const double* coordinates,
+                                       const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
+}
+
+/// Evaluate order n derivatives of basis function i at given point in cell
+void meltflux_0_finite_element_0::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 * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 2;
+    
+    
+    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
+    unsigned int **combinations = new unsigned int *[num_derivatives];
+    
+    for (unsigned int j = 0; j < num_derivatives; j++)
+    {
+      combinations[j] = new unsigned int [n];
+      for (unsigned int k = 0; k < n; k++)
+        combinations[j][k] = 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] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
+    
+    // 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
+    for (unsigned int j = 0; j < 2*num_derivatives; j++)
+      values[j] = 0;
+    
+    if (0 <= i && i <= 2)
+    {
+      // Map degree of freedom to element degree of freedom
+      const unsigned int dof = i;
+    
+      // Generate scalings
+      const double scalings_y_0 = 1;
+      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    
+      // Compute psitilde_a
+      const double psitilde_a_0 = 1;
+      const double psitilde_a_1 = x;
+    
+      // Compute psitilde_bs
+      const double psitilde_bs_0_0 = 1;
+      const double psitilde_bs_0_1 = 1.5*y + 0.5;
+      const double psitilde_bs_1_0 = 1;
+    
+      // Compute basisvalues
+      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    
+      // 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, 0.333333333333333}};
+    
+      // Interesting (new) part
+      // Tables of derivatives of the polynomial base (transpose)
+      static const double dmats0[3][3] =   \
+      {{0, 0, 0},
+      {4.89897948556636, 0, 0},
+      {0, 0, 0}};
+    
+      static const double dmats1[3][3] =   \
+      {{0, 0, 0},
+      {2.44948974278318, 0, 0},
+      {4.24264068711928, 0, 0}};
+    
+      // Compute reference derivatives
+      // Declare pointer to array of derivatives on FIAT element
+      double *derivatives = new double [num_derivatives];
+    
+      // Declare coefficients
+      double coeff0_0 = 0;
+      double coeff0_1 = 0;
+      double coeff0_2 = 0;
+    
+      // Declare new coefficients
+      double new_coeff0_0 = 0;
+      double new_coeff0_1 = 0;
+      double new_coeff0_2 = 0;
+    
+      // Loop possible derivatives
+      for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+      {
+        // Get values from coefficients array
+        new_coeff0_0 = coefficients0[dof][0];
+        new_coeff0_1 = coefficients0[dof][1];
+        new_coeff0_2 = coefficients0[dof][2];
+    
+        // Loop derivative order
+        for (unsigned int j = 0; j < n; j++)
+        {
+          // Update old coefficients
+          coeff0_0 = new_coeff0_0;
+          coeff0_1 = new_coeff0_1;
+          coeff0_2 = new_coeff0_2;
+    
+          if(combinations[deriv_num][j] == 0)
+          {
+            new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
+            new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
+            new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
+          }
+          if(combinations[deriv_num][j] == 1)
+          {
+            new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
+            new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
+            new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
+          }
+    
+        }
+        // Compute derivatives on reference element as dot product of coefficients and basisvalues
+        derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
+      }
+    
+      // Transform derivatives back to physical element
+      for (unsigned int row = 0; row < num_derivatives; row++)
+      {
+        for (unsigned int col = 0; col < num_derivatives; col++)
+        {
+          values[row] += transform[row][col]*derivatives[col];
+        }
+      }
+      // Delete pointer to array of derivatives on FIAT element
+      delete [] derivatives;
+    
+      // Delete pointer to array of combinations of derivatives and transform
+      for (unsigned int row = 0; row < num_derivatives; row++)
+      {
+        delete [] combinations[row];
+        delete [] transform[row];
+      }
+    
+      delete [] combinations;
+      delete [] transform;
+    }
+    
+    if (3 <= i && i <= 5)
+    {
+      // Map degree of freedom to element degree of freedom
+      const unsigned int dof = i - 3;
+    
+      // Generate scalings
+      const double scalings_y_0 = 1;
+      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    
+      // Compute psitilde_a
+      const double psitilde_a_0 = 1;
+      const double psitilde_a_1 = x;
+    
+      // Compute psitilde_bs
+      const double psitilde_bs_0_0 = 1;
+      const double psitilde_bs_0_1 = 1.5*y + 0.5;
+      const double psitilde_bs_1_0 = 1;
+    
+      // Compute basisvalues
+      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    
+      // 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, 0.333333333333333}};
+    
+      // Interesting (new) part
+      // Tables of derivatives of the polynomial base (transpose)
+      static const double dmats0[3][3] =   \
+      {{0, 0, 0},
+      {4.89897948556636, 0, 0},
+      {0, 0, 0}};
+    
+      static const double dmats1[3][3] =   \
+      {{0, 0, 0},
+      {2.44948974278318, 0, 0},
+      {4.24264068711928, 0, 0}};
+    
+      // Compute reference derivatives
+      // Declare pointer to array of derivatives on FIAT element
+      double *derivatives = new double [num_derivatives];
+    
+      // Declare coefficients
+      double coeff0_0 = 0;
+      double coeff0_1 = 0;
+      double coeff0_2 = 0;
+    
+      // Declare new coefficients
+      double new_coeff0_0 = 0;
+      double new_coeff0_1 = 0;
+      double new_coeff0_2 = 0;
+    
+      // Loop possible derivatives
+      for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+      {
+        // Get values from coefficients array
+        new_coeff0_0 = coefficients0[dof][0];
+        new_coeff0_1 = coefficients0[dof][1];
+        new_coeff0_2 = coefficients0[dof][2];
+    
+        // Loop derivative order
+        for (unsigned int j = 0; j < n; j++)
+        {
+          // Update old coefficients
+          coeff0_0 = new_coeff0_0;
+          coeff0_1 = new_coeff0_1;
+          coeff0_2 = new_coeff0_2;
+    
+          if(combinations[deriv_num][j] == 0)
+          {
+            new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
+            new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
+            new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
+          }
+          if(combinations[deriv_num][j] == 1)
+          {
+            new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
+            new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
+            new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
+          }
+    
+        }
+        // Compute derivatives on reference element as dot product of coefficients and basisvalues
+        derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
+      }
+    
+      // Transform derivatives back to physical element
+      for (unsigned int row = 0; row < num_derivatives; row++)
+      {
+        for (unsigned int col = 0; col < num_derivatives; col++)
+        {
+          values[num_derivatives + row] += transform[row][col]*derivatives[col];
+        }
+      }
+      // Delete pointer to array of derivatives on FIAT element
+      delete [] derivatives;
+    
+      // Delete pointer to array of combinations of derivatives and transform
+      for (unsigned int row = 0; row < num_derivatives; row++)
+      {
+        delete [] combinations[row];
+        delete [] transform[row];
+      }
+    
+      delete [] combinations;
+      delete [] transform;
+    }
+    
+}
+
+/// Evaluate order n derivatives of all basis functions at given point in cell
+void meltflux_0_finite_element_0::evaluate_basis_derivatives_all(unsigned int n,
+                                                   double* values,
+                                                   const double* coordinates,
+                                                   const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
+}
+
+/// Evaluate linear functional for dof i on the function f
+double meltflux_0_finite_element_0::evaluate_dof(unsigned int i,
+                                   const ufc::function& f,
+                                   const ufc::cell& c) const
+{
+    // The reference points, direction and weights:
+    static const double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0, 0}}, {{1, 0}}, {{0, 1}}};
+    static const double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
+    static const double D[6][1][2] = {{{1, 0}}, {{1, 0}}, {{1, 0}}, {{0, 1}}, {{0, 1}}, {{0, 1}}};
+    
+    const double * const * x = c.coordinates;
+    double result = 0.0;
+    // Iterate over the points:
+    // Evaluate basis functions for affine mapping
+    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    
+    // Compute affine mapping y = F(X)
+    double y[2];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
+    
+    // Evaluate function at physical points
+    double values[2];
+    f.evaluate(values, y, c);
+    
+    // Map function values using appropriate mapping
+    // Affine map: Do nothing
+    
+    // Note that we do not map the weights (yet).
+    
+    // Take directional components
+    for(int k = 0; k < 2; k++)
+      result += values[k]*D[i][0][k];
+    // Multiply by weights
+    result *= W[i][0];
+    
+    return result;
+}
+
+/// Evaluate linear functionals for all dofs on the function f
+void meltflux_0_finite_element_0::evaluate_dofs(double* values,
+                                  const ufc::function& f,
+                                  const ufc::cell& c) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Interpolate vertex values from dof values
+void meltflux_0_finite_element_0::interpolate_vertex_values(double* vertex_values,
+                                              const double* dof_values,
+                                              const ufc::cell& c) const
+{
+    // Evaluate at vertices and use affine mapping
+    vertex_values[0] = dof_values[0];
+    vertex_values[2] = dof_values[1];
+    vertex_values[4] = dof_values[2];
+    // Evaluate at vertices and use affine mapping
+    vertex_values[1] = dof_values[3];
+    vertex_values[3] = dof_values[4];
+    vertex_values[5] = dof_values[5];
+}
+
+/// Return the number of sub elements (for a mixed element)
+unsigned int meltflux_0_finite_element_0::num_sub_elements() const
+{
+    return 2;
+}
+
+/// Create a new finite element for sub element i (for a mixed element)
+ufc::finite_element* meltflux_0_finite_element_0::create_sub_element(unsigned int i) const
+{
+    switch ( i )
+    {
+    case 0:
+      return new meltflux_0_finite_element_0_0();
+      break;
+    case 1:
+      return new meltflux_0_finite_element_0_1();
+      break;
+    }
+    return 0;
+}
+
+
+/// Constructor
+meltflux_0_finite_element_1_0::meltflux_0_finite_element_1_0() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+meltflux_0_finite_element_1_0::~meltflux_0_finite_element_1_0()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* meltflux_0_finite_element_1_0::signature() const
+{
+    return "FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)";
+}
+
+/// Return the cell shape
+ufc::shape meltflux_0_finite_element_1_0::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int meltflux_0_finite_element_1_0::space_dimension() const
+{
+    return 3;
+}
+
+/// Return the rank of the value space
+unsigned int meltflux_0_finite_element_1_0::value_rank() const
+{
+    return 0;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int meltflux_0_finite_element_1_0::value_dimension(unsigned int i) const
+{
+    return 1;
+}
+
+/// Evaluate basis function i at given point in cell
+void meltflux_0_finite_element_1_0::evaluate_basis(unsigned int i,
+                                   double* values,
+                                   const double* coordinates,
+                                   const ufc::cell& c) const
+{
+    // Extract vertex coordinates
+    const double * const * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Reset values
+    *values = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_1_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    
+    // 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, 0.333333333333333}};
+    
+    // Extract relevant coefficients
+    const double coeff0_0 = coefficients0[dof][0];
+    const double coeff0_1 = coefficients0[dof][1];
+    const double coeff0_2 = coefficients0[dof][2];
+    
+    // Compute value(s)
+    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
+}
+
+/// Evaluate all basis functions at given point in cell
+void meltflux_0_finite_element_1_0::evaluate_basis_all(double* values,
+                                       const double* coordinates,
+                                       const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
+}
+
+/// Evaluate order n derivatives of basis function i at given point in cell
+void meltflux_0_finite_element_1_0::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 * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 2;
+    
+    
+    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
+    unsigned int **combinations = new unsigned int *[num_derivatives];
+    
+    for (unsigned int j = 0; j < num_derivatives; j++)
+    {
+      combinations[j] = new unsigned int [n];
+      for (unsigned int k = 0; k < n; k++)
+        combinations[j][k] = 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] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
+    
+    // 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
+    for (unsigned int j = 0; j < 1*num_derivatives; j++)
+      values[j] = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_1_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    
+    // 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, 0.333333333333333}};
+    
+    // Interesting (new) part
+    // Tables of derivatives of the polynomial base (transpose)
+    static const double dmats0[3][3] = \
+    {{0, 0, 0},
+    {4.89897948556636, 0, 0},
+    {0, 0, 0}};
+    
+    static const double dmats1[3][3] = \
+    {{0, 0, 0},
+    {2.44948974278318, 0, 0},
+    {4.24264068711928, 0, 0}};
+    
+    // Compute reference derivatives
+    // Declare pointer to array of derivatives on FIAT element
+    double *derivatives = new double [num_derivatives];
+    
+    // Declare coefficients
+    double coeff0_0 = 0;
+    double coeff0_1 = 0;
+    double coeff0_2 = 0;
+    
+    // Declare new coefficients
+    double new_coeff0_0 = 0;
+    double new_coeff0_1 = 0;
+    double new_coeff0_2 = 0;
+    
+    // Loop possible derivatives
+    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+    {
+      // Get values from coefficients array
+      new_coeff0_0 = coefficients0[dof][0];
+      new_coeff0_1 = coefficients0[dof][1];
+      new_coeff0_2 = coefficients0[dof][2];
+    
+      // Loop derivative order
+      for (unsigned int j = 0; j < n; j++)
+      {
+        // Update old coefficients
+        coeff0_0 = new_coeff0_0;
+        coeff0_1 = new_coeff0_1;
+        coeff0_2 = new_coeff0_2;
+    
+        if(combinations[deriv_num][j] == 0)
+        {
+          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
+          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
+          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
+        }
+        if(combinations[deriv_num][j] == 1)
+        {
+          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
+          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
+          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
+        }
+    
+      }
+      // Compute derivatives on reference element as dot product of coefficients and basisvalues
+      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
+    }
+    
+    // Transform derivatives back to physical element
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      for (unsigned int col = 0; col < num_derivatives; col++)
+      {
+        values[row] += transform[row][col]*derivatives[col];
+      }
+    }
+    // Delete pointer to array of derivatives on FIAT element
+    delete [] derivatives;
+    
+    // Delete pointer to array of combinations of derivatives and transform
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      delete [] combinations[row];
+      delete [] transform[row];
+    }
+    
+    delete [] combinations;
+    delete [] transform;
+}
+
+/// Evaluate order n derivatives of all basis functions at given point in cell
+void meltflux_0_finite_element_1_0::evaluate_basis_derivatives_all(unsigned int n,
+                                                   double* values,
+                                                   const double* coordinates,
+                                                   const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
+}
+
+/// Evaluate linear functional for dof i on the function f
+double meltflux_0_finite_element_1_0::evaluate_dof(unsigned int i,
+                                   const ufc::function& f,
+                                   const ufc::cell& c) const
+{
+    // The reference points, direction and weights:
+    static const double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
+    static const double W[3][1] = {{1}, {1}, {1}};
+    static const double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
+    
+    const double * const * x = c.coordinates;
+    double result = 0.0;
+    // Iterate over the points:
+    // Evaluate basis functions for affine mapping
+    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    
+    // Compute affine mapping y = F(X)
+    double y[2];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
+    
+    // Evaluate function at physical points
+    double values[1];
+    f.evaluate(values, y, c);
+    
+    // Map function values using appropriate mapping
+    // Affine map: Do nothing
+    
+    // Note that we do not map the weights (yet).
+    
+    // Take directional components
+    for(int k = 0; k < 1; k++)
+      result += values[k]*D[i][0][k];
+    // Multiply by weights
+    result *= W[i][0];
+    
+    return result;
+}
+
+/// Evaluate linear functionals for all dofs on the function f
+void meltflux_0_finite_element_1_0::evaluate_dofs(double* values,
+                                  const ufc::function& f,
+                                  const ufc::cell& c) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Interpolate vertex values from dof values
+void meltflux_0_finite_element_1_0::interpolate_vertex_values(double* vertex_values,
+                                              const double* dof_values,
+                                              const ufc::cell& c) const
+{
+    // Evaluate at vertices and use affine mapping
+    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)
+unsigned int meltflux_0_finite_element_1_0::num_sub_elements() const
+{
+    return 1;
+}
+
+/// Create a new finite element for sub element i (for a mixed element)
+ufc::finite_element* meltflux_0_finite_element_1_0::create_sub_element(unsigned int i) const
+{
+    return new meltflux_0_finite_element_1_0();
+}
+
+
+/// Constructor
+meltflux_0_finite_element_1_1::meltflux_0_finite_element_1_1() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+meltflux_0_finite_element_1_1::~meltflux_0_finite_element_1_1()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* meltflux_0_finite_element_1_1::signature() const
+{
+    return "FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)";
+}
+
+/// Return the cell shape
+ufc::shape meltflux_0_finite_element_1_1::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int meltflux_0_finite_element_1_1::space_dimension() const
+{
+    return 3;
+}
+
+/// Return the rank of the value space
+unsigned int meltflux_0_finite_element_1_1::value_rank() const
+{
+    return 0;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int meltflux_0_finite_element_1_1::value_dimension(unsigned int i) const
+{
+    return 1;
+}
+
+/// Evaluate basis function i at given point in cell
+void meltflux_0_finite_element_1_1::evaluate_basis(unsigned int i,
+                                   double* values,
+                                   const double* coordinates,
+                                   const ufc::cell& c) const
+{
+    // Extract vertex coordinates
+    const double * const * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Reset values
+    *values = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_1_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    
+    // 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, 0.333333333333333}};
+    
+    // Extract relevant coefficients
+    const double coeff0_0 = coefficients0[dof][0];
+    const double coeff0_1 = coefficients0[dof][1];
+    const double coeff0_2 = coefficients0[dof][2];
+    
+    // Compute value(s)
+    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
+}
+
+/// Evaluate all basis functions at given point in cell
+void meltflux_0_finite_element_1_1::evaluate_basis_all(double* values,
+                                       const double* coordinates,
+                                       const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
+}
+
+/// Evaluate order n derivatives of basis function i at given point in cell
+void meltflux_0_finite_element_1_1::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 * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 2;
+    
+    
+    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
+    unsigned int **combinations = new unsigned int *[num_derivatives];
+    
+    for (unsigned int j = 0; j < num_derivatives; j++)
+    {
+      combinations[j] = new unsigned int [n];
+      for (unsigned int k = 0; k < n; k++)
+        combinations[j][k] = 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] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
+    
+    // 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
+    for (unsigned int j = 0; j < 1*num_derivatives; j++)
+      values[j] = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_1_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    
+    // 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, 0.333333333333333}};
+    
+    // Interesting (new) part
+    // Tables of derivatives of the polynomial base (transpose)
+    static const double dmats0[3][3] = \
+    {{0, 0, 0},
+    {4.89897948556636, 0, 0},
+    {0, 0, 0}};
+    
+    static const double dmats1[3][3] = \
+    {{0, 0, 0},
+    {2.44948974278318, 0, 0},
+    {4.24264068711928, 0, 0}};
+    
+    // Compute reference derivatives
+    // Declare pointer to array of derivatives on FIAT element
+    double *derivatives = new double [num_derivatives];
+    
+    // Declare coefficients
+    double coeff0_0 = 0;
+    double coeff0_1 = 0;
+    double coeff0_2 = 0;
+    
+    // Declare new coefficients
+    double new_coeff0_0 = 0;
+    double new_coeff0_1 = 0;
+    double new_coeff0_2 = 0;
+    
+    // Loop possible derivatives
+    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+    {
+      // Get values from coefficients array
+      new_coeff0_0 = coefficients0[dof][0];
+      new_coeff0_1 = coefficients0[dof][1];
+      new_coeff0_2 = coefficients0[dof][2];
+    
+      // Loop derivative order
+      for (unsigned int j = 0; j < n; j++)
+      {
+        // Update old coefficients
+        coeff0_0 = new_coeff0_0;
+        coeff0_1 = new_coeff0_1;
+        coeff0_2 = new_coeff0_2;
+    
+        if(combinations[deriv_num][j] == 0)
+        {
+          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
+          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
+          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
+        }
+        if(combinations[deriv_num][j] == 1)
+        {
+          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
+          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
+          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
+        }
+    
+      }
+      // Compute derivatives on reference element as dot product of coefficients and basisvalues
+      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
+    }
+    
+    // Transform derivatives back to physical element
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      for (unsigned int col = 0; col < num_derivatives; col++)
+      {
+        values[row] += transform[row][col]*derivatives[col];
+      }
+    }
+    // Delete pointer to array of derivatives on FIAT element
+    delete [] derivatives;
+    
+    // Delete pointer to array of combinations of derivatives and transform
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      delete [] combinations[row];
+      delete [] transform[row];
+    }
+    
+    delete [] combinations;
+    delete [] transform;
+}
+
+/// Evaluate order n derivatives of all basis functions at given point in cell
+void meltflux_0_finite_element_1_1::evaluate_basis_derivatives_all(unsigned int n,
+                                                   double* values,
+                                                   const double* coordinates,
+                                                   const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
+}
+
+/// Evaluate linear functional for dof i on the function f
+double meltflux_0_finite_element_1_1::evaluate_dof(unsigned int i,
+                                   const ufc::function& f,
+                                   const ufc::cell& c) const
+{
+    // The reference points, direction and weights:
+    static const double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
+    static const double W[3][1] = {{1}, {1}, {1}};
+    static const double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
+    
+    const double * const * x = c.coordinates;
+    double result = 0.0;
+    // Iterate over the points:
+    // Evaluate basis functions for affine mapping
+    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    
+    // Compute affine mapping y = F(X)
+    double y[2];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
+    
+    // Evaluate function at physical points
+    double values[1];
+    f.evaluate(values, y, c);
+    
+    // Map function values using appropriate mapping
+    // Affine map: Do nothing
+    
+    // Note that we do not map the weights (yet).
+    
+    // Take directional components
+    for(int k = 0; k < 1; k++)
+      result += values[k]*D[i][0][k];
+    // Multiply by weights
+    result *= W[i][0];
+    
+    return result;
+}
+
+/// Evaluate linear functionals for all dofs on the function f
+void meltflux_0_finite_element_1_1::evaluate_dofs(double* values,
+                                  const ufc::function& f,
+                                  const ufc::cell& c) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Interpolate vertex values from dof values
+void meltflux_0_finite_element_1_1::interpolate_vertex_values(double* vertex_values,
+                                              const double* dof_values,
+                                              const ufc::cell& c) const
+{
+    // Evaluate at vertices and use affine mapping
+    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)
+unsigned int meltflux_0_finite_element_1_1::num_sub_elements() const
+{
+    return 1;
+}
+
+/// Create a new finite element for sub element i (for a mixed element)
+ufc::finite_element* meltflux_0_finite_element_1_1::create_sub_element(unsigned int i) const
+{
+    return new meltflux_0_finite_element_1_1();
+}
+
+
+/// Constructor
+meltflux_0_finite_element_1::meltflux_0_finite_element_1() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+meltflux_0_finite_element_1::~meltflux_0_finite_element_1()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* meltflux_0_finite_element_1::signature() const
+{
+    return "VectorElement('Lagrange', Cell('triangle', 1, Space(2)), 1, 2)";
+}
+
+/// Return the cell shape
+ufc::shape meltflux_0_finite_element_1::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int meltflux_0_finite_element_1::space_dimension() const
+{
+    return 6;
+}
+
+/// Return the rank of the value space
+unsigned int meltflux_0_finite_element_1::value_rank() const
+{
+    return 1;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int meltflux_0_finite_element_1::value_dimension(unsigned int i) const
+{
+    return 2;
+}
+
+/// Evaluate basis function i at given point in cell
+void meltflux_0_finite_element_1::evaluate_basis(unsigned int i,
+                                   double* values,
+                                   const double* coordinates,
+                                   const ufc::cell& c) const
+{
+    // Extract vertex coordinates
+    const double * const * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Reset values
+    values[0] = 0;
+    values[1] = 0;
+    
+    if (0 <= i && i <= 2)
+    {
+      // Map degree of freedom to element degree of freedom
+      const unsigned int dof = i;
+    
+      // Generate scalings
+      const double scalings_y_0 = 1;
+      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    
+      // Compute psitilde_a
+      const double psitilde_a_0 = 1;
+      const double psitilde_a_1 = x;
+    
+      // Compute psitilde_bs
+      const double psitilde_bs_0_0 = 1;
+      const double psitilde_bs_0_1 = 1.5*y + 0.5;
+      const double psitilde_bs_1_0 = 1;
+    
+      // Compute basisvalues
+      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    
+      // 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, 0.333333333333333}};
+    
+      // Extract relevant coefficients
+      const double coeff0_0 =   coefficients0[dof][0];
+      const double coeff0_1 =   coefficients0[dof][1];
+      const double coeff0_2 =   coefficients0[dof][2];
+    
+      // Compute value(s)
+      values[0] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
+    }
+    
+    if (3 <= i && i <= 5)
+    {
+      // Map degree of freedom to element degree of freedom
+      const unsigned int dof = i - 3;
+    
+      // Generate scalings
+      const double scalings_y_0 = 1;
+      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    
+      // Compute psitilde_a
+      const double psitilde_a_0 = 1;
+      const double psitilde_a_1 = x;
+    
+      // Compute psitilde_bs
+      const double psitilde_bs_0_0 = 1;
+      const double psitilde_bs_0_1 = 1.5*y + 0.5;
+      const double psitilde_bs_1_0 = 1;
+    
+      // Compute basisvalues
+      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    
+      // 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, 0.333333333333333}};
+    
+      // Extract relevant coefficients
+      const double coeff0_0 =   coefficients0[dof][0];
+      const double coeff0_1 =   coefficients0[dof][1];
+      const double coeff0_2 =   coefficients0[dof][2];
+    
+      // Compute value(s)
+      values[1] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
+    }
+    
+}
+
+/// Evaluate all basis functions at given point in cell
+void meltflux_0_finite_element_1::evaluate_basis_all(double* values,
+                                       const double* coordinates,
+                                       const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
+}
+
+/// Evaluate order n derivatives of basis function i at given point in cell
+void meltflux_0_finite_element_1::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 * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 2;
+    
+    
+    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
+    unsigned int **combinations = new unsigned int *[num_derivatives];
+    
+    for (unsigned int j = 0; j < num_derivatives; j++)
+    {
+      combinations[j] = new unsigned int [n];
+      for (unsigned int k = 0; k < n; k++)
+        combinations[j][k] = 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] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
+    
+    // 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
+    for (unsigned int j = 0; j < 2*num_derivatives; j++)
+      values[j] = 0;
+    
+    if (0 <= i && i <= 2)
+    {
+      // Map degree of freedom to element degree of freedom
+      const unsigned int dof = i;
+    
+      // Generate scalings
+      const double scalings_y_0 = 1;
+      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    
+      // Compute psitilde_a
+      const double psitilde_a_0 = 1;
+      const double psitilde_a_1 = x;
+    
+      // Compute psitilde_bs
+      const double psitilde_bs_0_0 = 1;
+      const double psitilde_bs_0_1 = 1.5*y + 0.5;
+      const double psitilde_bs_1_0 = 1;
+    
+      // Compute basisvalues
+      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    
+      // 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, 0.333333333333333}};
+    
+      // Interesting (new) part
+      // Tables of derivatives of the polynomial base (transpose)
+      static const double dmats0[3][3] =   \
+      {{0, 0, 0},
+      {4.89897948556636, 0, 0},
+      {0, 0, 0}};
+    
+      static const double dmats1[3][3] =   \
+      {{0, 0, 0},
+      {2.44948974278318, 0, 0},
+      {4.24264068711928, 0, 0}};
+    
+      // Compute reference derivatives
+      // Declare pointer to array of derivatives on FIAT element
+      double *derivatives = new double [num_derivatives];
+    
+      // Declare coefficients
+      double coeff0_0 = 0;
+      double coeff0_1 = 0;
+      double coeff0_2 = 0;
+    
+      // Declare new coefficients
+      double new_coeff0_0 = 0;
+      double new_coeff0_1 = 0;
+      double new_coeff0_2 = 0;
+    
+      // Loop possible derivatives
+      for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+      {
+        // Get values from coefficients array
+        new_coeff0_0 = coefficients0[dof][0];
+        new_coeff0_1 = coefficients0[dof][1];
+        new_coeff0_2 = coefficients0[dof][2];
+    
+        // Loop derivative order
+        for (unsigned int j = 0; j < n; j++)
+        {
+          // Update old coefficients
+          coeff0_0 = new_coeff0_0;
+          coeff0_1 = new_coeff0_1;
+          coeff0_2 = new_coeff0_2;
+    
+          if(combinations[deriv_num][j] == 0)
+          {
+            new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
+            new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
+            new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
+          }
+          if(combinations[deriv_num][j] == 1)
+          {
+            new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
+            new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
+            new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
+          }
+    
+        }
+        // Compute derivatives on reference element as dot product of coefficients and basisvalues
+        derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
+      }
+    
+      // Transform derivatives back to physical element
+      for (unsigned int row = 0; row < num_derivatives; row++)
+      {
+        for (unsigned int col = 0; col < num_derivatives; col++)
+        {
+          values[row] += transform[row][col]*derivatives[col];
+        }
+      }
+      // Delete pointer to array of derivatives on FIAT element
+      delete [] derivatives;
+    
+      // Delete pointer to array of combinations of derivatives and transform
+      for (unsigned int row = 0; row < num_derivatives; row++)
+      {
+        delete [] combinations[row];
+        delete [] transform[row];
+      }
+    
+      delete [] combinations;
+      delete [] transform;
+    }
+    
+    if (3 <= i && i <= 5)
+    {
+      // Map degree of freedom to element degree of freedom
+      const unsigned int dof = i - 3;
+    
+      // Generate scalings
+      const double scalings_y_0 = 1;
+      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    
+      // Compute psitilde_a
+      const double psitilde_a_0 = 1;
+      const double psitilde_a_1 = x;
+    
+      // Compute psitilde_bs
+      const double psitilde_bs_0_0 = 1;
+      const double psitilde_bs_0_1 = 1.5*y + 0.5;
+      const double psitilde_bs_1_0 = 1;
+    
+      // Compute basisvalues
+      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    
+      // 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, 0.333333333333333}};
+    
+      // Interesting (new) part
+      // Tables of derivatives of the polynomial base (transpose)
+      static const double dmats0[3][3] =   \
+      {{0, 0, 0},
+      {4.89897948556636, 0, 0},
+      {0, 0, 0}};
+    
+      static const double dmats1[3][3] =   \
+      {{0, 0, 0},
+      {2.44948974278318, 0, 0},
+      {4.24264068711928, 0, 0}};
+    
+      // Compute reference derivatives
+      // Declare pointer to array of derivatives on FIAT element
+      double *derivatives = new double [num_derivatives];
+    
+      // Declare coefficients
+      double coeff0_0 = 0;
+      double coeff0_1 = 0;
+      double coeff0_2 = 0;
+    
+      // Declare new coefficients
+      double new_coeff0_0 = 0;
+      double new_coeff0_1 = 0;
+      double new_coeff0_2 = 0;
+    
+      // Loop possible derivatives
+      for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+      {
+        // Get values from coefficients array
+        new_coeff0_0 = coefficients0[dof][0];
+        new_coeff0_1 = coefficients0[dof][1];
+        new_coeff0_2 = coefficients0[dof][2];
+    
+        // Loop derivative order
+        for (unsigned int j = 0; j < n; j++)
+        {
+          // Update old coefficients
+          coeff0_0 = new_coeff0_0;
+          coeff0_1 = new_coeff0_1;
+          coeff0_2 = new_coeff0_2;
+    
+          if(combinations[deriv_num][j] == 0)
+          {
+            new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
+            new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
+            new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
+          }
+          if(combinations[deriv_num][j] == 1)
+          {
+            new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
+            new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
+            new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
+          }
+    
+        }
+        // Compute derivatives on reference element as dot product of coefficients and basisvalues
+        derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
+      }
+    
+      // Transform derivatives back to physical element
+      for (unsigned int row = 0; row < num_derivatives; row++)
+      {
+        for (unsigned int col = 0; col < num_derivatives; col++)
+        {
+          values[num_derivatives + row] += transform[row][col]*derivatives[col];
+        }
+      }
+      // Delete pointer to array of derivatives on FIAT element
+      delete [] derivatives;
+    
+      // Delete pointer to array of combinations of derivatives and transform
+      for (unsigned int row = 0; row < num_derivatives; row++)
+      {
+        delete [] combinations[row];
+        delete [] transform[row];
+      }
+    
+      delete [] combinations;
+      delete [] transform;
+    }
+    
+}
+
+/// Evaluate order n derivatives of all basis functions at given point in cell
+void meltflux_0_finite_element_1::evaluate_basis_derivatives_all(unsigned int n,
+                                                   double* values,
+                                                   const double* coordinates,
+                                                   const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
+}
+
+/// Evaluate linear functional for dof i on the function f
+double meltflux_0_finite_element_1::evaluate_dof(unsigned int i,
+                                   const ufc::function& f,
+                                   const ufc::cell& c) const
+{
+    // The reference points, direction and weights:
+    static const double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0, 0}}, {{1, 0}}, {{0, 1}}};
+    static const double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
+    static const double D[6][1][2] = {{{1, 0}}, {{1, 0}}, {{1, 0}}, {{0, 1}}, {{0, 1}}, {{0, 1}}};
+    
+    const double * const * x = c.coordinates;
+    double result = 0.0;
+    // Iterate over the points:
+    // Evaluate basis functions for affine mapping
+    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    
+    // Compute affine mapping y = F(X)
+    double y[2];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
+    
+    // Evaluate function at physical points
+    double values[2];
+    f.evaluate(values, y, c);
+    
+    // Map function values using appropriate mapping
+    // Affine map: Do nothing
+    
+    // Note that we do not map the weights (yet).
+    
+    // Take directional components
+    for(int k = 0; k < 2; k++)
+      result += values[k]*D[i][0][k];
+    // Multiply by weights
+    result *= W[i][0];
+    
+    return result;
+}
+
+/// Evaluate linear functionals for all dofs on the function f
+void meltflux_0_finite_element_1::evaluate_dofs(double* values,
+                                  const ufc::function& f,
+                                  const ufc::cell& c) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Interpolate vertex values from dof values
+void meltflux_0_finite_element_1::interpolate_vertex_values(double* vertex_values,
+                                              const double* dof_values,
+                                              const ufc::cell& c) const
+{
+    // Evaluate at vertices and use affine mapping
+    vertex_values[0] = dof_values[0];
+    vertex_values[2] = dof_values[1];
+    vertex_values[4] = dof_values[2];
+    // Evaluate at vertices and use affine mapping
+    vertex_values[1] = dof_values[3];
+    vertex_values[3] = dof_values[4];
+    vertex_values[5] = dof_values[5];
+}
+
+/// Return the number of sub elements (for a mixed element)
+unsigned int meltflux_0_finite_element_1::num_sub_elements() const
+{
+    return 2;
+}
+
+/// Create a new finite element for sub element i (for a mixed element)
+ufc::finite_element* meltflux_0_finite_element_1::create_sub_element(unsigned int i) const
+{
+    switch ( i )
+    {
+    case 0:
+      return new meltflux_0_finite_element_1_0();
+      break;
+    case 1:
+      return new meltflux_0_finite_element_1_1();
+      break;
+    }
+    return 0;
+}
+
+/// Constructor
+meltflux_0_dof_map_0_0::meltflux_0_dof_map_0_0() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+meltflux_0_dof_map_0_0::~meltflux_0_dof_map_0_0()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* meltflux_0_dof_map_0_0::signature() const
+{
+    return "FFC dof map for FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool meltflux_0_dof_map_0_0::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)
+bool meltflux_0_dof_map_0_0::init_mesh(const ufc::mesh& m)
+{
+    __global_dimension = m.num_entities[0];
+    return false;
+}
+
+/// Initialize dof map for given cell
+void meltflux_0_dof_map_0_0::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void meltflux_0_dof_map_0_0::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int meltflux_0_dof_map_0_0::global_dimension() const
+{
+    return __global_dimension;
+}
+
+/// Return the dimension of the local finite element function space for a cell
+unsigned int meltflux_0_dof_map_0_0::local_dimension(const ufc::cell& c) const
+{
+    return 3;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int meltflux_0_dof_map_0_0::max_local_dimension() const
+{
+    return 3;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int meltflux_0_dof_map_0_0::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int meltflux_0_dof_map_0_0::num_facet_dofs() const
+{
+    return 2;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int meltflux_0_dof_map_0_0::num_entity_dofs(unsigned int d) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the local-to-global mapping of dofs on a cell
+void meltflux_0_dof_map_0_0::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
+void meltflux_0_dof_map_0_0::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)
+void meltflux_0_dof_map_0_0::tabulate_entity_dofs(unsigned int* dofs,
+                                  unsigned int d, unsigned int i) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the coordinates of all dofs on a cell
+void meltflux_0_dof_map_0_0::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)
+unsigned int meltflux_0_dof_map_0_0::num_sub_dof_maps() const
+{
+    return 1;
+}
+
+/// Create a new dof_map for sub dof map i (for a mixed element)
+ufc::dof_map* meltflux_0_dof_map_0_0::create_sub_dof_map(unsigned int i) const
+{
+    return new meltflux_0_dof_map_0_0();
+}
+
+
+/// Constructor
+meltflux_0_dof_map_0_1::meltflux_0_dof_map_0_1() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+meltflux_0_dof_map_0_1::~meltflux_0_dof_map_0_1()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* meltflux_0_dof_map_0_1::signature() const
+{
+    return "FFC dof map for FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool meltflux_0_dof_map_0_1::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)
+bool meltflux_0_dof_map_0_1::init_mesh(const ufc::mesh& m)
+{
+    __global_dimension = m.num_entities[0];
+    return false;
+}
+
+/// Initialize dof map for given cell
+void meltflux_0_dof_map_0_1::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void meltflux_0_dof_map_0_1::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int meltflux_0_dof_map_0_1::global_dimension() const
+{
+    return __global_dimension;
+}
+
+/// Return the dimension of the local finite element function space for a cell
+unsigned int meltflux_0_dof_map_0_1::local_dimension(const ufc::cell& c) const
+{
+    return 3;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int meltflux_0_dof_map_0_1::max_local_dimension() const
+{
+    return 3;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int meltflux_0_dof_map_0_1::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int meltflux_0_dof_map_0_1::num_facet_dofs() const
+{
+    return 2;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int meltflux_0_dof_map_0_1::num_entity_dofs(unsigned int d) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the local-to-global mapping of dofs on a cell
+void meltflux_0_dof_map_0_1::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
+void meltflux_0_dof_map_0_1::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)
+void meltflux_0_dof_map_0_1::tabulate_entity_dofs(unsigned int* dofs,
+                                  unsigned int d, unsigned int i) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the coordinates of all dofs on a cell
+void meltflux_0_dof_map_0_1::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)
+unsigned int meltflux_0_dof_map_0_1::num_sub_dof_maps() const
+{
+    return 1;
+}
+
+/// Create a new dof_map for sub dof map i (for a mixed element)
+ufc::dof_map* meltflux_0_dof_map_0_1::create_sub_dof_map(unsigned int i) const
+{
+    return new meltflux_0_dof_map_0_1();
+}
+
+
+/// Constructor
+meltflux_0_dof_map_0::meltflux_0_dof_map_0() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+meltflux_0_dof_map_0::~meltflux_0_dof_map_0()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* meltflux_0_dof_map_0::signature() const
+{
+    return "FFC dof map for VectorElement('Lagrange', Cell('triangle', 1, Space(2)), 1, 2)";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool meltflux_0_dof_map_0::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)
+bool meltflux_0_dof_map_0::init_mesh(const ufc::mesh& m)
+{
+    __global_dimension = 2*m.num_entities[0];
+    return false;
+}
+
+/// Initialize dof map for given cell
+void meltflux_0_dof_map_0::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void meltflux_0_dof_map_0::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int meltflux_0_dof_map_0::global_dimension() const
+{
+    return __global_dimension;
+}
+
+/// Return the dimension of the local finite element function space for a cell
+unsigned int meltflux_0_dof_map_0::local_dimension(const ufc::cell& c) const
+{
+    return 6;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int meltflux_0_dof_map_0::max_local_dimension() const
+{
+    return 6;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int meltflux_0_dof_map_0::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int meltflux_0_dof_map_0::num_facet_dofs() const
+{
+    return 4;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int meltflux_0_dof_map_0::num_entity_dofs(unsigned int d) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the local-to-global mapping of dofs on a cell
+void meltflux_0_dof_map_0::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];
+    unsigned int offset = m.num_entities[0];
+    dofs[3] = offset + c.entity_indices[0][0];
+    dofs[4] = offset + c.entity_indices[0][1];
+    dofs[5] = offset + c.entity_indices[0][2];
+}
+
+/// Tabulate the local-to-local mapping from facet dofs to cell dofs
+void meltflux_0_dof_map_0::tabulate_facet_dofs(unsigned int* dofs,
+                                        unsigned int facet) const
+{
+    switch ( facet )
+    {
+    case 0:
+      dofs[0] = 1;
+      dofs[1] = 2;
+      dofs[2] = 4;
+      dofs[3] = 5;
+      break;
+    case 1:
+      dofs[0] = 0;
+      dofs[1] = 2;
+      dofs[2] = 3;
+      dofs[3] = 5;
+      break;
+    case 2:
+      dofs[0] = 0;
+      dofs[1] = 1;
+      dofs[2] = 3;
+      dofs[3] = 4;
+      break;
+    }
+}
+
+/// Tabulate the local-to-local mapping of dofs on entity (d, i)
+void meltflux_0_dof_map_0::tabulate_entity_dofs(unsigned int* dofs,
+                                  unsigned int d, unsigned int i) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the coordinates of all dofs on a cell
+void meltflux_0_dof_map_0::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];
+    coordinates[3][0] = x[0][0];
+    coordinates[3][1] = x[0][1];
+    coordinates[4][0] = x[1][0];
+    coordinates[4][1] = x[1][1];
+    coordinates[5][0] = x[2][0];
+    coordinates[5][1] = x[2][1];
+}
+
+/// Return the number of sub dof maps (for a mixed element)
+unsigned int meltflux_0_dof_map_0::num_sub_dof_maps() const
+{
+    return 2;
+}
+
+/// Create a new dof_map for sub dof map i (for a mixed element)
+ufc::dof_map* meltflux_0_dof_map_0::create_sub_dof_map(unsigned int i) const
+{
+    switch ( i )
+    {
+    case 0:
+      return new meltflux_0_dof_map_0_0();
+      break;
+    case 1:
+      return new meltflux_0_dof_map_0_1();
+      break;
+    }
+    return 0;
+}
+
+
+/// Constructor
+meltflux_0_dof_map_1_0::meltflux_0_dof_map_1_0() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+meltflux_0_dof_map_1_0::~meltflux_0_dof_map_1_0()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* meltflux_0_dof_map_1_0::signature() const
+{
+    return "FFC dof map for FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool meltflux_0_dof_map_1_0::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)
+bool meltflux_0_dof_map_1_0::init_mesh(const ufc::mesh& m)
+{
+    __global_dimension = m.num_entities[0];
+    return false;
+}
+
+/// Initialize dof map for given cell
+void meltflux_0_dof_map_1_0::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void meltflux_0_dof_map_1_0::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int meltflux_0_dof_map_1_0::global_dimension() const
+{
+    return __global_dimension;
+}
+
+/// Return the dimension of the local finite element function space for a cell
+unsigned int meltflux_0_dof_map_1_0::local_dimension(const ufc::cell& c) const
+{
+    return 3;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int meltflux_0_dof_map_1_0::max_local_dimension() const
+{
+    return 3;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int meltflux_0_dof_map_1_0::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int meltflux_0_dof_map_1_0::num_facet_dofs() const
+{
+    return 2;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int meltflux_0_dof_map_1_0::num_entity_dofs(unsigned int d) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the local-to-global mapping of dofs on a cell
+void meltflux_0_dof_map_1_0::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
+void meltflux_0_dof_map_1_0::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)
+void meltflux_0_dof_map_1_0::tabulate_entity_dofs(unsigned int* dofs,
+                                  unsigned int d, unsigned int i) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the coordinates of all dofs on a cell
+void meltflux_0_dof_map_1_0::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)
+unsigned int meltflux_0_dof_map_1_0::num_sub_dof_maps() const
+{
+    return 1;
+}
+
+/// Create a new dof_map for sub dof map i (for a mixed element)
+ufc::dof_map* meltflux_0_dof_map_1_0::create_sub_dof_map(unsigned int i) const
+{
+    return new meltflux_0_dof_map_1_0();
+}
+
+
+/// Constructor
+meltflux_0_dof_map_1_1::meltflux_0_dof_map_1_1() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+meltflux_0_dof_map_1_1::~meltflux_0_dof_map_1_1()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* meltflux_0_dof_map_1_1::signature() const
+{
+    return "FFC dof map for FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool meltflux_0_dof_map_1_1::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)
+bool meltflux_0_dof_map_1_1::init_mesh(const ufc::mesh& m)
+{
+    __global_dimension = m.num_entities[0];
+    return false;
+}
+
+/// Initialize dof map for given cell
+void meltflux_0_dof_map_1_1::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void meltflux_0_dof_map_1_1::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int meltflux_0_dof_map_1_1::global_dimension() const
+{
+    return __global_dimension;
+}
+
+/// Return the dimension of the local finite element function space for a cell
+unsigned int meltflux_0_dof_map_1_1::local_dimension(const ufc::cell& c) const
+{
+    return 3;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int meltflux_0_dof_map_1_1::max_local_dimension() const
+{
+    return 3;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int meltflux_0_dof_map_1_1::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int meltflux_0_dof_map_1_1::num_facet_dofs() const
+{
+    return 2;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int meltflux_0_dof_map_1_1::num_entity_dofs(unsigned int d) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the local-to-global mapping of dofs on a cell
+void meltflux_0_dof_map_1_1::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
+void meltflux_0_dof_map_1_1::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)
+void meltflux_0_dof_map_1_1::tabulate_entity_dofs(unsigned int* dofs,
+                                  unsigned int d, unsigned int i) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the coordinates of all dofs on a cell
+void meltflux_0_dof_map_1_1::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)
+unsigned int meltflux_0_dof_map_1_1::num_sub_dof_maps() const
+{
+    return 1;
+}
+
+/// Create a new dof_map for sub dof map i (for a mixed element)
+ufc::dof_map* meltflux_0_dof_map_1_1::create_sub_dof_map(unsigned int i) const
+{
+    return new meltflux_0_dof_map_1_1();
+}
+
+
+/// Constructor
+meltflux_0_dof_map_1::meltflux_0_dof_map_1() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+meltflux_0_dof_map_1::~meltflux_0_dof_map_1()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* meltflux_0_dof_map_1::signature() const
+{
+    return "FFC dof map for VectorElement('Lagrange', Cell('triangle', 1, Space(2)), 1, 2)";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool meltflux_0_dof_map_1::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)
+bool meltflux_0_dof_map_1::init_mesh(const ufc::mesh& m)
+{
+    __global_dimension = 2*m.num_entities[0];
+    return false;
+}
+
+/// Initialize dof map for given cell
+void meltflux_0_dof_map_1::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void meltflux_0_dof_map_1::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int meltflux_0_dof_map_1::global_dimension() const
+{
+    return __global_dimension;
+}
+
+/// Return the dimension of the local finite element function space for a cell
+unsigned int meltflux_0_dof_map_1::local_dimension(const ufc::cell& c) const
+{
+    return 6;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int meltflux_0_dof_map_1::max_local_dimension() const
+{
+    return 6;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int meltflux_0_dof_map_1::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int meltflux_0_dof_map_1::num_facet_dofs() const
+{
+    return 4;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int meltflux_0_dof_map_1::num_entity_dofs(unsigned int d) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the local-to-global mapping of dofs on a cell
+void meltflux_0_dof_map_1::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];
+    unsigned int offset = m.num_entities[0];
+    dofs[3] = offset + c.entity_indices[0][0];
+    dofs[4] = offset + c.entity_indices[0][1];
+    dofs[5] = offset + c.entity_indices[0][2];
+}
+
+/// Tabulate the local-to-local mapping from facet dofs to cell dofs
+void meltflux_0_dof_map_1::tabulate_facet_dofs(unsigned int* dofs,
+                                        unsigned int facet) const
+{
+    switch ( facet )
+    {
+    case 0:
+      dofs[0] = 1;
+      dofs[1] = 2;
+      dofs[2] = 4;
+      dofs[3] = 5;
+      break;
+    case 1:
+      dofs[0] = 0;
+      dofs[1] = 2;
+      dofs[2] = 3;
+      dofs[3] = 5;
+      break;
+    case 2:
+      dofs[0] = 0;
+      dofs[1] = 1;
+      dofs[2] = 3;
+      dofs[3] = 4;
+      break;
+    }
+}
+
+/// Tabulate the local-to-local mapping of dofs on entity (d, i)
+void meltflux_0_dof_map_1::tabulate_entity_dofs(unsigned int* dofs,
+                                  unsigned int d, unsigned int i) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the coordinates of all dofs on a cell
+void meltflux_0_dof_map_1::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];
+    coordinates[3][0] = x[0][0];
+    coordinates[3][1] = x[0][1];
+    coordinates[4][0] = x[1][0];
+    coordinates[4][1] = x[1][1];
+    coordinates[5][0] = x[2][0];
+    coordinates[5][1] = x[2][1];
+}
+
+/// Return the number of sub dof maps (for a mixed element)
+unsigned int meltflux_0_dof_map_1::num_sub_dof_maps() const
+{
+    return 2;
+}
+
+/// Create a new dof_map for sub dof map i (for a mixed element)
+ufc::dof_map* meltflux_0_dof_map_1::create_sub_dof_map(unsigned int i) const
+{
+    switch ( i )
+    {
+    case 0:
+      return new meltflux_0_dof_map_1_0();
+      break;
+    case 1:
+      return new meltflux_0_dof_map_1_1();
+      break;
+    }
+    return 0;
+}
+
+
+/// Constructor
+meltflux_0_cell_integral_0_quadrature::meltflux_0_cell_integral_0_quadrature() : ufc::cell_integral()
+{
+    // Do nothing
+}
+
+/// Destructor
+meltflux_0_cell_integral_0_quadrature::~meltflux_0_cell_integral_0_quadrature()
+{
+    // Do nothing
+}
+
+/// Tabulate the tensor for the contribution from a local cell
+void meltflux_0_cell_integral_0_quadrature::tabulate_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.0909793091280113, 0.159020690871988, 0.0909793091280113};
+    // Quadrature points on the UFC reference element: (0.178558728263616, 0.155051025721682), (0.0750311102226081, 0.644948974278318), (0.666390246014701, 0.155051025721682), (0.280019915499074, 0.644948974278318)
+    
+    // Value of basis functions at quadrature points.
+    static const double FE0_C0[4][3] = \
+    {{0.666390246014701, 0.178558728263616, 0.155051025721682},
+    {0.280019915499074, 0.0750311102226082, 0.644948974278318},
+    {0.178558728263616, 0.666390246014701, 0.155051025721682},
+    {0.0750311102226081, 0.280019915499074, 0.644948974278318}};
+    
+    // Array of non-zero columns
+    static const unsigned int nzc1[3] = {3, 4, 5};
+    // Array of non-zero columns
+    static const unsigned int nzc0[3] = {0, 1, 2};
+    
+    // Compute element tensor using UFL quadrature representation
+    // Optimisations: ('simplify expressions', True), ('ignore zero tables', True), ('non zero columns', True), ('remove zero terms', True), ('ignore ones', True)
+    // Total number of operations to compute element tensor: 220
+    
+    // Loop quadrature points for integral
+    // Number of operations to compute element tensor for following IP loop = 220
+    for (unsigned int ip = 0; ip < 4; ip++)
+    {
+      
+      // Number of operations to compute ip constants: 1
+      // Number of operations: 1
+      const double Gip0 = W4[ip]*det;
+      
+      
+      // Number of operations for primary indices: 54
+      for (unsigned int j = 0; j < 3; j++)
+      {
+        for (unsigned int k = 0; k < 3; k++)
+        {
+          // Number of operations to compute entry: 3
+          A[nzc1[j]*6 + nzc1[k]] += FE0_C0[ip][j]*FE0_C0[ip][k]*Gip0;
+          // Number of operations to compute entry: 3
+          A[nzc0[j]*6 + nzc0[k]] += FE0_C0[ip][j]*FE0_C0[ip][k]*Gip0;
+        }// end loop over 'k'
+      }// end loop over 'j'
+    }// end loop over 'ip'
+}
+
+/// Constructor
+meltflux_0_cell_integral_0::meltflux_0_cell_integral_0() : ufc::cell_integral()
+{
+    // Do nothing
+}
+
+/// Destructor
+meltflux_0_cell_integral_0::~meltflux_0_cell_integral_0()
+{
+    // Do nothing
+}
+
+/// Tabulate the tensor for the contribution from a local cell
+void meltflux_0_cell_integral_0::tabulate_tensor(double* A,
+                                    const double * const * w,
+                                    const ufc::cell& c) const
+{
+    // Reset values of the element tensor block
+    for (unsigned int j = 0; j < 36; j++)
+      A[j] = 0;
+    
+    // Add all contributions to element tensor
+    integral_0_quadrature.tabulate_tensor(A, w, c);
+}
+
+/// Constructor
+meltflux_form_0::meltflux_form_0() : ufc::form()
+{
+    // Do nothing
+}
+
+/// Destructor
+meltflux_form_0::~meltflux_form_0()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the form
+const char* meltflux_form_0::signature() const
+{
+    return "Form([Integral(IndexSum(Product(Indexed(BasisFunction(VectorElement('Lagrange', Cell('triangle', 1, Space(2)), 1, 2), 0), MultiIndex((Index(0),), {Index(0): 2})), Indexed(BasisFunction(VectorElement('Lagrange', Cell('triangle', 1, Space(2)), 1, 2), 1), MultiIndex((Index(0),), {Index(0): 2}))), MultiIndex((Index(0),), {Index(0): 2})), Measure('cell', 0, None))])";
+}
+
+/// Return the rank of the global tensor (r)
+unsigned int meltflux_form_0::rank() const
+{
+    return 2;
+}
+
+/// Return the number of coefficients (n)
+unsigned int meltflux_form_0::num_coefficients() const
+{
+    return 0;
+}
+
+/// Return the number of cell integrals
+unsigned int meltflux_form_0::num_cell_integrals() const
+{
+    return 1;
+}
+
+/// Return the number of exterior facet integrals
+unsigned int meltflux_form_0::num_exterior_facet_integrals() const
+{
+    return 0;
+}
+
+/// Return the number of interior facet integrals
+unsigned int meltflux_form_0::num_interior_facet_integrals() const
+{
+    return 0;
+}
+
+/// Create a new finite element for argument function i
+ufc::finite_element* meltflux_form_0::create_finite_element(unsigned int i) const
+{
+    switch ( i )
+    {
+    case 0:
+      return new meltflux_0_finite_element_0();
+      break;
+    case 1:
+      return new meltflux_0_finite_element_1();
+      break;
+    }
+    return 0;
+}
+
+/// Create a new dof map for argument function i
+ufc::dof_map* meltflux_form_0::create_dof_map(unsigned int i) const
+{
+    switch ( i )
+    {
+    case 0:
+      return new meltflux_0_dof_map_0();
+      break;
+    case 1:
+      return new meltflux_0_dof_map_1();
+      break;
+    }
+    return 0;
+}
+
+/// Create a new cell integral on sub domain i
+ufc::cell_integral* meltflux_form_0::create_cell_integral(unsigned int i) const
+{
+    return new meltflux_0_cell_integral_0();
+}
+
+/// Create a new exterior facet integral on sub domain i
+ufc::exterior_facet_integral* meltflux_form_0::create_exterior_facet_integral(unsigned int i) const
+{
+    return 0;
+}
+
+/// Create a new interior facet integral on sub domain i
+ufc::interior_facet_integral* meltflux_form_0::create_interior_facet_integral(unsigned int i) const
+{
+    return 0;
+}
+
+
+/// Constructor
+meltflux_1_finite_element_0_0::meltflux_1_finite_element_0_0() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+meltflux_1_finite_element_0_0::~meltflux_1_finite_element_0_0()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* meltflux_1_finite_element_0_0::signature() const
+{
+    return "FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)";
+}
+
+/// Return the cell shape
+ufc::shape meltflux_1_finite_element_0_0::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int meltflux_1_finite_element_0_0::space_dimension() const
+{
+    return 3;
+}
+
+/// Return the rank of the value space
+unsigned int meltflux_1_finite_element_0_0::value_rank() const
+{
+    return 0;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int meltflux_1_finite_element_0_0::value_dimension(unsigned int i) const
+{
+    return 1;
+}
+
+/// Evaluate basis function i at given point in cell
+void meltflux_1_finite_element_0_0::evaluate_basis(unsigned int i,
+                                   double* values,
+                                   const double* coordinates,
+                                   const ufc::cell& c) const
+{
+    // Extract vertex coordinates
+    const double * const * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Reset values
+    *values = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_1_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    
+    // 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, 0.333333333333333}};
+    
+    // Extract relevant coefficients
+    const double coeff0_0 = coefficients0[dof][0];
+    const double coeff0_1 = coefficients0[dof][1];
+    const double coeff0_2 = coefficients0[dof][2];
+    
+    // Compute value(s)
+    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
+}
+
+/// Evaluate all basis functions at given point in cell
+void meltflux_1_finite_element_0_0::evaluate_basis_all(double* values,
+                                       const double* coordinates,
+                                       const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
+}
+
+/// Evaluate order n derivatives of basis function i at given point in cell
+void meltflux_1_finite_element_0_0::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 * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 2;
+    
+    
+    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
+    unsigned int **combinations = new unsigned int *[num_derivatives];
+    
+    for (unsigned int j = 0; j < num_derivatives; j++)
+    {
+      combinations[j] = new unsigned int [n];
+      for (unsigned int k = 0; k < n; k++)
+        combinations[j][k] = 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] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
+    
+    // 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
+    for (unsigned int j = 0; j < 1*num_derivatives; j++)
+      values[j] = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_1_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    
+    // 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, 0.333333333333333}};
+    
+    // Interesting (new) part
+    // Tables of derivatives of the polynomial base (transpose)
+    static const double dmats0[3][3] = \
+    {{0, 0, 0},
+    {4.89897948556636, 0, 0},
+    {0, 0, 0}};
+    
+    static const double dmats1[3][3] = \
+    {{0, 0, 0},
+    {2.44948974278318, 0, 0},
+    {4.24264068711928, 0, 0}};
+    
+    // Compute reference derivatives
+    // Declare pointer to array of derivatives on FIAT element
+    double *derivatives = new double [num_derivatives];
+    
+    // Declare coefficients
+    double coeff0_0 = 0;
+    double coeff0_1 = 0;
+    double coeff0_2 = 0;
+    
+    // Declare new coefficients
+    double new_coeff0_0 = 0;
+    double new_coeff0_1 = 0;
+    double new_coeff0_2 = 0;
+    
+    // Loop possible derivatives
+    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+    {
+      // Get values from coefficients array
+      new_coeff0_0 = coefficients0[dof][0];
+      new_coeff0_1 = coefficients0[dof][1];
+      new_coeff0_2 = coefficients0[dof][2];
+    
+      // Loop derivative order
+      for (unsigned int j = 0; j < n; j++)
+      {
+        // Update old coefficients
+        coeff0_0 = new_coeff0_0;
+        coeff0_1 = new_coeff0_1;
+        coeff0_2 = new_coeff0_2;
+    
+        if(combinations[deriv_num][j] == 0)
+        {
+          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
+          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
+          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
+        }
+        if(combinations[deriv_num][j] == 1)
+        {
+          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
+          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
+          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
+        }
+    
+      }
+      // Compute derivatives on reference element as dot product of coefficients and basisvalues
+      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
+    }
+    
+    // Transform derivatives back to physical element
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      for (unsigned int col = 0; col < num_derivatives; col++)
+      {
+        values[row] += transform[row][col]*derivatives[col];
+      }
+    }
+    // Delete pointer to array of derivatives on FIAT element
+    delete [] derivatives;
+    
+    // Delete pointer to array of combinations of derivatives and transform
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      delete [] combinations[row];
+      delete [] transform[row];
+    }
+    
+    delete [] combinations;
+    delete [] transform;
+}
+
+/// Evaluate order n derivatives of all basis functions at given point in cell
+void meltflux_1_finite_element_0_0::evaluate_basis_derivatives_all(unsigned int n,
+                                                   double* values,
+                                                   const double* coordinates,
+                                                   const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
+}
+
+/// Evaluate linear functional for dof i on the function f
+double meltflux_1_finite_element_0_0::evaluate_dof(unsigned int i,
+                                   const ufc::function& f,
+                                   const ufc::cell& c) const
+{
+    // The reference points, direction and weights:
+    static const double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
+    static const double W[3][1] = {{1}, {1}, {1}};
+    static const double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
+    
+    const double * const * x = c.coordinates;
+    double result = 0.0;
+    // Iterate over the points:
+    // Evaluate basis functions for affine mapping
+    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    
+    // Compute affine mapping y = F(X)
+    double y[2];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
+    
+    // Evaluate function at physical points
+    double values[1];
+    f.evaluate(values, y, c);
+    
+    // Map function values using appropriate mapping
+    // Affine map: Do nothing
+    
+    // Note that we do not map the weights (yet).
+    
+    // Take directional components
+    for(int k = 0; k < 1; k++)
+      result += values[k]*D[i][0][k];
+    // Multiply by weights
+    result *= W[i][0];
+    
+    return result;
+}
+
+/// Evaluate linear functionals for all dofs on the function f
+void meltflux_1_finite_element_0_0::evaluate_dofs(double* values,
+                                  const ufc::function& f,
+                                  const ufc::cell& c) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Interpolate vertex values from dof values
+void meltflux_1_finite_element_0_0::interpolate_vertex_values(double* vertex_values,
+                                              const double* dof_values,
+                                              const ufc::cell& c) const
+{
+    // Evaluate at vertices and use affine mapping
+    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)
+unsigned int meltflux_1_finite_element_0_0::num_sub_elements() const
+{
+    return 1;
+}
+
+/// Create a new finite element for sub element i (for a mixed element)
+ufc::finite_element* meltflux_1_finite_element_0_0::create_sub_element(unsigned int i) const
+{
+    return new meltflux_1_finite_element_0_0();
+}
+
+
+/// Constructor
+meltflux_1_finite_element_0_1::meltflux_1_finite_element_0_1() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+meltflux_1_finite_element_0_1::~meltflux_1_finite_element_0_1()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* meltflux_1_finite_element_0_1::signature() const
+{
+    return "FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)";
+}
+
+/// Return the cell shape
+ufc::shape meltflux_1_finite_element_0_1::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int meltflux_1_finite_element_0_1::space_dimension() const
+{
+    return 3;
+}
+
+/// Return the rank of the value space
+unsigned int meltflux_1_finite_element_0_1::value_rank() const
+{
+    return 0;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int meltflux_1_finite_element_0_1::value_dimension(unsigned int i) const
+{
+    return 1;
+}
+
+/// Evaluate basis function i at given point in cell
+void meltflux_1_finite_element_0_1::evaluate_basis(unsigned int i,
+                                   double* values,
+                                   const double* coordinates,
+                                   const ufc::cell& c) const
+{
+    // Extract vertex coordinates
+    const double * const * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Reset values
+    *values = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_1_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    
+    // 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, 0.333333333333333}};
+    
+    // Extract relevant coefficients
+    const double coeff0_0 = coefficients0[dof][0];
+    const double coeff0_1 = coefficients0[dof][1];
+    const double coeff0_2 = coefficients0[dof][2];
+    
+    // Compute value(s)
+    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
+}
+
+/// Evaluate all basis functions at given point in cell
+void meltflux_1_finite_element_0_1::evaluate_basis_all(double* values,
+                                       const double* coordinates,
+                                       const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
+}
+
+/// Evaluate order n derivatives of basis function i at given point in cell
+void meltflux_1_finite_element_0_1::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 * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 2;
+    
+    
+    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
+    unsigned int **combinations = new unsigned int *[num_derivatives];
+    
+    for (unsigned int j = 0; j < num_derivatives; j++)
+    {
+      combinations[j] = new unsigned int [n];
+      for (unsigned int k = 0; k < n; k++)
+        combinations[j][k] = 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] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
+    
+    // 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
+    for (unsigned int j = 0; j < 1*num_derivatives; j++)
+      values[j] = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_1_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    
+    // 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, 0.333333333333333}};
+    
+    // Interesting (new) part
+    // Tables of derivatives of the polynomial base (transpose)
+    static const double dmats0[3][3] = \
+    {{0, 0, 0},
+    {4.89897948556636, 0, 0},
+    {0, 0, 0}};
+    
+    static const double dmats1[3][3] = \
+    {{0, 0, 0},
+    {2.44948974278318, 0, 0},
+    {4.24264068711928, 0, 0}};
+    
+    // Compute reference derivatives
+    // Declare pointer to array of derivatives on FIAT element
+    double *derivatives = new double [num_derivatives];
+    
+    // Declare coefficients
+    double coeff0_0 = 0;
+    double coeff0_1 = 0;
+    double coeff0_2 = 0;
+    
+    // Declare new coefficients
+    double new_coeff0_0 = 0;
+    double new_coeff0_1 = 0;
+    double new_coeff0_2 = 0;
+    
+    // Loop possible derivatives
+    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+    {
+      // Get values from coefficients array
+      new_coeff0_0 = coefficients0[dof][0];
+      new_coeff0_1 = coefficients0[dof][1];
+      new_coeff0_2 = coefficients0[dof][2];
+    
+      // Loop derivative order
+      for (unsigned int j = 0; j < n; j++)
+      {
+        // Update old coefficients
+        coeff0_0 = new_coeff0_0;
+        coeff0_1 = new_coeff0_1;
+        coeff0_2 = new_coeff0_2;
+    
+        if(combinations[deriv_num][j] == 0)
+        {
+          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
+          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
+          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
+        }
+        if(combinations[deriv_num][j] == 1)
+        {
+          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
+          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
+          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
+        }
+    
+      }
+      // Compute derivatives on reference element as dot product of coefficients and basisvalues
+      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
+    }
+    
+    // Transform derivatives back to physical element
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      for (unsigned int col = 0; col < num_derivatives; col++)
+      {
+        values[row] += transform[row][col]*derivatives[col];
+      }
+    }
+    // Delete pointer to array of derivatives on FIAT element
+    delete [] derivatives;
+    
+    // Delete pointer to array of combinations of derivatives and transform
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      delete [] combinations[row];
+      delete [] transform[row];
+    }
+    
+    delete [] combinations;
+    delete [] transform;
+}
+
+/// Evaluate order n derivatives of all basis functions at given point in cell
+void meltflux_1_finite_element_0_1::evaluate_basis_derivatives_all(unsigned int n,
+                                                   double* values,
+                                                   const double* coordinates,
+                                                   const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
+}
+
+/// Evaluate linear functional for dof i on the function f
+double meltflux_1_finite_element_0_1::evaluate_dof(unsigned int i,
+                                   const ufc::function& f,
+                                   const ufc::cell& c) const
+{
+    // The reference points, direction and weights:
+    static const double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
+    static const double W[3][1] = {{1}, {1}, {1}};
+    static const double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
+    
+    const double * const * x = c.coordinates;
+    double result = 0.0;
+    // Iterate over the points:
+    // Evaluate basis functions for affine mapping
+    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    
+    // Compute affine mapping y = F(X)
+    double y[2];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
+    
+    // Evaluate function at physical points
+    double values[1];
+    f.evaluate(values, y, c);
+    
+    // Map function values using appropriate mapping
+    // Affine map: Do nothing
+    
+    // Note that we do not map the weights (yet).
+    
+    // Take directional components
+    for(int k = 0; k < 1; k++)
+      result += values[k]*D[i][0][k];
+    // Multiply by weights
+    result *= W[i][0];
+    
+    return result;
+}
+
+/// Evaluate linear functionals for all dofs on the function f
+void meltflux_1_finite_element_0_1::evaluate_dofs(double* values,
+                                  const ufc::function& f,
+                                  const ufc::cell& c) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Interpolate vertex values from dof values
+void meltflux_1_finite_element_0_1::interpolate_vertex_values(double* vertex_values,
+                                              const double* dof_values,
+                                              const ufc::cell& c) const
+{
+    // Evaluate at vertices and use affine mapping
+    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)
+unsigned int meltflux_1_finite_element_0_1::num_sub_elements() const
+{
+    return 1;
+}
+
+/// Create a new finite element for sub element i (for a mixed element)
+ufc::finite_element* meltflux_1_finite_element_0_1::create_sub_element(unsigned int i) const
+{
+    return new meltflux_1_finite_element_0_1();
+}
+
+
+/// Constructor
+meltflux_1_finite_element_0::meltflux_1_finite_element_0() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+meltflux_1_finite_element_0::~meltflux_1_finite_element_0()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* meltflux_1_finite_element_0::signature() const
+{
+    return "VectorElement('Lagrange', Cell('triangle', 1, Space(2)), 1, 2)";
+}
+
+/// Return the cell shape
+ufc::shape meltflux_1_finite_element_0::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int meltflux_1_finite_element_0::space_dimension() const
+{
+    return 6;
+}
+
+/// Return the rank of the value space
+unsigned int meltflux_1_finite_element_0::value_rank() const
+{
+    return 1;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int meltflux_1_finite_element_0::value_dimension(unsigned int i) const
+{
+    return 2;
+}
+
+/// Evaluate basis function i at given point in cell
+void meltflux_1_finite_element_0::evaluate_basis(unsigned int i,
+                                   double* values,
+                                   const double* coordinates,
+                                   const ufc::cell& c) const
+{
+    // Extract vertex coordinates
+    const double * const * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Reset values
+    values[0] = 0;
+    values[1] = 0;
+    
+    if (0 <= i && i <= 2)
+    {
+      // Map degree of freedom to element degree of freedom
+      const unsigned int dof = i;
+    
+      // Generate scalings
+      const double scalings_y_0 = 1;
+      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    
+      // Compute psitilde_a
+      const double psitilde_a_0 = 1;
+      const double psitilde_a_1 = x;
+    
+      // Compute psitilde_bs
+      const double psitilde_bs_0_0 = 1;
+      const double psitilde_bs_0_1 = 1.5*y + 0.5;
+      const double psitilde_bs_1_0 = 1;
+    
+      // Compute basisvalues
+      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    
+      // 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, 0.333333333333333}};
+    
+      // Extract relevant coefficients
+      const double coeff0_0 =   coefficients0[dof][0];
+      const double coeff0_1 =   coefficients0[dof][1];
+      const double coeff0_2 =   coefficients0[dof][2];
+    
+      // Compute value(s)
+      values[0] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
+    }
+    
+    if (3 <= i && i <= 5)
+    {
+      // Map degree of freedom to element degree of freedom
+      const unsigned int dof = i - 3;
+    
+      // Generate scalings
+      const double scalings_y_0 = 1;
+      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    
+      // Compute psitilde_a
+      const double psitilde_a_0 = 1;
+      const double psitilde_a_1 = x;
+    
+      // Compute psitilde_bs
+      const double psitilde_bs_0_0 = 1;
+      const double psitilde_bs_0_1 = 1.5*y + 0.5;
+      const double psitilde_bs_1_0 = 1;
+    
+      // Compute basisvalues
+      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    
+      // 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, 0.333333333333333}};
+    
+      // Extract relevant coefficients
+      const double coeff0_0 =   coefficients0[dof][0];
+      const double coeff0_1 =   coefficients0[dof][1];
+      const double coeff0_2 =   coefficients0[dof][2];
+    
+      // Compute value(s)
+      values[1] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
+    }
+    
+}
+
+/// Evaluate all basis functions at given point in cell
+void meltflux_1_finite_element_0::evaluate_basis_all(double* values,
+                                       const double* coordinates,
+                                       const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
+}
+
+/// Evaluate order n derivatives of basis function i at given point in cell
+void meltflux_1_finite_element_0::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 * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 2;
+    
+    
+    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
+    unsigned int **combinations = new unsigned int *[num_derivatives];
+    
+    for (unsigned int j = 0; j < num_derivatives; j++)
+    {
+      combinations[j] = new unsigned int [n];
+      for (unsigned int k = 0; k < n; k++)
+        combinations[j][k] = 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] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
+    
+    // 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
+    for (unsigned int j = 0; j < 2*num_derivatives; j++)
+      values[j] = 0;
+    
+    if (0 <= i && i <= 2)
+    {
+      // Map degree of freedom to element degree of freedom
+      const unsigned int dof = i;
+    
+      // Generate scalings
+      const double scalings_y_0 = 1;
+      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    
+      // Compute psitilde_a
+      const double psitilde_a_0 = 1;
+      const double psitilde_a_1 = x;
+    
+      // Compute psitilde_bs
+      const double psitilde_bs_0_0 = 1;
+      const double psitilde_bs_0_1 = 1.5*y + 0.5;
+      const double psitilde_bs_1_0 = 1;
+    
+      // Compute basisvalues
+      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    
+      // 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, 0.333333333333333}};
+    
+      // Interesting (new) part
+      // Tables of derivatives of the polynomial base (transpose)
+      static const double dmats0[3][3] =   \
+      {{0, 0, 0},
+      {4.89897948556636, 0, 0},
+      {0, 0, 0}};
+    
+      static const double dmats1[3][3] =   \
+      {{0, 0, 0},
+      {2.44948974278318, 0, 0},
+      {4.24264068711928, 0, 0}};
+    
+      // Compute reference derivatives
+      // Declare pointer to array of derivatives on FIAT element
+      double *derivatives = new double [num_derivatives];
+    
+      // Declare coefficients
+      double coeff0_0 = 0;
+      double coeff0_1 = 0;
+      double coeff0_2 = 0;
+    
+      // Declare new coefficients
+      double new_coeff0_0 = 0;
+      double new_coeff0_1 = 0;
+      double new_coeff0_2 = 0;
+    
+      // Loop possible derivatives
+      for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+      {
+        // Get values from coefficients array
+        new_coeff0_0 = coefficients0[dof][0];
+        new_coeff0_1 = coefficients0[dof][1];
+        new_coeff0_2 = coefficients0[dof][2];
+    
+        // Loop derivative order
+        for (unsigned int j = 0; j < n; j++)
+        {
+          // Update old coefficients
+          coeff0_0 = new_coeff0_0;
+          coeff0_1 = new_coeff0_1;
+          coeff0_2 = new_coeff0_2;
+    
+          if(combinations[deriv_num][j] == 0)
+          {
+            new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
+            new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
+            new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
+          }
+          if(combinations[deriv_num][j] == 1)
+          {
+            new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
+            new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
+            new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
+          }
+    
+        }
+        // Compute derivatives on reference element as dot product of coefficients and basisvalues
+        derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
+      }
+    
+      // Transform derivatives back to physical element
+      for (unsigned int row = 0; row < num_derivatives; row++)
+      {
+        for (unsigned int col = 0; col < num_derivatives; col++)
+        {
+          values[row] += transform[row][col]*derivatives[col];
+        }
+      }
+      // Delete pointer to array of derivatives on FIAT element
+      delete [] derivatives;
+    
+      // Delete pointer to array of combinations of derivatives and transform
+      for (unsigned int row = 0; row < num_derivatives; row++)
+      {
+        delete [] combinations[row];
+        delete [] transform[row];
+      }
+    
+      delete [] combinations;
+      delete [] transform;
+    }
+    
+    if (3 <= i && i <= 5)
+    {
+      // Map degree of freedom to element degree of freedom
+      const unsigned int dof = i - 3;
+    
+      // Generate scalings
+      const double scalings_y_0 = 1;
+      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    
+      // Compute psitilde_a
+      const double psitilde_a_0 = 1;
+      const double psitilde_a_1 = x;
+    
+      // Compute psitilde_bs
+      const double psitilde_bs_0_0 = 1;
+      const double psitilde_bs_0_1 = 1.5*y + 0.5;
+      const double psitilde_bs_1_0 = 1;
+    
+      // Compute basisvalues
+      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    
+      // 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, 0.333333333333333}};
+    
+      // Interesting (new) part
+      // Tables of derivatives of the polynomial base (transpose)
+      static const double dmats0[3][3] =   \
+      {{0, 0, 0},
+      {4.89897948556636, 0, 0},
+      {0, 0, 0}};
+    
+      static const double dmats1[3][3] =   \
+      {{0, 0, 0},
+      {2.44948974278318, 0, 0},
+      {4.24264068711928, 0, 0}};
+    
+      // Compute reference derivatives
+      // Declare pointer to array of derivatives on FIAT element
+      double *derivatives = new double [num_derivatives];
+    
+      // Declare coefficients
+      double coeff0_0 = 0;
+      double coeff0_1 = 0;
+      double coeff0_2 = 0;
+    
+      // Declare new coefficients
+      double new_coeff0_0 = 0;
+      double new_coeff0_1 = 0;
+      double new_coeff0_2 = 0;
+    
+      // Loop possible derivatives
+      for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+      {
+        // Get values from coefficients array
+        new_coeff0_0 = coefficients0[dof][0];
+        new_coeff0_1 = coefficients0[dof][1];
+        new_coeff0_2 = coefficients0[dof][2];
+    
+        // Loop derivative order
+        for (unsigned int j = 0; j < n; j++)
+        {
+          // Update old coefficients
+          coeff0_0 = new_coeff0_0;
+          coeff0_1 = new_coeff0_1;
+          coeff0_2 = new_coeff0_2;
+    
+          if(combinations[deriv_num][j] == 0)
+          {
+            new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
+            new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
+            new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
+          }
+          if(combinations[deriv_num][j] == 1)
+          {
+            new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
+            new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
+            new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
+          }
+    
+        }
+        // Compute derivatives on reference element as dot product of coefficients and basisvalues
+        derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
+      }
+    
+      // Transform derivatives back to physical element
+      for (unsigned int row = 0; row < num_derivatives; row++)
+      {
+        for (unsigned int col = 0; col < num_derivatives; col++)
+        {
+          values[num_derivatives + row] += transform[row][col]*derivatives[col];
+        }
+      }
+      // Delete pointer to array of derivatives on FIAT element
+      delete [] derivatives;
+    
+      // Delete pointer to array of combinations of derivatives and transform
+      for (unsigned int row = 0; row < num_derivatives; row++)
+      {
+        delete [] combinations[row];
+        delete [] transform[row];
+      }
+    
+      delete [] combinations;
+      delete [] transform;
+    }
+    
+}
+
+/// Evaluate order n derivatives of all basis functions at given point in cell
+void meltflux_1_finite_element_0::evaluate_basis_derivatives_all(unsigned int n,
+                                                   double* values,
+                                                   const double* coordinates,
+                                                   const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
+}
+
+/// Evaluate linear functional for dof i on the function f
+double meltflux_1_finite_element_0::evaluate_dof(unsigned int i,
+                                   const ufc::function& f,
+                                   const ufc::cell& c) const
+{
+    // The reference points, direction and weights:
+    static const double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0, 0}}, {{1, 0}}, {{0, 1}}};
+    static const double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
+    static const double D[6][1][2] = {{{1, 0}}, {{1, 0}}, {{1, 0}}, {{0, 1}}, {{0, 1}}, {{0, 1}}};
+    
+    const double * const * x = c.coordinates;
+    double result = 0.0;
+    // Iterate over the points:
+    // Evaluate basis functions for affine mapping
+    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    
+    // Compute affine mapping y = F(X)
+    double y[2];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
+    
+    // Evaluate function at physical points
+    double values[2];
+    f.evaluate(values, y, c);
+    
+    // Map function values using appropriate mapping
+    // Affine map: Do nothing
+    
+    // Note that we do not map the weights (yet).
+    
+    // Take directional components
+    for(int k = 0; k < 2; k++)
+      result += values[k]*D[i][0][k];
+    // Multiply by weights
+    result *= W[i][0];
+    
+    return result;
+}
+
+/// Evaluate linear functionals for all dofs on the function f
+void meltflux_1_finite_element_0::evaluate_dofs(double* values,
+                                  const ufc::function& f,
+                                  const ufc::cell& c) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Interpolate vertex values from dof values
+void meltflux_1_finite_element_0::interpolate_vertex_values(double* vertex_values,
+                                              const double* dof_values,
+                                              const ufc::cell& c) const
+{
+    // Evaluate at vertices and use affine mapping
+    vertex_values[0] = dof_values[0];
+    vertex_values[2] = dof_values[1];
+    vertex_values[4] = dof_values[2];
+    // Evaluate at vertices and use affine mapping
+    vertex_values[1] = dof_values[3];
+    vertex_values[3] = dof_values[4];
+    vertex_values[5] = dof_values[5];
+}
+
+/// Return the number of sub elements (for a mixed element)
+unsigned int meltflux_1_finite_element_0::num_sub_elements() const
+{
+    return 2;
+}
+
+/// Create a new finite element for sub element i (for a mixed element)
+ufc::finite_element* meltflux_1_finite_element_0::create_sub_element(unsigned int i) const
+{
+    switch ( i )
+    {
+    case 0:
+      return new meltflux_1_finite_element_0_0();
+      break;
+    case 1:
+      return new meltflux_1_finite_element_0_1();
+      break;
+    }
+    return 0;
+}
+
+
+/// Constructor
+meltflux_1_finite_element_1::meltflux_1_finite_element_1() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+meltflux_1_finite_element_1::~meltflux_1_finite_element_1()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* meltflux_1_finite_element_1::signature() const
+{
+    return "FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
+}
+
+/// Return the cell shape
+ufc::shape meltflux_1_finite_element_1::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int meltflux_1_finite_element_1::space_dimension() const
+{
+    return 6;
+}
+
+/// Return the rank of the value space
+unsigned int meltflux_1_finite_element_1::value_rank() const
+{
+    return 0;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int meltflux_1_finite_element_1::value_dimension(unsigned int i) const
+{
+    return 1;
+}
+
+/// Evaluate basis function i at given point in cell
+void meltflux_1_finite_element_1::evaluate_basis(unsigned int i,
+                                   double* values,
+                                   const double* coordinates,
+                                   const ufc::cell& c) const
+{
+    // Extract vertex coordinates
+    const double * const * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Reset values
+    *values = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+    const double psitilde_bs_1_0 = 1;
+    const double psitilde_bs_1_1 = 2.5*y + 1.5;
+    const double psitilde_bs_2_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+    const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+    const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[6][6] = \
+    {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+    {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+    {0, 0, 0.2, 0, 0, 0.163299316185545},
+    {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+    {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+    {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+    // Extract relevant coefficients
+    const double coeff0_0 = coefficients0[dof][0];
+    const double coeff0_1 = coefficients0[dof][1];
+    const double coeff0_2 = coefficients0[dof][2];
+    const double coeff0_3 = coefficients0[dof][3];
+    const double coeff0_4 = coefficients0[dof][4];
+    const double coeff0_5 = coefficients0[dof][5];
+    
+    // Compute value(s)
+    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
+}
+
+/// Evaluate all basis functions at given point in cell
+void meltflux_1_finite_element_1::evaluate_basis_all(double* values,
+                                       const double* coordinates,
+                                       const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
+}
+
+/// Evaluate order n derivatives of basis function i at given point in cell
+void meltflux_1_finite_element_1::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 * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 2;
+    
+    
+    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
+    unsigned int **combinations = new unsigned int *[num_derivatives];
+    
+    for (unsigned int j = 0; j < num_derivatives; j++)
+    {
+      combinations[j] = new unsigned int [n];
+      for (unsigned int k = 0; k < n; k++)
+        combinations[j][k] = 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] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
+    
+    // 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
+    for (unsigned int j = 0; j < 1*num_derivatives; j++)
+      values[j] = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+    const double psitilde_bs_1_0 = 1;
+    const double psitilde_bs_1_1 = 2.5*y + 1.5;
+    const double psitilde_bs_2_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+    const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+    const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[6][6] = \
+    {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+    {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+    {0, 0, 0.2, 0, 0, 0.163299316185545},
+    {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+    {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+    {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+    // Interesting (new) part
+    // Tables of derivatives of the polynomial base (transpose)
+    static const double dmats0[6][6] = \
+    {{0, 0, 0, 0, 0, 0},
+    {4.89897948556636, 0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0},
+    {0, 9.48683298050514, 0, 0, 0, 0},
+    {4, 0, 7.07106781186548, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0}};
+    
+    static const double dmats1[6][6] = \
+    {{0, 0, 0, 0, 0, 0},
+    {2.44948974278318, 0, 0, 0, 0, 0},
+    {4.24264068711928, 0, 0, 0, 0, 0},
+    {2.58198889747161, 4.74341649025257, -0.912870929175277, 0, 0, 0},
+    {2, 6.12372435695795, 3.53553390593274, 0, 0, 0},
+    {-2.3094010767585, 0, 8.16496580927726, 0, 0, 0}};
+    
+    // Compute reference derivatives
+    // Declare pointer to array of derivatives on FIAT element
+    double *derivatives = new double [num_derivatives];
+    
+    // Declare coefficients
+    double coeff0_0 = 0;
+    double coeff0_1 = 0;
+    double coeff0_2 = 0;
+    double coeff0_3 = 0;
+    double coeff0_4 = 0;
+    double coeff0_5 = 0;
+    
+    // Declare new coefficients
+    double new_coeff0_0 = 0;
+    double new_coeff0_1 = 0;
+    double new_coeff0_2 = 0;
+    double new_coeff0_3 = 0;
+    double new_coeff0_4 = 0;
+    double new_coeff0_5 = 0;
+    
+    // Loop possible derivatives
+    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+    {
+      // Get values from coefficients array
+      new_coeff0_0 = coefficients0[dof][0];
+      new_coeff0_1 = coefficients0[dof][1];
+      new_coeff0_2 = coefficients0[dof][2];
+      new_coeff0_3 = coefficients0[dof][3];
+      new_coeff0_4 = coefficients0[dof][4];
+      new_coeff0_5 = coefficients0[dof][5];
+    
+      // Loop derivative order
+      for (unsigned int j = 0; j < n; j++)
+      {
+        // Update old coefficients
+        coeff0_0 = new_coeff0_0;
+        coeff0_1 = new_coeff0_1;
+        coeff0_2 = new_coeff0_2;
+        coeff0_3 = new_coeff0_3;
+        coeff0_4 = new_coeff0_4;
+        coeff0_5 = new_coeff0_5;
+    
+        if(combinations[deriv_num][j] == 0)
+        {
+          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
+          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
+          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
+          new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
+          new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
+          new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
+        }
+        if(combinations[deriv_num][j] == 1)
+        {
+          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
+          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
+          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
+          new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
+          new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
+          new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
+        }
+    
+      }
+      // Compute derivatives on reference element as dot product of coefficients and basisvalues
+      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
+    }
+    
+    // Transform derivatives back to physical element
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      for (unsigned int col = 0; col < num_derivatives; col++)
+      {
+        values[row] += transform[row][col]*derivatives[col];
+      }
+    }
+    // Delete pointer to array of derivatives on FIAT element
+    delete [] derivatives;
+    
+    // Delete pointer to array of combinations of derivatives and transform
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      delete [] combinations[row];
+      delete [] transform[row];
+    }
+    
+    delete [] combinations;
+    delete [] transform;
+}
+
+/// Evaluate order n derivatives of all basis functions at given point in cell
+void meltflux_1_finite_element_1::evaluate_basis_derivatives_all(unsigned int n,
+                                                   double* values,
+                                                   const double* coordinates,
+                                                   const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
+}
+
+/// Evaluate linear functional for dof i on the function f
+double meltflux_1_finite_element_1::evaluate_dof(unsigned int i,
+                                   const ufc::function& f,
+                                   const ufc::cell& c) const
+{
+    // The reference points, direction and weights:
+    static const double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}};
+    static const double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
+    static const double D[6][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}, {{1}}, {{1}}};
+    
+    const double * const * x = c.coordinates;
+    double result = 0.0;
+    // Iterate over the points:
+    // Evaluate basis functions for affine mapping
+    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    
+    // Compute affine mapping y = F(X)
+    double y[2];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
+    
+    // Evaluate function at physical points
+    double values[1];
+    f.evaluate(values, y, c);
+    
+    // Map function values using appropriate mapping
+    // Affine map: Do nothing
+    
+    // Note that we do not map the weights (yet).
+    
+    // Take directional components
+    for(int k = 0; k < 1; k++)
+      result += values[k]*D[i][0][k];
+    // Multiply by weights
+    result *= W[i][0];
+    
+    return result;
+}
+
+/// Evaluate linear functionals for all dofs on the function f
+void meltflux_1_finite_element_1::evaluate_dofs(double* values,
+                                  const ufc::function& f,
+                                  const ufc::cell& c) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Interpolate vertex values from dof values
+void meltflux_1_finite_element_1::interpolate_vertex_values(double* vertex_values,
+                                              const double* dof_values,
+                                              const ufc::cell& c) const
+{
+    // Evaluate at vertices and use affine mapping
+    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)
+unsigned int meltflux_1_finite_element_1::num_sub_elements() const
+{
+    return 1;
+}
+
+/// Create a new finite element for sub element i (for a mixed element)
+ufc::finite_element* meltflux_1_finite_element_1::create_sub_element(unsigned int i) const
+{
+    return new meltflux_1_finite_element_1();
+}
+
+
+/// Constructor
+meltflux_1_finite_element_2::meltflux_1_finite_element_2() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+meltflux_1_finite_element_2::~meltflux_1_finite_element_2()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* meltflux_1_finite_element_2::signature() const
+{
+    return "FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
+}
+
+/// Return the cell shape
+ufc::shape meltflux_1_finite_element_2::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int meltflux_1_finite_element_2::space_dimension() const
+{
+    return 6;
+}
+
+/// Return the rank of the value space
+unsigned int meltflux_1_finite_element_2::value_rank() const
+{
+    return 0;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int meltflux_1_finite_element_2::value_dimension(unsigned int i) const
+{
+    return 1;
+}
+
+/// Evaluate basis function i at given point in cell
+void meltflux_1_finite_element_2::evaluate_basis(unsigned int i,
+                                   double* values,
+                                   const double* coordinates,
+                                   const ufc::cell& c) const
+{
+    // Extract vertex coordinates
+    const double * const * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Reset values
+    *values = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+    const double psitilde_bs_1_0 = 1;
+    const double psitilde_bs_1_1 = 2.5*y + 1.5;
+    const double psitilde_bs_2_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+    const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+    const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[6][6] = \
+    {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+    {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+    {0, 0, 0.2, 0, 0, 0.163299316185545},
+    {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+    {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+    {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+    // Extract relevant coefficients
+    const double coeff0_0 = coefficients0[dof][0];
+    const double coeff0_1 = coefficients0[dof][1];
+    const double coeff0_2 = coefficients0[dof][2];
+    const double coeff0_3 = coefficients0[dof][3];
+    const double coeff0_4 = coefficients0[dof][4];
+    const double coeff0_5 = coefficients0[dof][5];
+    
+    // Compute value(s)
+    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
+}
+
+/// Evaluate all basis functions at given point in cell
+void meltflux_1_finite_element_2::evaluate_basis_all(double* values,
+                                       const double* coordinates,
+                                       const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
+}
+
+/// Evaluate order n derivatives of basis function i at given point in cell
+void meltflux_1_finite_element_2::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 * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 2;
+    
+    
+    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
+    unsigned int **combinations = new unsigned int *[num_derivatives];
+    
+    for (unsigned int j = 0; j < num_derivatives; j++)
+    {
+      combinations[j] = new unsigned int [n];
+      for (unsigned int k = 0; k < n; k++)
+        combinations[j][k] = 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] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
+    
+    // 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
+    for (unsigned int j = 0; j < 1*num_derivatives; j++)
+      values[j] = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+    const double psitilde_bs_1_0 = 1;
+    const double psitilde_bs_1_1 = 2.5*y + 1.5;
+    const double psitilde_bs_2_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+    const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+    const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[6][6] = \
+    {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+    {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+    {0, 0, 0.2, 0, 0, 0.163299316185545},
+    {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+    {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+    {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+    // Interesting (new) part
+    // Tables of derivatives of the polynomial base (transpose)
+    static const double dmats0[6][6] = \
+    {{0, 0, 0, 0, 0, 0},
+    {4.89897948556636, 0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0},
+    {0, 9.48683298050514, 0, 0, 0, 0},
+    {4, 0, 7.07106781186548, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0}};
+    
+    static const double dmats1[6][6] = \
+    {{0, 0, 0, 0, 0, 0},
+    {2.44948974278318, 0, 0, 0, 0, 0},
+    {4.24264068711928, 0, 0, 0, 0, 0},
+    {2.58198889747161, 4.74341649025257, -0.912870929175277, 0, 0, 0},
+    {2, 6.12372435695795, 3.53553390593274, 0, 0, 0},
+    {-2.3094010767585, 0, 8.16496580927726, 0, 0, 0}};
+    
+    // Compute reference derivatives
+    // Declare pointer to array of derivatives on FIAT element
+    double *derivatives = new double [num_derivatives];
+    
+    // Declare coefficients
+    double coeff0_0 = 0;
+    double coeff0_1 = 0;
+    double coeff0_2 = 0;
+    double coeff0_3 = 0;
+    double coeff0_4 = 0;
+    double coeff0_5 = 0;
+    
+    // Declare new coefficients
+    double new_coeff0_0 = 0;
+    double new_coeff0_1 = 0;
+    double new_coeff0_2 = 0;
+    double new_coeff0_3 = 0;
+    double new_coeff0_4 = 0;
+    double new_coeff0_5 = 0;
+    
+    // Loop possible derivatives
+    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+    {
+      // Get values from coefficients array
+      new_coeff0_0 = coefficients0[dof][0];
+      new_coeff0_1 = coefficients0[dof][1];
+      new_coeff0_2 = coefficients0[dof][2];
+      new_coeff0_3 = coefficients0[dof][3];
+      new_coeff0_4 = coefficients0[dof][4];
+      new_coeff0_5 = coefficients0[dof][5];
+    
+      // Loop derivative order
+      for (unsigned int j = 0; j < n; j++)
+      {
+        // Update old coefficients
+        coeff0_0 = new_coeff0_0;
+        coeff0_1 = new_coeff0_1;
+        coeff0_2 = new_coeff0_2;
+        coeff0_3 = new_coeff0_3;
+        coeff0_4 = new_coeff0_4;
+        coeff0_5 = new_coeff0_5;
+    
+        if(combinations[deriv_num][j] == 0)
+        {
+          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
+          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
+          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
+          new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
+          new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
+          new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
+        }
+        if(combinations[deriv_num][j] == 1)
+        {
+          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
+          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
+          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
+          new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
+          new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
+          new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
+        }
+    
+      }
+      // Compute derivatives on reference element as dot product of coefficients and basisvalues
+      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
+    }
+    
+    // Transform derivatives back to physical element
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      for (unsigned int col = 0; col < num_derivatives; col++)
+      {
+        values[row] += transform[row][col]*derivatives[col];
+      }
+    }
+    // Delete pointer to array of derivatives on FIAT element
+    delete [] derivatives;
+    
+    // Delete pointer to array of combinations of derivatives and transform
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      delete [] combinations[row];
+      delete [] transform[row];
+    }
+    
+    delete [] combinations;
+    delete [] transform;
+}
+
+/// Evaluate order n derivatives of all basis functions at given point in cell
+void meltflux_1_finite_element_2::evaluate_basis_derivatives_all(unsigned int n,
+                                                   double* values,
+                                                   const double* coordinates,
+                                                   const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
+}
+
+/// Evaluate linear functional for dof i on the function f
+double meltflux_1_finite_element_2::evaluate_dof(unsigned int i,
+                                   const ufc::function& f,
+                                   const ufc::cell& c) const
+{
+    // The reference points, direction and weights:
+    static const double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}};
+    static const double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
+    static const double D[6][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}, {{1}}, {{1}}};
+    
+    const double * const * x = c.coordinates;
+    double result = 0.0;
+    // Iterate over the points:
+    // Evaluate basis functions for affine mapping
+    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    
+    // Compute affine mapping y = F(X)
+    double y[2];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
+    
+    // Evaluate function at physical points
+    double values[1];
+    f.evaluate(values, y, c);
+    
+    // Map function values using appropriate mapping
+    // Affine map: Do nothing
+    
+    // Note that we do not map the weights (yet).
+    
+    // Take directional components
+    for(int k = 0; k < 1; k++)
+      result += values[k]*D[i][0][k];
+    // Multiply by weights
+    result *= W[i][0];
+    
+    return result;
+}
+
+/// Evaluate linear functionals for all dofs on the function f
+void meltflux_1_finite_element_2::evaluate_dofs(double* values,
+                                  const ufc::function& f,
+                                  const ufc::cell& c) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Interpolate vertex values from dof values
+void meltflux_1_finite_element_2::interpolate_vertex_values(double* vertex_values,
+                                              const double* dof_values,
+                                              const ufc::cell& c) const
+{
+    // Evaluate at vertices and use affine mapping
+    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)
+unsigned int meltflux_1_finite_element_2::num_sub_elements() const
+{
+    return 1;
+}
+
+/// Create a new finite element for sub element i (for a mixed element)
+ufc::finite_element* meltflux_1_finite_element_2::create_sub_element(unsigned int i) const
+{
+    return new meltflux_1_finite_element_2();
+}
+
+
+/// Constructor
+meltflux_1_finite_element_3::meltflux_1_finite_element_3() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+meltflux_1_finite_element_3::~meltflux_1_finite_element_3()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* meltflux_1_finite_element_3::signature() const
+{
+    return "FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)";
+}
+
+/// Return the cell shape
+ufc::shape meltflux_1_finite_element_3::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int meltflux_1_finite_element_3::space_dimension() const
+{
+    return 3;
+}
+
+/// Return the rank of the value space
+unsigned int meltflux_1_finite_element_3::value_rank() const
+{
+    return 0;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int meltflux_1_finite_element_3::value_dimension(unsigned int i) const
+{
+    return 1;
+}
+
+/// Evaluate basis function i at given point in cell
+void meltflux_1_finite_element_3::evaluate_basis(unsigned int i,
+                                   double* values,
+                                   const double* coordinates,
+                                   const ufc::cell& c) const
+{
+    // Extract vertex coordinates
+    const double * const * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Reset values
+    *values = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_1_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    
+    // 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, 0.333333333333333}};
+    
+    // Extract relevant coefficients
+    const double coeff0_0 = coefficients0[dof][0];
+    const double coeff0_1 = coefficients0[dof][1];
+    const double coeff0_2 = coefficients0[dof][2];
+    
+    // Compute value(s)
+    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
+}
+
+/// Evaluate all basis functions at given point in cell
+void meltflux_1_finite_element_3::evaluate_basis_all(double* values,
+                                       const double* coordinates,
+                                       const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
+}
+
+/// Evaluate order n derivatives of basis function i at given point in cell
+void meltflux_1_finite_element_3::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 * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 2;
+    
+    
+    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
+    unsigned int **combinations = new unsigned int *[num_derivatives];
+    
+    for (unsigned int j = 0; j < num_derivatives; j++)
+    {
+      combinations[j] = new unsigned int [n];
+      for (unsigned int k = 0; k < n; k++)
+        combinations[j][k] = 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] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
+    
+    // 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
+    for (unsigned int j = 0; j < 1*num_derivatives; j++)
+      values[j] = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_1_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    
+    // 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, 0.333333333333333}};
+    
+    // Interesting (new) part
+    // Tables of derivatives of the polynomial base (transpose)
+    static const double dmats0[3][3] = \
+    {{0, 0, 0},
+    {4.89897948556636, 0, 0},
+    {0, 0, 0}};
+    
+    static const double dmats1[3][3] = \
+    {{0, 0, 0},
+    {2.44948974278318, 0, 0},
+    {4.24264068711928, 0, 0}};
+    
+    // Compute reference derivatives
+    // Declare pointer to array of derivatives on FIAT element
+    double *derivatives = new double [num_derivatives];
+    
+    // Declare coefficients
+    double coeff0_0 = 0;
+    double coeff0_1 = 0;
+    double coeff0_2 = 0;
+    
+    // Declare new coefficients
+    double new_coeff0_0 = 0;
+    double new_coeff0_1 = 0;
+    double new_coeff0_2 = 0;
+    
+    // Loop possible derivatives
+    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+    {
+      // Get values from coefficients array
+      new_coeff0_0 = coefficients0[dof][0];
+      new_coeff0_1 = coefficients0[dof][1];
+      new_coeff0_2 = coefficients0[dof][2];
+    
+      // Loop derivative order
+      for (unsigned int j = 0; j < n; j++)
+      {
+        // Update old coefficients
+        coeff0_0 = new_coeff0_0;
+        coeff0_1 = new_coeff0_1;
+        coeff0_2 = new_coeff0_2;
+    
+        if(combinations[deriv_num][j] == 0)
+        {
+          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
+          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
+          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
+        }
+        if(combinations[deriv_num][j] == 1)
+        {
+          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
+          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
+          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
+        }
+    
+      }
+      // Compute derivatives on reference element as dot product of coefficients and basisvalues
+      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
+    }
+    
+    // Transform derivatives back to physical element
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      for (unsigned int col = 0; col < num_derivatives; col++)
+      {
+        values[row] += transform[row][col]*derivatives[col];
+      }
+    }
+    // Delete pointer to array of derivatives on FIAT element
+    delete [] derivatives;
+    
+    // Delete pointer to array of combinations of derivatives and transform
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      delete [] combinations[row];
+      delete [] transform[row];
+    }
+    
+    delete [] combinations;
+    delete [] transform;
+}
+
+/// Evaluate order n derivatives of all basis functions at given point in cell
+void meltflux_1_finite_element_3::evaluate_basis_derivatives_all(unsigned int n,
+                                                   double* values,
+                                                   const double* coordinates,
+                                                   const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
+}
+
+/// Evaluate linear functional for dof i on the function f
+double meltflux_1_finite_element_3::evaluate_dof(unsigned int i,
+                                   const ufc::function& f,
+                                   const ufc::cell& c) const
+{
+    // The reference points, direction and weights:
+    static const double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
+    static const double W[3][1] = {{1}, {1}, {1}};
+    static const double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
+    
+    const double * const * x = c.coordinates;
+    double result = 0.0;
+    // Iterate over the points:
+    // Evaluate basis functions for affine mapping
+    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    
+    // Compute affine mapping y = F(X)
+    double y[2];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
+    
+    // Evaluate function at physical points
+    double values[1];
+    f.evaluate(values, y, c);
+    
+    // Map function values using appropriate mapping
+    // Affine map: Do nothing
+    
+    // Note that we do not map the weights (yet).
+    
+    // Take directional components
+    for(int k = 0; k < 1; k++)
+      result += values[k]*D[i][0][k];
+    // Multiply by weights
+    result *= W[i][0];
+    
+    return result;
+}
+
+/// Evaluate linear functionals for all dofs on the function f
+void meltflux_1_finite_element_3::evaluate_dofs(double* values,
+                                  const ufc::function& f,
+                                  const ufc::cell& c) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Interpolate vertex values from dof values
+void meltflux_1_finite_element_3::interpolate_vertex_values(double* vertex_values,
+                                              const double* dof_values,
+                                              const ufc::cell& c) const
+{
+    // Evaluate at vertices and use affine mapping
+    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)
+unsigned int meltflux_1_finite_element_3::num_sub_elements() const
+{
+    return 1;
+}
+
+/// Create a new finite element for sub element i (for a mixed element)
+ufc::finite_element* meltflux_1_finite_element_3::create_sub_element(unsigned int i) const
+{
+    return new meltflux_1_finite_element_3();
+}
+
+
+/// Constructor
+meltflux_1_finite_element_4_0::meltflux_1_finite_element_4_0() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+meltflux_1_finite_element_4_0::~meltflux_1_finite_element_4_0()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* meltflux_1_finite_element_4_0::signature() const
+{
+    return "FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
+}
+
+/// Return the cell shape
+ufc::shape meltflux_1_finite_element_4_0::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int meltflux_1_finite_element_4_0::space_dimension() const
+{
+    return 6;
+}
+
+/// Return the rank of the value space
+unsigned int meltflux_1_finite_element_4_0::value_rank() const
+{
+    return 0;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int meltflux_1_finite_element_4_0::value_dimension(unsigned int i) const
+{
+    return 1;
+}
+
+/// Evaluate basis function i at given point in cell
+void meltflux_1_finite_element_4_0::evaluate_basis(unsigned int i,
+                                   double* values,
+                                   const double* coordinates,
+                                   const ufc::cell& c) const
+{
+    // Extract vertex coordinates
+    const double * const * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Reset values
+    *values = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+    const double psitilde_bs_1_0 = 1;
+    const double psitilde_bs_1_1 = 2.5*y + 1.5;
+    const double psitilde_bs_2_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+    const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+    const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[6][6] = \
+    {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+    {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+    {0, 0, 0.2, 0, 0, 0.163299316185545},
+    {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+    {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+    {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+    // Extract relevant coefficients
+    const double coeff0_0 = coefficients0[dof][0];
+    const double coeff0_1 = coefficients0[dof][1];
+    const double coeff0_2 = coefficients0[dof][2];
+    const double coeff0_3 = coefficients0[dof][3];
+    const double coeff0_4 = coefficients0[dof][4];
+    const double coeff0_5 = coefficients0[dof][5];
+    
+    // Compute value(s)
+    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
+}
+
+/// Evaluate all basis functions at given point in cell
+void meltflux_1_finite_element_4_0::evaluate_basis_all(double* values,
+                                       const double* coordinates,
+                                       const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
+}
+
+/// Evaluate order n derivatives of basis function i at given point in cell
+void meltflux_1_finite_element_4_0::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 * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 2;
+    
+    
+    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
+    unsigned int **combinations = new unsigned int *[num_derivatives];
+    
+    for (unsigned int j = 0; j < num_derivatives; j++)
+    {
+      combinations[j] = new unsigned int [n];
+      for (unsigned int k = 0; k < n; k++)
+        combinations[j][k] = 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] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
+    
+    // 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
+    for (unsigned int j = 0; j < 1*num_derivatives; j++)
+      values[j] = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+    const double psitilde_bs_1_0 = 1;
+    const double psitilde_bs_1_1 = 2.5*y + 1.5;
+    const double psitilde_bs_2_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+    const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+    const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[6][6] = \
+    {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+    {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+    {0, 0, 0.2, 0, 0, 0.163299316185545},
+    {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+    {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+    {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+    // Interesting (new) part
+    // Tables of derivatives of the polynomial base (transpose)
+    static const double dmats0[6][6] = \
+    {{0, 0, 0, 0, 0, 0},
+    {4.89897948556636, 0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0},
+    {0, 9.48683298050514, 0, 0, 0, 0},
+    {4, 0, 7.07106781186548, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0}};
+    
+    static const double dmats1[6][6] = \
+    {{0, 0, 0, 0, 0, 0},
+    {2.44948974278318, 0, 0, 0, 0, 0},
+    {4.24264068711928, 0, 0, 0, 0, 0},
+    {2.58198889747161, 4.74341649025257, -0.912870929175277, 0, 0, 0},
+    {2, 6.12372435695795, 3.53553390593274, 0, 0, 0},
+    {-2.3094010767585, 0, 8.16496580927726, 0, 0, 0}};
+    
+    // Compute reference derivatives
+    // Declare pointer to array of derivatives on FIAT element
+    double *derivatives = new double [num_derivatives];
+    
+    // Declare coefficients
+    double coeff0_0 = 0;
+    double coeff0_1 = 0;
+    double coeff0_2 = 0;
+    double coeff0_3 = 0;
+    double coeff0_4 = 0;
+    double coeff0_5 = 0;
+    
+    // Declare new coefficients
+    double new_coeff0_0 = 0;
+    double new_coeff0_1 = 0;
+    double new_coeff0_2 = 0;
+    double new_coeff0_3 = 0;
+    double new_coeff0_4 = 0;
+    double new_coeff0_5 = 0;
+    
+    // Loop possible derivatives
+    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+    {
+      // Get values from coefficients array
+      new_coeff0_0 = coefficients0[dof][0];
+      new_coeff0_1 = coefficients0[dof][1];
+      new_coeff0_2 = coefficients0[dof][2];
+      new_coeff0_3 = coefficients0[dof][3];
+      new_coeff0_4 = coefficients0[dof][4];
+      new_coeff0_5 = coefficients0[dof][5];
+    
+      // Loop derivative order
+      for (unsigned int j = 0; j < n; j++)
+      {
+        // Update old coefficients
+        coeff0_0 = new_coeff0_0;
+        coeff0_1 = new_coeff0_1;
+        coeff0_2 = new_coeff0_2;
+        coeff0_3 = new_coeff0_3;
+        coeff0_4 = new_coeff0_4;
+        coeff0_5 = new_coeff0_5;
+    
+        if(combinations[deriv_num][j] == 0)
+        {
+          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
+          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
+          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
+          new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
+          new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
+          new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
+        }
+        if(combinations[deriv_num][j] == 1)
+        {
+          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
+          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
+          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
+          new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
+          new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
+          new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
+        }
+    
+      }
+      // Compute derivatives on reference element as dot product of coefficients and basisvalues
+      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
+    }
+    
+    // Transform derivatives back to physical element
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      for (unsigned int col = 0; col < num_derivatives; col++)
+      {
+        values[row] += transform[row][col]*derivatives[col];
+      }
+    }
+    // Delete pointer to array of derivatives on FIAT element
+    delete [] derivatives;
+    
+    // Delete pointer to array of combinations of derivatives and transform
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      delete [] combinations[row];
+      delete [] transform[row];
+    }
+    
+    delete [] combinations;
+    delete [] transform;
+}
+
+/// Evaluate order n derivatives of all basis functions at given point in cell
+void meltflux_1_finite_element_4_0::evaluate_basis_derivatives_all(unsigned int n,
+                                                   double* values,
+                                                   const double* coordinates,
+                                                   const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
+}
+
+/// Evaluate linear functional for dof i on the function f
+double meltflux_1_finite_element_4_0::evaluate_dof(unsigned int i,
+                                   const ufc::function& f,
+                                   const ufc::cell& c) const
+{
+    // The reference points, direction and weights:
+    static const double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}};
+    static const double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
+    static const double D[6][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}, {{1}}, {{1}}};
+    
+    const double * const * x = c.coordinates;
+    double result = 0.0;
+    // Iterate over the points:
+    // Evaluate basis functions for affine mapping
+    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    
+    // Compute affine mapping y = F(X)
+    double y[2];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
+    
+    // Evaluate function at physical points
+    double values[1];
+    f.evaluate(values, y, c);
+    
+    // Map function values using appropriate mapping
+    // Affine map: Do nothing
+    
+    // Note that we do not map the weights (yet).
+    
+    // Take directional components
+    for(int k = 0; k < 1; k++)
+      result += values[k]*D[i][0][k];
+    // Multiply by weights
+    result *= W[i][0];
+    
+    return result;
+}
+
+/// Evaluate linear functionals for all dofs on the function f
+void meltflux_1_finite_element_4_0::evaluate_dofs(double* values,
+                                  const ufc::function& f,
+                                  const ufc::cell& c) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Interpolate vertex values from dof values
+void meltflux_1_finite_element_4_0::interpolate_vertex_values(double* vertex_values,
+                                              const double* dof_values,
+                                              const ufc::cell& c) const
+{
+    // Evaluate at vertices and use affine mapping
+    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)
+unsigned int meltflux_1_finite_element_4_0::num_sub_elements() const
+{
+    return 1;
+}
+
+/// Create a new finite element for sub element i (for a mixed element)
+ufc::finite_element* meltflux_1_finite_element_4_0::create_sub_element(unsigned int i) const
+{
+    return new meltflux_1_finite_element_4_0();
+}
+
+
+/// Constructor
+meltflux_1_finite_element_4_1::meltflux_1_finite_element_4_1() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+meltflux_1_finite_element_4_1::~meltflux_1_finite_element_4_1()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* meltflux_1_finite_element_4_1::signature() const
+{
+    return "FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
+}
+
+/// Return the cell shape
+ufc::shape meltflux_1_finite_element_4_1::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int meltflux_1_finite_element_4_1::space_dimension() const
+{
+    return 6;
+}
+
+/// Return the rank of the value space
+unsigned int meltflux_1_finite_element_4_1::value_rank() const
+{
+    return 0;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int meltflux_1_finite_element_4_1::value_dimension(unsigned int i) const
+{
+    return 1;
+}
+
+/// Evaluate basis function i at given point in cell
+void meltflux_1_finite_element_4_1::evaluate_basis(unsigned int i,
+                                   double* values,
+                                   const double* coordinates,
+                                   const ufc::cell& c) const
+{
+    // Extract vertex coordinates
+    const double * const * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Reset values
+    *values = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+    const double psitilde_bs_1_0 = 1;
+    const double psitilde_bs_1_1 = 2.5*y + 1.5;
+    const double psitilde_bs_2_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+    const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+    const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[6][6] = \
+    {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+    {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+    {0, 0, 0.2, 0, 0, 0.163299316185545},
+    {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+    {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+    {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+    // Extract relevant coefficients
+    const double coeff0_0 = coefficients0[dof][0];
+    const double coeff0_1 = coefficients0[dof][1];
+    const double coeff0_2 = coefficients0[dof][2];
+    const double coeff0_3 = coefficients0[dof][3];
+    const double coeff0_4 = coefficients0[dof][4];
+    const double coeff0_5 = coefficients0[dof][5];
+    
+    // Compute value(s)
+    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
+}
+
+/// Evaluate all basis functions at given point in cell
+void meltflux_1_finite_element_4_1::evaluate_basis_all(double* values,
+                                       const double* coordinates,
+                                       const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
+}
+
+/// Evaluate order n derivatives of basis function i at given point in cell
+void meltflux_1_finite_element_4_1::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 * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 2;
+    
+    
+    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
+    unsigned int **combinations = new unsigned int *[num_derivatives];
+    
+    for (unsigned int j = 0; j < num_derivatives; j++)
+    {
+      combinations[j] = new unsigned int [n];
+      for (unsigned int k = 0; k < n; k++)
+        combinations[j][k] = 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] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
+    
+    // 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
+    for (unsigned int j = 0; j < 1*num_derivatives; j++)
+      values[j] = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+    const double psitilde_bs_1_0 = 1;
+    const double psitilde_bs_1_1 = 2.5*y + 1.5;
+    const double psitilde_bs_2_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+    const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+    const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[6][6] = \
+    {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+    {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+    {0, 0, 0.2, 0, 0, 0.163299316185545},
+    {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+    {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+    {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+    // Interesting (new) part
+    // Tables of derivatives of the polynomial base (transpose)
+    static const double dmats0[6][6] = \
+    {{0, 0, 0, 0, 0, 0},
+    {4.89897948556636, 0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0},
+    {0, 9.48683298050514, 0, 0, 0, 0},
+    {4, 0, 7.07106781186548, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0}};
+    
+    static const double dmats1[6][6] = \
+    {{0, 0, 0, 0, 0, 0},
+    {2.44948974278318, 0, 0, 0, 0, 0},
+    {4.24264068711928, 0, 0, 0, 0, 0},
+    {2.58198889747161, 4.74341649025257, -0.912870929175277, 0, 0, 0},
+    {2, 6.12372435695795, 3.53553390593274, 0, 0, 0},
+    {-2.3094010767585, 0, 8.16496580927726, 0, 0, 0}};
+    
+    // Compute reference derivatives
+    // Declare pointer to array of derivatives on FIAT element
+    double *derivatives = new double [num_derivatives];
+    
+    // Declare coefficients
+    double coeff0_0 = 0;
+    double coeff0_1 = 0;
+    double coeff0_2 = 0;
+    double coeff0_3 = 0;
+    double coeff0_4 = 0;
+    double coeff0_5 = 0;
+    
+    // Declare new coefficients
+    double new_coeff0_0 = 0;
+    double new_coeff0_1 = 0;
+    double new_coeff0_2 = 0;
+    double new_coeff0_3 = 0;
+    double new_coeff0_4 = 0;
+    double new_coeff0_5 = 0;
+    
+    // Loop possible derivatives
+    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+    {
+      // Get values from coefficients array
+      new_coeff0_0 = coefficients0[dof][0];
+      new_coeff0_1 = coefficients0[dof][1];
+      new_coeff0_2 = coefficients0[dof][2];
+      new_coeff0_3 = coefficients0[dof][3];
+      new_coeff0_4 = coefficients0[dof][4];
+      new_coeff0_5 = coefficients0[dof][5];
+    
+      // Loop derivative order
+      for (unsigned int j = 0; j < n; j++)
+      {
+        // Update old coefficients
+        coeff0_0 = new_coeff0_0;
+        coeff0_1 = new_coeff0_1;
+        coeff0_2 = new_coeff0_2;
+        coeff0_3 = new_coeff0_3;
+        coeff0_4 = new_coeff0_4;
+        coeff0_5 = new_coeff0_5;
+    
+        if(combinations[deriv_num][j] == 0)
+        {
+          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
+          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
+          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
+          new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
+          new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
+          new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
+        }
+        if(combinations[deriv_num][j] == 1)
+        {
+          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
+          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
+          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
+          new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
+          new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
+          new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
+        }
+    
+      }
+      // Compute derivatives on reference element as dot product of coefficients and basisvalues
+      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
+    }
+    
+    // Transform derivatives back to physical element
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      for (unsigned int col = 0; col < num_derivatives; col++)
+      {
+        values[row] += transform[row][col]*derivatives[col];
+      }
+    }
+    // Delete pointer to array of derivatives on FIAT element
+    delete [] derivatives;
+    
+    // Delete pointer to array of combinations of derivatives and transform
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      delete [] combinations[row];
+      delete [] transform[row];
+    }
+    
+    delete [] combinations;
+    delete [] transform;
+}
+
+/// Evaluate order n derivatives of all basis functions at given point in cell
+void meltflux_1_finite_element_4_1::evaluate_basis_derivatives_all(unsigned int n,
+                                                   double* values,
+                                                   const double* coordinates,
+                                                   const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
+}
+
+/// Evaluate linear functional for dof i on the function f
+double meltflux_1_finite_element_4_1::evaluate_dof(unsigned int i,
+                                   const ufc::function& f,
+                                   const ufc::cell& c) const
+{
+    // The reference points, direction and weights:
+    static const double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}};
+    static const double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
+    static const double D[6][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}, {{1}}, {{1}}};
+    
+    const double * const * x = c.coordinates;
+    double result = 0.0;
+    // Iterate over the points:
+    // Evaluate basis functions for affine mapping
+    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    
+    // Compute affine mapping y = F(X)
+    double y[2];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
+    
+    // Evaluate function at physical points
+    double values[1];
+    f.evaluate(values, y, c);
+    
+    // Map function values using appropriate mapping
+    // Affine map: Do nothing
+    
+    // Note that we do not map the weights (yet).
+    
+    // Take directional components
+    for(int k = 0; k < 1; k++)
+      result += values[k]*D[i][0][k];
+    // Multiply by weights
+    result *= W[i][0];
+    
+    return result;
+}
+
+/// Evaluate linear functionals for all dofs on the function f
+void meltflux_1_finite_element_4_1::evaluate_dofs(double* values,
+                                  const ufc::function& f,
+                                  const ufc::cell& c) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Interpolate vertex values from dof values
+void meltflux_1_finite_element_4_1::interpolate_vertex_values(double* vertex_values,
+                                              const double* dof_values,
+                                              const ufc::cell& c) const
+{
+    // Evaluate at vertices and use affine mapping
+    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)
+unsigned int meltflux_1_finite_element_4_1::num_sub_elements() const
+{
+    return 1;
+}
+
+/// Create a new finite element for sub element i (for a mixed element)
+ufc::finite_element* meltflux_1_finite_element_4_1::create_sub_element(unsigned int i) const
+{
+    return new meltflux_1_finite_element_4_1();
+}
+
+
+/// Constructor
+meltflux_1_finite_element_4::meltflux_1_finite_element_4() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+meltflux_1_finite_element_4::~meltflux_1_finite_element_4()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* meltflux_1_finite_element_4::signature() const
+{
+    return "VectorElement('Lagrange', Cell('triangle', 1, Space(2)), 2, 2)";
+}
+
+/// Return the cell shape
+ufc::shape meltflux_1_finite_element_4::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int meltflux_1_finite_element_4::space_dimension() const
+{
+    return 12;
+}
+
+/// Return the rank of the value space
+unsigned int meltflux_1_finite_element_4::value_rank() const
+{
+    return 1;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int meltflux_1_finite_element_4::value_dimension(unsigned int i) const
+{
+    return 2;
+}
+
+/// Evaluate basis function i at given point in cell
+void meltflux_1_finite_element_4::evaluate_basis(unsigned int i,
+                                   double* values,
+                                   const double* coordinates,
+                                   const ufc::cell& c) const
+{
+    // Extract vertex coordinates
+    const double * const * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Reset values
+    values[0] = 0;
+    values[1] = 0;
+    
+    if (0 <= i && i <= 5)
+    {
+      // Map degree of freedom to element degree of freedom
+      const unsigned int dof = i;
+    
+      // Generate scalings
+      const double scalings_y_0 = 1;
+      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+      const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+      // Compute psitilde_a
+      const double psitilde_a_0 = 1;
+      const double psitilde_a_1 = x;
+      const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+      // Compute psitilde_bs
+      const double psitilde_bs_0_0 = 1;
+      const double psitilde_bs_0_1 = 1.5*y + 0.5;
+      const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+      const double psitilde_bs_1_0 = 1;
+      const double psitilde_bs_1_1 = 2.5*y + 1.5;
+      const double psitilde_bs_2_0 = 1;
+    
+      // Compute basisvalues
+      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+      const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+      const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+      const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+      // Table(s) of coefficients
+      static const double coefficients0[6][6] =   \
+      {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+      {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+      {0, 0, 0.2, 0, 0, 0.163299316185545},
+      {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+      {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+      {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+      // Extract relevant coefficients
+      const double coeff0_0 =   coefficients0[dof][0];
+      const double coeff0_1 =   coefficients0[dof][1];
+      const double coeff0_2 =   coefficients0[dof][2];
+      const double coeff0_3 =   coefficients0[dof][3];
+      const double coeff0_4 =   coefficients0[dof][4];
+      const double coeff0_5 =   coefficients0[dof][5];
+    
+      // Compute value(s)
+      values[0] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
+    }
+    
+    if (6 <= i && i <= 11)
+    {
+      // Map degree of freedom to element degree of freedom
+      const unsigned int dof = i - 6;
+    
+      // Generate scalings
+      const double scalings_y_0 = 1;
+      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+      const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+      // Compute psitilde_a
+      const double psitilde_a_0 = 1;
+      const double psitilde_a_1 = x;
+      const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+      // Compute psitilde_bs
+      const double psitilde_bs_0_0 = 1;
+      const double psitilde_bs_0_1 = 1.5*y + 0.5;
+      const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+      const double psitilde_bs_1_0 = 1;
+      const double psitilde_bs_1_1 = 2.5*y + 1.5;
+      const double psitilde_bs_2_0 = 1;
+    
+      // Compute basisvalues
+      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+      const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+      const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+      const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+      // Table(s) of coefficients
+      static const double coefficients0[6][6] =   \
+      {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+      {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+      {0, 0, 0.2, 0, 0, 0.163299316185545},
+      {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+      {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+      {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+      // Extract relevant coefficients
+      const double coeff0_0 =   coefficients0[dof][0];
+      const double coeff0_1 =   coefficients0[dof][1];
+      const double coeff0_2 =   coefficients0[dof][2];
+      const double coeff0_3 =   coefficients0[dof][3];
+      const double coeff0_4 =   coefficients0[dof][4];
+      const double coeff0_5 =   coefficients0[dof][5];
+    
+      // Compute value(s)
+      values[1] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
+    }
+    
+}
+
+/// Evaluate all basis functions at given point in cell
+void meltflux_1_finite_element_4::evaluate_basis_all(double* values,
+                                       const double* coordinates,
+                                       const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
+}
+
+/// Evaluate order n derivatives of basis function i at given point in cell
+void meltflux_1_finite_element_4::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 * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 2;
+    
+    
+    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
+    unsigned int **combinations = new unsigned int *[num_derivatives];
+    
+    for (unsigned int j = 0; j < num_derivatives; j++)
+    {
+      combinations[j] = new unsigned int [n];
+      for (unsigned int k = 0; k < n; k++)
+        combinations[j][k] = 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] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
+    
+    // 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
+    for (unsigned int j = 0; j < 2*num_derivatives; j++)
+      values[j] = 0;
+    
+    if (0 <= i && i <= 5)
+    {
+      // Map degree of freedom to element degree of freedom
+      const unsigned int dof = i;
+    
+      // Generate scalings
+      const double scalings_y_0 = 1;
+      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+      const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+      // Compute psitilde_a
+      const double psitilde_a_0 = 1;
+      const double psitilde_a_1 = x;
+      const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+      // Compute psitilde_bs
+      const double psitilde_bs_0_0 = 1;
+      const double psitilde_bs_0_1 = 1.5*y + 0.5;
+      const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+      const double psitilde_bs_1_0 = 1;
+      const double psitilde_bs_1_1 = 2.5*y + 1.5;
+      const double psitilde_bs_2_0 = 1;
+    
+      // Compute basisvalues
+      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+      const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+      const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+      const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+      // Table(s) of coefficients
+      static const double coefficients0[6][6] =   \
+      {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+      {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+      {0, 0, 0.2, 0, 0, 0.163299316185545},
+      {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+      {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+      {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+      // Interesting (new) part
+      // Tables of derivatives of the polynomial base (transpose)
+      static const double dmats0[6][6] =   \
+      {{0, 0, 0, 0, 0, 0},
+      {4.89897948556636, 0, 0, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0},
+      {0, 9.48683298050514, 0, 0, 0, 0},
+      {4, 0, 7.07106781186548, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0}};
+    
+      static const double dmats1[6][6] =   \
+      {{0, 0, 0, 0, 0, 0},
+      {2.44948974278318, 0, 0, 0, 0, 0},
+      {4.24264068711928, 0, 0, 0, 0, 0},
+      {2.58198889747161, 4.74341649025257, -0.912870929175277, 0, 0, 0},
+      {2, 6.12372435695795, 3.53553390593274, 0, 0, 0},
+      {-2.3094010767585, 0, 8.16496580927726, 0, 0, 0}};
+    
+      // Compute reference derivatives
+      // Declare pointer to array of derivatives on FIAT element
+      double *derivatives = new double [num_derivatives];
+    
+      // Declare coefficients
+      double coeff0_0 = 0;
+      double coeff0_1 = 0;
+      double coeff0_2 = 0;
+      double coeff0_3 = 0;
+      double coeff0_4 = 0;
+      double coeff0_5 = 0;
+    
+      // Declare new coefficients
+      double new_coeff0_0 = 0;
+      double new_coeff0_1 = 0;
+      double new_coeff0_2 = 0;
+      double new_coeff0_3 = 0;
+      double new_coeff0_4 = 0;
+      double new_coeff0_5 = 0;
+    
+      // Loop possible derivatives
+      for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+      {
+        // Get values from coefficients array
+        new_coeff0_0 = coefficients0[dof][0];
+        new_coeff0_1 = coefficients0[dof][1];
+        new_coeff0_2 = coefficients0[dof][2];
+        new_coeff0_3 = coefficients0[dof][3];
+        new_coeff0_4 = coefficients0[dof][4];
+        new_coeff0_5 = coefficients0[dof][5];
+    
+        // Loop derivative order
+        for (unsigned int j = 0; j < n; j++)
+        {
+          // Update old coefficients
+          coeff0_0 = new_coeff0_0;
+          coeff0_1 = new_coeff0_1;
+          coeff0_2 = new_coeff0_2;
+          coeff0_3 = new_coeff0_3;
+          coeff0_4 = new_coeff0_4;
+          coeff0_5 = new_coeff0_5;
+    
+          if(combinations[deriv_num][j] == 0)
+          {
+            new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
+            new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
+            new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
+            new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
+            new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
+            new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
+          }
+          if(combinations[deriv_num][j] == 1)
+          {
+            new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
+            new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
+            new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
+            new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
+            new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
+            new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
+          }
+    
+        }
+        // Compute derivatives on reference element as dot product of coefficients and basisvalues
+        derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
+      }
+    
+      // Transform derivatives back to physical element
+      for (unsigned int row = 0; row < num_derivatives; row++)
+      {
+        for (unsigned int col = 0; col < num_derivatives; col++)
+        {
+          values[row] += transform[row][col]*derivatives[col];
+        }
+      }
+      // Delete pointer to array of derivatives on FIAT element
+      delete [] derivatives;
+    
+      // Delete pointer to array of combinations of derivatives and transform
+      for (unsigned int row = 0; row < num_derivatives; row++)
+      {
+        delete [] combinations[row];
+        delete [] transform[row];
+      }
+    
+      delete [] combinations;
+      delete [] transform;
+    }
+    
+    if (6 <= i && i <= 11)
+    {
+      // Map degree of freedom to element degree of freedom
+      const unsigned int dof = i - 6;
+    
+      // Generate scalings
+      const double scalings_y_0 = 1;
+      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+      const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+      // Compute psitilde_a
+      const double psitilde_a_0 = 1;
+      const double psitilde_a_1 = x;
+      const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+      // Compute psitilde_bs
+      const double psitilde_bs_0_0 = 1;
+      const double psitilde_bs_0_1 = 1.5*y + 0.5;
+      const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+      const double psitilde_bs_1_0 = 1;
+      const double psitilde_bs_1_1 = 2.5*y + 1.5;
+      const double psitilde_bs_2_0 = 1;
+    
+      // Compute basisvalues
+      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+      const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+      const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+      const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+      // Table(s) of coefficients
+      static const double coefficients0[6][6] =   \
+      {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+      {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+      {0, 0, 0.2, 0, 0, 0.163299316185545},
+      {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+      {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+      {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+      // Interesting (new) part
+      // Tables of derivatives of the polynomial base (transpose)
+      static const double dmats0[6][6] =   \
+      {{0, 0, 0, 0, 0, 0},
+      {4.89897948556636, 0, 0, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0},
+      {0, 9.48683298050514, 0, 0, 0, 0},
+      {4, 0, 7.07106781186548, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0}};
+    
+      static const double dmats1[6][6] =   \
+      {{0, 0, 0, 0, 0, 0},
+      {2.44948974278318, 0, 0, 0, 0, 0},
+      {4.24264068711928, 0, 0, 0, 0, 0},
+      {2.58198889747161, 4.74341649025257, -0.912870929175277, 0, 0, 0},
+      {2, 6.12372435695795, 3.53553390593274, 0, 0, 0},
+      {-2.3094010767585, 0, 8.16496580927726, 0, 0, 0}};
+    
+      // Compute reference derivatives
+      // Declare pointer to array of derivatives on FIAT element
+      double *derivatives = new double [num_derivatives];
+    
+      // Declare coefficients
+      double coeff0_0 = 0;
+      double coeff0_1 = 0;
+      double coeff0_2 = 0;
+      double coeff0_3 = 0;
+      double coeff0_4 = 0;
+      double coeff0_5 = 0;
+    
+      // Declare new coefficients
+      double new_coeff0_0 = 0;
+      double new_coeff0_1 = 0;
+      double new_coeff0_2 = 0;
+      double new_coeff0_3 = 0;
+      double new_coeff0_4 = 0;
+      double new_coeff0_5 = 0;
+    
+      // Loop possible derivatives
+      for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+      {
+        // Get values from coefficients array
+        new_coeff0_0 = coefficients0[dof][0];
+        new_coeff0_1 = coefficients0[dof][1];
+        new_coeff0_2 = coefficients0[dof][2];
+        new_coeff0_3 = coefficients0[dof][3];
+        new_coeff0_4 = coefficients0[dof][4];
+        new_coeff0_5 = coefficients0[dof][5];
+    
+        // Loop derivative order
+        for (unsigned int j = 0; j < n; j++)
+        {
+          // Update old coefficients
+          coeff0_0 = new_coeff0_0;
+          coeff0_1 = new_coeff0_1;
+          coeff0_2 = new_coeff0_2;
+          coeff0_3 = new_coeff0_3;
+          coeff0_4 = new_coeff0_4;
+          coeff0_5 = new_coeff0_5;
+    
+          if(combinations[deriv_num][j] == 0)
+          {
+            new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
+            new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
+            new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
+            new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
+            new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
+            new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
+          }
+          if(combinations[deriv_num][j] == 1)
+          {
+            new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
+            new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
+            new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
+            new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
+            new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
+            new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
+          }
+    
+        }
+        // Compute derivatives on reference element as dot product of coefficients and basisvalues
+        derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
+      }
+    
+      // Transform derivatives back to physical element
+      for (unsigned int row = 0; row < num_derivatives; row++)
+      {
+        for (unsigned int col = 0; col < num_derivatives; col++)
+        {
+          values[num_derivatives + row] += transform[row][col]*derivatives[col];
+        }
+      }
+      // Delete pointer to array of derivatives on FIAT element
+      delete [] derivatives;
+    
+      // Delete pointer to array of combinations of derivatives and transform
+      for (unsigned int row = 0; row < num_derivatives; row++)
+      {
+        delete [] combinations[row];
+        delete [] transform[row];
+      }
+    
+      delete [] combinations;
+      delete [] transform;
+    }
+    
+}
+
+/// Evaluate order n derivatives of all basis functions at given point in cell
+void meltflux_1_finite_element_4::evaluate_basis_derivatives_all(unsigned int n,
+                                                   double* values,
+                                                   const double* coordinates,
+                                                   const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
+}
+
+/// Evaluate linear functional for dof i on the function f
+double meltflux_1_finite_element_4::evaluate_dof(unsigned int i,
+                                   const ufc::function& f,
+                                   const ufc::cell& c) const
+{
+    // The reference points, direction and weights:
+    static const double X[12][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}, {{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}};
+    static const double W[12][1] = {{1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}};
+    static const double D[12][1][2] = {{{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{0, 1}}, {{0, 1}}, {{0, 1}}, {{0, 1}}, {{0, 1}}, {{0, 1}}};
+    
+    const double * const * x = c.coordinates;
+    double result = 0.0;
+    // Iterate over the points:
+    // Evaluate basis functions for affine mapping
+    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    
+    // Compute affine mapping y = F(X)
+    double y[2];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
+    
+    // Evaluate function at physical points
+    double values[2];
+    f.evaluate(values, y, c);
+    
+    // Map function values using appropriate mapping
+    // Affine map: Do nothing
+    
+    // Note that we do not map the weights (yet).
+    
+    // Take directional components
+    for(int k = 0; k < 2; k++)
+      result += values[k]*D[i][0][k];
+    // Multiply by weights
+    result *= W[i][0];
+    
+    return result;
+}
+
+/// Evaluate linear functionals for all dofs on the function f
+void meltflux_1_finite_element_4::evaluate_dofs(double* values,
+                                  const ufc::function& f,
+                                  const ufc::cell& c) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Interpolate vertex values from dof values
+void meltflux_1_finite_element_4::interpolate_vertex_values(double* vertex_values,
+                                              const double* dof_values,
+                                              const ufc::cell& c) const
+{
+    // Evaluate at vertices and use affine mapping
+    vertex_values[0] = dof_values[0];
+    vertex_values[2] = dof_values[1];
+    vertex_values[4] = dof_values[2];
+    // Evaluate at vertices and use affine mapping
+    vertex_values[1] = dof_values[6];
+    vertex_values[3] = dof_values[7];
+    vertex_values[5] = dof_values[8];
+}
+
+/// Return the number of sub elements (for a mixed element)
+unsigned int meltflux_1_finite_element_4::num_sub_elements() const
+{
+    return 2;
+}
+
+/// Create a new finite element for sub element i (for a mixed element)
+ufc::finite_element* meltflux_1_finite_element_4::create_sub_element(unsigned int i) const
+{
+    switch ( i )
+    {
+    case 0:
+      return new meltflux_1_finite_element_4_0();
+      break;
+    case 1:
+      return new meltflux_1_finite_element_4_1();
+      break;
+    }
+    return 0;
+}
+
+
+/// Constructor
+meltflux_1_finite_element_5::meltflux_1_finite_element_5() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+meltflux_1_finite_element_5::~meltflux_1_finite_element_5()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* meltflux_1_finite_element_5::signature() const
+{
+    return "FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 0)";
+}
+
+/// Return the cell shape
+ufc::shape meltflux_1_finite_element_5::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int meltflux_1_finite_element_5::space_dimension() const
+{
+    return 1;
+}
+
+/// Return the rank of the value space
+unsigned int meltflux_1_finite_element_5::value_rank() const
+{
+    return 0;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int meltflux_1_finite_element_5::value_dimension(unsigned int i) const
+{
+    return 1;
+}
+
+/// Evaluate basis function i at given point in cell
+void meltflux_1_finite_element_5::evaluate_basis(unsigned int i,
+                                   double* values,
+                                   const double* coordinates,
+                                   const ufc::cell& c) const
+{
+    // Extract vertex coordinates
+    const double * const * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Reset values
+    *values = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[1][1] = \
+    {{1.41421356237309}};
+    
+    // Extract relevant coefficients
+    const double coeff0_0 = coefficients0[dof][0];
+    
+    // Compute value(s)
+    *values = coeff0_0*basisvalue0;
+}
+
+/// Evaluate all basis functions at given point in cell
+void meltflux_1_finite_element_5::evaluate_basis_all(double* values,
+                                       const double* coordinates,
+                                       const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
+}
+
+/// Evaluate order n derivatives of basis function i at given point in cell
+void meltflux_1_finite_element_5::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 * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 2;
+    
+    
+    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
+    unsigned int **combinations = new unsigned int *[num_derivatives];
+    
+    for (unsigned int j = 0; j < num_derivatives; j++)
+    {
+      combinations[j] = new unsigned int [n];
+      for (unsigned int k = 0; k < n; k++)
+        combinations[j][k] = 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] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
+    
+    // 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
+    for (unsigned int j = 0; j < 1*num_derivatives; j++)
+      values[j] = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[1][1] = \
+    {{1.41421356237309}};
+    
+    // Interesting (new) part
+    // Tables of derivatives of the polynomial base (transpose)
+    static const double dmats0[1][1] = \
+    {{0}};
+    
+    static const double dmats1[1][1] = \
+    {{0}};
+    
+    // Compute reference derivatives
+    // Declare pointer to array of derivatives on FIAT element
+    double *derivatives = new double [num_derivatives];
+    
+    // Declare coefficients
+    double coeff0_0 = 0;
+    
+    // Declare new coefficients
+    double new_coeff0_0 = 0;
+    
+    // Loop possible derivatives
+    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+    {
+      // Get values from coefficients array
+      new_coeff0_0 = coefficients0[dof][0];
+    
+      // Loop derivative order
+      for (unsigned int j = 0; j < n; j++)
+      {
+        // Update old coefficients
+        coeff0_0 = new_coeff0_0;
+    
+        if(combinations[deriv_num][j] == 0)
+        {
+          new_coeff0_0 = coeff0_0*dmats0[0][0];
+        }
+        if(combinations[deriv_num][j] == 1)
+        {
+          new_coeff0_0 = coeff0_0*dmats1[0][0];
+        }
+    
+      }
+      // Compute derivatives on reference element as dot product of coefficients and basisvalues
+      derivatives[deriv_num] = new_coeff0_0*basisvalue0;
+    }
+    
+    // Transform derivatives back to physical element
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      for (unsigned int col = 0; col < num_derivatives; col++)
+      {
+        values[row] += transform[row][col]*derivatives[col];
+      }
+    }
+    // Delete pointer to array of derivatives on FIAT element
+    delete [] derivatives;
+    
+    // Delete pointer to array of combinations of derivatives and transform
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      delete [] combinations[row];
+      delete [] transform[row];
+    }
+    
+    delete [] combinations;
+    delete [] transform;
+}
+
+/// Evaluate order n derivatives of all basis functions at given point in cell
+void meltflux_1_finite_element_5::evaluate_basis_derivatives_all(unsigned int n,
+                                                   double* values,
+                                                   const double* coordinates,
+                                                   const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
+}
+
+/// Evaluate linear functional for dof i on the function f
+double meltflux_1_finite_element_5::evaluate_dof(unsigned int i,
+                                   const ufc::function& f,
+                                   const ufc::cell& c) const
+{
+    // The reference points, direction and weights:
+    static const double X[1][1][2] = {{{0.333333333333333, 0.333333333333333}}};
+    static const double W[1][1] = {{1}};
+    static const double D[1][1][1] = {{{1}}};
+    
+    const double * const * x = c.coordinates;
+    double result = 0.0;
+    // Iterate over the points:
+    // Evaluate basis functions for affine mapping
+    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    
+    // Compute affine mapping y = F(X)
+    double y[2];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
+    
+    // Evaluate function at physical points
+    double values[1];
+    f.evaluate(values, y, c);
+    
+    // Map function values using appropriate mapping
+    // Affine map: Do nothing
+    
+    // Note that we do not map the weights (yet).
+    
+    // Take directional components
+    for(int k = 0; k < 1; k++)
+      result += values[k]*D[i][0][k];
+    // Multiply by weights
+    result *= W[i][0];
+    
+    return result;
+}
+
+/// Evaluate linear functionals for all dofs on the function f
+void meltflux_1_finite_element_5::evaluate_dofs(double* values,
+                                  const ufc::function& f,
+                                  const ufc::cell& c) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Interpolate vertex values from dof values
+void meltflux_1_finite_element_5::interpolate_vertex_values(double* vertex_values,
+                                              const double* dof_values,
+                                              const ufc::cell& c) const
+{
+    // Evaluate at vertices and use affine mapping
+    vertex_values[0] = dof_values[0];
+    vertex_values[1] = dof_values[0];
+    vertex_values[2] = dof_values[0];
+}
+
+/// Return the number of sub elements (for a mixed element)
+unsigned int meltflux_1_finite_element_5::num_sub_elements() const
+{
+    return 1;
+}
+
+/// Create a new finite element for sub element i (for a mixed element)
+ufc::finite_element* meltflux_1_finite_element_5::create_sub_element(unsigned int i) const
+{
+    return new meltflux_1_finite_element_5();
+}
+
+/// Constructor
+meltflux_1_dof_map_0_0::meltflux_1_dof_map_0_0() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+meltflux_1_dof_map_0_0::~meltflux_1_dof_map_0_0()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* meltflux_1_dof_map_0_0::signature() const
+{
+    return "FFC dof map for FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool meltflux_1_dof_map_0_0::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)
+bool meltflux_1_dof_map_0_0::init_mesh(const ufc::mesh& m)
+{
+    __global_dimension = m.num_entities[0];
+    return false;
+}
+
+/// Initialize dof map for given cell
+void meltflux_1_dof_map_0_0::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void meltflux_1_dof_map_0_0::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int meltflux_1_dof_map_0_0::global_dimension() const
+{
+    return __global_dimension;
+}
+
+/// Return the dimension of the local finite element function space for a cell
+unsigned int meltflux_1_dof_map_0_0::local_dimension(const ufc::cell& c) const
+{
+    return 3;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int meltflux_1_dof_map_0_0::max_local_dimension() const
+{
+    return 3;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int meltflux_1_dof_map_0_0::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int meltflux_1_dof_map_0_0::num_facet_dofs() const
+{
+    return 2;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int meltflux_1_dof_map_0_0::num_entity_dofs(unsigned int d) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the local-to-global mapping of dofs on a cell
+void meltflux_1_dof_map_0_0::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
+void meltflux_1_dof_map_0_0::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)
+void meltflux_1_dof_map_0_0::tabulate_entity_dofs(unsigned int* dofs,
+                                  unsigned int d, unsigned int i) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the coordinates of all dofs on a cell
+void meltflux_1_dof_map_0_0::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)
+unsigned int meltflux_1_dof_map_0_0::num_sub_dof_maps() const
+{
+    return 1;
+}
+
+/// Create a new dof_map for sub dof map i (for a mixed element)
+ufc::dof_map* meltflux_1_dof_map_0_0::create_sub_dof_map(unsigned int i) const
+{
+    return new meltflux_1_dof_map_0_0();
+}
+
+
+/// Constructor
+meltflux_1_dof_map_0_1::meltflux_1_dof_map_0_1() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+meltflux_1_dof_map_0_1::~meltflux_1_dof_map_0_1()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* meltflux_1_dof_map_0_1::signature() const
+{
+    return "FFC dof map for FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool meltflux_1_dof_map_0_1::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)
+bool meltflux_1_dof_map_0_1::init_mesh(const ufc::mesh& m)
+{
+    __global_dimension = m.num_entities[0];
+    return false;
+}
+
+/// Initialize dof map for given cell
+void meltflux_1_dof_map_0_1::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void meltflux_1_dof_map_0_1::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int meltflux_1_dof_map_0_1::global_dimension() const
+{
+    return __global_dimension;
+}
+
+/// Return the dimension of the local finite element function space for a cell
+unsigned int meltflux_1_dof_map_0_1::local_dimension(const ufc::cell& c) const
+{
+    return 3;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int meltflux_1_dof_map_0_1::max_local_dimension() const
+{
+    return 3;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int meltflux_1_dof_map_0_1::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int meltflux_1_dof_map_0_1::num_facet_dofs() const
+{
+    return 2;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int meltflux_1_dof_map_0_1::num_entity_dofs(unsigned int d) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the local-to-global mapping of dofs on a cell
+void meltflux_1_dof_map_0_1::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
+void meltflux_1_dof_map_0_1::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)
+void meltflux_1_dof_map_0_1::tabulate_entity_dofs(unsigned int* dofs,
+                                  unsigned int d, unsigned int i) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the coordinates of all dofs on a cell
+void meltflux_1_dof_map_0_1::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)
+unsigned int meltflux_1_dof_map_0_1::num_sub_dof_maps() const
+{
+    return 1;
+}
+
+/// Create a new dof_map for sub dof map i (for a mixed element)
+ufc::dof_map* meltflux_1_dof_map_0_1::create_sub_dof_map(unsigned int i) const
+{
+    return new meltflux_1_dof_map_0_1();
+}
+
+
+/// Constructor
+meltflux_1_dof_map_0::meltflux_1_dof_map_0() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+meltflux_1_dof_map_0::~meltflux_1_dof_map_0()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* meltflux_1_dof_map_0::signature() const
+{
+    return "FFC dof map for VectorElement('Lagrange', Cell('triangle', 1, Space(2)), 1, 2)";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool meltflux_1_dof_map_0::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)
+bool meltflux_1_dof_map_0::init_mesh(const ufc::mesh& m)
+{
+    __global_dimension = 2*m.num_entities[0];
+    return false;
+}
+
+/// Initialize dof map for given cell
+void meltflux_1_dof_map_0::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void meltflux_1_dof_map_0::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int meltflux_1_dof_map_0::global_dimension() const
+{
+    return __global_dimension;
+}
+
+/// Return the dimension of the local finite element function space for a cell
+unsigned int meltflux_1_dof_map_0::local_dimension(const ufc::cell& c) const
+{
+    return 6;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int meltflux_1_dof_map_0::max_local_dimension() const
+{
+    return 6;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int meltflux_1_dof_map_0::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int meltflux_1_dof_map_0::num_facet_dofs() const
+{
+    return 4;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int meltflux_1_dof_map_0::num_entity_dofs(unsigned int d) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the local-to-global mapping of dofs on a cell
+void meltflux_1_dof_map_0::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];
+    unsigned int offset = m.num_entities[0];
+    dofs[3] = offset + c.entity_indices[0][0];
+    dofs[4] = offset + c.entity_indices[0][1];
+    dofs[5] = offset + c.entity_indices[0][2];
+}
+
+/// Tabulate the local-to-local mapping from facet dofs to cell dofs
+void meltflux_1_dof_map_0::tabulate_facet_dofs(unsigned int* dofs,
+                                        unsigned int facet) const
+{
+    switch ( facet )
+    {
+    case 0:
+      dofs[0] = 1;
+      dofs[1] = 2;
+      dofs[2] = 4;
+      dofs[3] = 5;
+      break;
+    case 1:
+      dofs[0] = 0;
+      dofs[1] = 2;
+      dofs[2] = 3;
+      dofs[3] = 5;
+      break;
+    case 2:
+      dofs[0] = 0;
+      dofs[1] = 1;
+      dofs[2] = 3;
+      dofs[3] = 4;
+      break;
+    }
+}
+
+/// Tabulate the local-to-local mapping of dofs on entity (d, i)
+void meltflux_1_dof_map_0::tabulate_entity_dofs(unsigned int* dofs,
+                                  unsigned int d, unsigned int i) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the coordinates of all dofs on a cell
+void meltflux_1_dof_map_0::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];
+    coordinates[3][0] = x[0][0];
+    coordinates[3][1] = x[0][1];
+    coordinates[4][0] = x[1][0];
+    coordinates[4][1] = x[1][1];
+    coordinates[5][0] = x[2][0];
+    coordinates[5][1] = x[2][1];
+}
+
+/// Return the number of sub dof maps (for a mixed element)
+unsigned int meltflux_1_dof_map_0::num_sub_dof_maps() const
+{
+    return 2;
+}
+
+/// Create a new dof_map for sub dof map i (for a mixed element)
+ufc::dof_map* meltflux_1_dof_map_0::create_sub_dof_map(unsigned int i) const
+{
+    switch ( i )
+    {
+    case 0:
+      return new meltflux_1_dof_map_0_0();
+      break;
+    case 1:
+      return new meltflux_1_dof_map_0_1();
+      break;
+    }
+    return 0;
+}
+
+
+/// Constructor
+meltflux_1_dof_map_1::meltflux_1_dof_map_1() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+meltflux_1_dof_map_1::~meltflux_1_dof_map_1()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* meltflux_1_dof_map_1::signature() const
+{
+    return "FFC dof map for FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool meltflux_1_dof_map_1::needs_mesh_entities(unsigned int d) const
+{
+    switch ( d )
+    {
+    case 0:
+      return true;
+      break;
+    case 1:
+      return true;
+      break;
+    case 2:
+      return false;
+      break;
+    }
+    return false;
+}
+
+/// Initialize dof map for mesh (return true iff init_cell() is needed)
+bool meltflux_1_dof_map_1::init_mesh(const ufc::mesh& m)
+{
+    __global_dimension = m.num_entities[0] + m.num_entities[1];
+    return false;
+}
+
+/// Initialize dof map for given cell
+void meltflux_1_dof_map_1::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void meltflux_1_dof_map_1::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int meltflux_1_dof_map_1::global_dimension() const
+{
+    return __global_dimension;
+}
+
+/// Return the dimension of the local finite element function space for a cell
+unsigned int meltflux_1_dof_map_1::local_dimension(const ufc::cell& c) const
+{
+    return 6;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int meltflux_1_dof_map_1::max_local_dimension() const
+{
+    return 6;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int meltflux_1_dof_map_1::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int meltflux_1_dof_map_1::num_facet_dofs() const
+{
+    return 3;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int meltflux_1_dof_map_1::num_entity_dofs(unsigned int d) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the local-to-global mapping of dofs on a cell
+void meltflux_1_dof_map_1::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];
+    unsigned int offset = m.num_entities[0];
+    dofs[3] = offset + c.entity_indices[1][0];
+    dofs[4] = offset + c.entity_indices[1][1];
+    dofs[5] = offset + c.entity_indices[1][2];
+}
+
+/// Tabulate the local-to-local mapping from facet dofs to cell dofs
+void meltflux_1_dof_map_1::tabulate_facet_dofs(unsigned int* dofs,
+                                        unsigned int facet) const
+{
+    switch ( facet )
+    {
+    case 0:
+      dofs[0] = 1;
+      dofs[1] = 2;
+      dofs[2] = 3;
+      break;
+    case 1:
+      dofs[0] = 0;
+      dofs[1] = 2;
+      dofs[2] = 4;
+      break;
+    case 2:
+      dofs[0] = 0;
+      dofs[1] = 1;
+      dofs[2] = 5;
+      break;
+    }
+}
+
+/// Tabulate the local-to-local mapping of dofs on entity (d, i)
+void meltflux_1_dof_map_1::tabulate_entity_dofs(unsigned int* dofs,
+                                  unsigned int d, unsigned int i) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the coordinates of all dofs on a cell
+void meltflux_1_dof_map_1::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];
+    coordinates[3][0] = 0.5*x[1][0] + 0.5*x[2][0];
+    coordinates[3][1] = 0.5*x[1][1] + 0.5*x[2][1];
+    coordinates[4][0] = 0.5*x[0][0] + 0.5*x[2][0];
+    coordinates[4][1] = 0.5*x[0][1] + 0.5*x[2][1];
+    coordinates[5][0] = 0.5*x[0][0] + 0.5*x[1][0];
+    coordinates[5][1] = 0.5*x[0][1] + 0.5*x[1][1];
+}
+
+/// Return the number of sub dof maps (for a mixed element)
+unsigned int meltflux_1_dof_map_1::num_sub_dof_maps() const
+{
+    return 1;
+}
+
+/// Create a new dof_map for sub dof map i (for a mixed element)
+ufc::dof_map* meltflux_1_dof_map_1::create_sub_dof_map(unsigned int i) const
+{
+    return new meltflux_1_dof_map_1();
+}
+
+
+/// Constructor
+meltflux_1_dof_map_2::meltflux_1_dof_map_2() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+meltflux_1_dof_map_2::~meltflux_1_dof_map_2()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* meltflux_1_dof_map_2::signature() const
+{
+    return "FFC dof map for FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool meltflux_1_dof_map_2::needs_mesh_entities(unsigned int d) const
+{
+    switch ( d )
+    {
+    case 0:
+      return true;
+      break;
+    case 1:
+      return true;
+      break;
+    case 2:
+      return false;
+      break;
+    }
+    return false;
+}
+
+/// Initialize dof map for mesh (return true iff init_cell() is needed)
+bool meltflux_1_dof_map_2::init_mesh(const ufc::mesh& m)
+{
+    __global_dimension = m.num_entities[0] + m.num_entities[1];
+    return false;
+}
+
+/// Initialize dof map for given cell
+void meltflux_1_dof_map_2::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void meltflux_1_dof_map_2::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int meltflux_1_dof_map_2::global_dimension() const
+{
+    return __global_dimension;
+}
+
+/// Return the dimension of the local finite element function space for a cell
+unsigned int meltflux_1_dof_map_2::local_dimension(const ufc::cell& c) const
+{
+    return 6;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int meltflux_1_dof_map_2::max_local_dimension() const
+{
+    return 6;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int meltflux_1_dof_map_2::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int meltflux_1_dof_map_2::num_facet_dofs() const
+{
+    return 3;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int meltflux_1_dof_map_2::num_entity_dofs(unsigned int d) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the local-to-global mapping of dofs on a cell
+void meltflux_1_dof_map_2::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];
+    unsigned int offset = m.num_entities[0];
+    dofs[3] = offset + c.entity_indices[1][0];
+    dofs[4] = offset + c.entity_indices[1][1];
+    dofs[5] = offset + c.entity_indices[1][2];
+}
+
+/// Tabulate the local-to-local mapping from facet dofs to cell dofs
+void meltflux_1_dof_map_2::tabulate_facet_dofs(unsigned int* dofs,
+                                        unsigned int facet) const
+{
+    switch ( facet )
+    {
+    case 0:
+      dofs[0] = 1;
+      dofs[1] = 2;
+      dofs[2] = 3;
+      break;
+    case 1:
+      dofs[0] = 0;
+      dofs[1] = 2;
+      dofs[2] = 4;
+      break;
+    case 2:
+      dofs[0] = 0;
+      dofs[1] = 1;
+      dofs[2] = 5;
+      break;
+    }
+}
+
+/// Tabulate the local-to-local mapping of dofs on entity (d, i)
+void meltflux_1_dof_map_2::tabulate_entity_dofs(unsigned int* dofs,
+                                  unsigned int d, unsigned int i) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the coordinates of all dofs on a cell
+void meltflux_1_dof_map_2::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];
+    coordinates[3][0] = 0.5*x[1][0] + 0.5*x[2][0];
+    coordinates[3][1] = 0.5*x[1][1] + 0.5*x[2][1];
+    coordinates[4][0] = 0.5*x[0][0] + 0.5*x[2][0];
+    coordinates[4][1] = 0.5*x[0][1] + 0.5*x[2][1];
+    coordinates[5][0] = 0.5*x[0][0] + 0.5*x[1][0];
+    coordinates[5][1] = 0.5*x[0][1] + 0.5*x[1][1];
+}
+
+/// Return the number of sub dof maps (for a mixed element)
+unsigned int meltflux_1_dof_map_2::num_sub_dof_maps() const
+{
+    return 1;
+}
+
+/// Create a new dof_map for sub dof map i (for a mixed element)
+ufc::dof_map* meltflux_1_dof_map_2::create_sub_dof_map(unsigned int i) const
+{
+    return new meltflux_1_dof_map_2();
+}
+
+
+/// Constructor
+meltflux_1_dof_map_3::meltflux_1_dof_map_3() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+meltflux_1_dof_map_3::~meltflux_1_dof_map_3()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* meltflux_1_dof_map_3::signature() const
+{
+    return "FFC dof map for FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool meltflux_1_dof_map_3::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)
+bool meltflux_1_dof_map_3::init_mesh(const ufc::mesh& m)
+{
+    __global_dimension = m.num_entities[0];
+    return false;
+}
+
+/// Initialize dof map for given cell
+void meltflux_1_dof_map_3::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void meltflux_1_dof_map_3::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int meltflux_1_dof_map_3::global_dimension() const
+{
+    return __global_dimension;
+}
+
+/// Return the dimension of the local finite element function space for a cell
+unsigned int meltflux_1_dof_map_3::local_dimension(const ufc::cell& c) const
+{
+    return 3;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int meltflux_1_dof_map_3::max_local_dimension() const
+{
+    return 3;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int meltflux_1_dof_map_3::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int meltflux_1_dof_map_3::num_facet_dofs() const
+{
+    return 2;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int meltflux_1_dof_map_3::num_entity_dofs(unsigned int d) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the local-to-global mapping of dofs on a cell
+void meltflux_1_dof_map_3::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
+void meltflux_1_dof_map_3::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)
+void meltflux_1_dof_map_3::tabulate_entity_dofs(unsigned int* dofs,
+                                  unsigned int d, unsigned int i) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the coordinates of all dofs on a cell
+void meltflux_1_dof_map_3::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)
+unsigned int meltflux_1_dof_map_3::num_sub_dof_maps() const
+{
+    return 1;
+}
+
+/// Create a new dof_map for sub dof map i (for a mixed element)
+ufc::dof_map* meltflux_1_dof_map_3::create_sub_dof_map(unsigned int i) const
+{
+    return new meltflux_1_dof_map_3();
+}
+
+
+/// Constructor
+meltflux_1_dof_map_4_0::meltflux_1_dof_map_4_0() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+meltflux_1_dof_map_4_0::~meltflux_1_dof_map_4_0()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* meltflux_1_dof_map_4_0::signature() const
+{
+    return "FFC dof map for FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool meltflux_1_dof_map_4_0::needs_mesh_entities(unsigned int d) const
+{
+    switch ( d )
+    {
+    case 0:
+      return true;
+      break;
+    case 1:
+      return true;
+      break;
+    case 2:
+      return false;
+      break;
+    }
+    return false;
+}
+
+/// Initialize dof map for mesh (return true iff init_cell() is needed)
+bool meltflux_1_dof_map_4_0::init_mesh(const ufc::mesh& m)
+{
+    __global_dimension = m.num_entities[0] + m.num_entities[1];
+    return false;
+}
+
+/// Initialize dof map for given cell
+void meltflux_1_dof_map_4_0::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void meltflux_1_dof_map_4_0::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int meltflux_1_dof_map_4_0::global_dimension() const
+{
+    return __global_dimension;
+}
+
+/// Return the dimension of the local finite element function space for a cell
+unsigned int meltflux_1_dof_map_4_0::local_dimension(const ufc::cell& c) const
+{
+    return 6;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int meltflux_1_dof_map_4_0::max_local_dimension() const
+{
+    return 6;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int meltflux_1_dof_map_4_0::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int meltflux_1_dof_map_4_0::num_facet_dofs() const
+{
+    return 3;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int meltflux_1_dof_map_4_0::num_entity_dofs(unsigned int d) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the local-to-global mapping of dofs on a cell
+void meltflux_1_dof_map_4_0::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];
+    unsigned int offset = m.num_entities[0];
+    dofs[3] = offset + c.entity_indices[1][0];
+    dofs[4] = offset + c.entity_indices[1][1];
+    dofs[5] = offset + c.entity_indices[1][2];
+}
+
+/// Tabulate the local-to-local mapping from facet dofs to cell dofs
+void meltflux_1_dof_map_4_0::tabulate_facet_dofs(unsigned int* dofs,
+                                        unsigned int facet) const
+{
+    switch ( facet )
+    {
+    case 0:
+      dofs[0] = 1;
+      dofs[1] = 2;
+      dofs[2] = 3;
+      break;
+    case 1:
+      dofs[0] = 0;
+      dofs[1] = 2;
+      dofs[2] = 4;
+      break;
+    case 2:
+      dofs[0] = 0;
+      dofs[1] = 1;
+      dofs[2] = 5;
+      break;
+    }
+}
+
+/// Tabulate the local-to-local mapping of dofs on entity (d, i)
+void meltflux_1_dof_map_4_0::tabulate_entity_dofs(unsigned int* dofs,
+                                  unsigned int d, unsigned int i) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the coordinates of all dofs on a cell
+void meltflux_1_dof_map_4_0::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];
+    coordinates[3][0] = 0.5*x[1][0] + 0.5*x[2][0];
+    coordinates[3][1] = 0.5*x[1][1] + 0.5*x[2][1];
+    coordinates[4][0] = 0.5*x[0][0] + 0.5*x[2][0];
+    coordinates[4][1] = 0.5*x[0][1] + 0.5*x[2][1];
+    coordinates[5][0] = 0.5*x[0][0] + 0.5*x[1][0];
+    coordinates[5][1] = 0.5*x[0][1] + 0.5*x[1][1];
+}
+
+/// Return the number of sub dof maps (for a mixed element)
+unsigned int meltflux_1_dof_map_4_0::num_sub_dof_maps() const
+{
+    return 1;
+}
+
+/// Create a new dof_map for sub dof map i (for a mixed element)
+ufc::dof_map* meltflux_1_dof_map_4_0::create_sub_dof_map(unsigned int i) const
+{
+    return new meltflux_1_dof_map_4_0();
+}
+
+
+/// Constructor
+meltflux_1_dof_map_4_1::meltflux_1_dof_map_4_1() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+meltflux_1_dof_map_4_1::~meltflux_1_dof_map_4_1()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* meltflux_1_dof_map_4_1::signature() const
+{
+    return "FFC dof map for FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool meltflux_1_dof_map_4_1::needs_mesh_entities(unsigned int d) const
+{
+    switch ( d )
+    {
+    case 0:
+      return true;
+      break;
+    case 1:
+      return true;
+      break;
+    case 2:
+      return false;
+      break;
+    }
+    return false;
+}
+
+/// Initialize dof map for mesh (return true iff init_cell() is needed)
+bool meltflux_1_dof_map_4_1::init_mesh(const ufc::mesh& m)
+{
+    __global_dimension = m.num_entities[0] + m.num_entities[1];
+    return false;
+}
+
+/// Initialize dof map for given cell
+void meltflux_1_dof_map_4_1::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void meltflux_1_dof_map_4_1::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int meltflux_1_dof_map_4_1::global_dimension() const
+{
+    return __global_dimension;
+}
+
+/// Return the dimension of the local finite element function space for a cell
+unsigned int meltflux_1_dof_map_4_1::local_dimension(const ufc::cell& c) const
+{
+    return 6;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int meltflux_1_dof_map_4_1::max_local_dimension() const
+{
+    return 6;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int meltflux_1_dof_map_4_1::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int meltflux_1_dof_map_4_1::num_facet_dofs() const
+{
+    return 3;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int meltflux_1_dof_map_4_1::num_entity_dofs(unsigned int d) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the local-to-global mapping of dofs on a cell
+void meltflux_1_dof_map_4_1::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];
+    unsigned int offset = m.num_entities[0];
+    dofs[3] = offset + c.entity_indices[1][0];
+    dofs[4] = offset + c.entity_indices[1][1];
+    dofs[5] = offset + c.entity_indices[1][2];
+}
+
+/// Tabulate the local-to-local mapping from facet dofs to cell dofs
+void meltflux_1_dof_map_4_1::tabulate_facet_dofs(unsigned int* dofs,
+                                        unsigned int facet) const
+{
+    switch ( facet )
+    {
+    case 0:
+      dofs[0] = 1;
+      dofs[1] = 2;
+      dofs[2] = 3;
+      break;
+    case 1:
+      dofs[0] = 0;
+      dofs[1] = 2;
+      dofs[2] = 4;
+      break;
+    case 2:
+      dofs[0] = 0;
+      dofs[1] = 1;
+      dofs[2] = 5;
+      break;
+    }
+}
+
+/// Tabulate the local-to-local mapping of dofs on entity (d, i)
+void meltflux_1_dof_map_4_1::tabulate_entity_dofs(unsigned int* dofs,
+                                  unsigned int d, unsigned int i) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the coordinates of all dofs on a cell
+void meltflux_1_dof_map_4_1::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];
+    coordinates[3][0] = 0.5*x[1][0] + 0.5*x[2][0];
+    coordinates[3][1] = 0.5*x[1][1] + 0.5*x[2][1];
+    coordinates[4][0] = 0.5*x[0][0] + 0.5*x[2][0];
+    coordinates[4][1] = 0.5*x[0][1] + 0.5*x[2][1];
+    coordinates[5][0] = 0.5*x[0][0] + 0.5*x[1][0];
+    coordinates[5][1] = 0.5*x[0][1] + 0.5*x[1][1];
+}
+
+/// Return the number of sub dof maps (for a mixed element)
+unsigned int meltflux_1_dof_map_4_1::num_sub_dof_maps() const
+{
+    return 1;
+}
+
+/// Create a new dof_map for sub dof map i (for a mixed element)
+ufc::dof_map* meltflux_1_dof_map_4_1::create_sub_dof_map(unsigned int i) const
+{
+    return new meltflux_1_dof_map_4_1();
+}
+
+
+/// Constructor
+meltflux_1_dof_map_4::meltflux_1_dof_map_4() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+meltflux_1_dof_map_4::~meltflux_1_dof_map_4()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* meltflux_1_dof_map_4::signature() const
+{
+    return "FFC dof map for VectorElement('Lagrange', Cell('triangle', 1, Space(2)), 2, 2)";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool meltflux_1_dof_map_4::needs_mesh_entities(unsigned int d) const
+{
+    switch ( d )
+    {
+    case 0:
+      return true;
+      break;
+    case 1:
+      return true;
+      break;
+    case 2:
+      return false;
+      break;
+    }
+    return false;
+}
+
+/// Initialize dof map for mesh (return true iff init_cell() is needed)
+bool meltflux_1_dof_map_4::init_mesh(const ufc::mesh& m)
+{
+    __global_dimension = 2*m.num_entities[0] + 2*m.num_entities[1];
+    return false;
+}
+
+/// Initialize dof map for given cell
+void meltflux_1_dof_map_4::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void meltflux_1_dof_map_4::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int meltflux_1_dof_map_4::global_dimension() const
+{
+    return __global_dimension;
+}
+
+/// Return the dimension of the local finite element function space for a cell
+unsigned int meltflux_1_dof_map_4::local_dimension(const ufc::cell& c) const
+{
+    return 12;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int meltflux_1_dof_map_4::max_local_dimension() const
+{
+    return 12;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int meltflux_1_dof_map_4::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int meltflux_1_dof_map_4::num_facet_dofs() const
+{
+    return 6;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int meltflux_1_dof_map_4::num_entity_dofs(unsigned int d) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the local-to-global mapping of dofs on a cell
+void meltflux_1_dof_map_4::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];
+    unsigned int offset = m.num_entities[0];
+    dofs[3] = offset + c.entity_indices[1][0];
+    dofs[4] = offset + c.entity_indices[1][1];
+    dofs[5] = offset + c.entity_indices[1][2];
+    offset = offset + m.num_entities[1];
+    dofs[6] = offset + c.entity_indices[0][0];
+    dofs[7] = offset + c.entity_indices[0][1];
+    dofs[8] = offset + c.entity_indices[0][2];
+    offset = offset + m.num_entities[0];
+    dofs[9] = offset + c.entity_indices[1][0];
+    dofs[10] = offset + c.entity_indices[1][1];
+    dofs[11] = offset + c.entity_indices[1][2];
+}
+
+/// Tabulate the local-to-local mapping from facet dofs to cell dofs
+void meltflux_1_dof_map_4::tabulate_facet_dofs(unsigned int* dofs,
+                                        unsigned int facet) const
+{
+    switch ( facet )
+    {
+    case 0:
+      dofs[0] = 1;
+      dofs[1] = 2;
+      dofs[2] = 3;
+      dofs[3] = 7;
+      dofs[4] = 8;
+      dofs[5] = 9;
+      break;
+    case 1:
+      dofs[0] = 0;
+      dofs[1] = 2;
+      dofs[2] = 4;
+      dofs[3] = 6;
+      dofs[4] = 8;
+      dofs[5] = 10;
+      break;
+    case 2:
+      dofs[0] = 0;
+      dofs[1] = 1;
+      dofs[2] = 5;
+      dofs[3] = 6;
+      dofs[4] = 7;
+      dofs[5] = 11;
+      break;
+    }
+}
+
+/// Tabulate the local-to-local mapping of dofs on entity (d, i)
+void meltflux_1_dof_map_4::tabulate_entity_dofs(unsigned int* dofs,
+                                  unsigned int d, unsigned int i) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the coordinates of all dofs on a cell
+void meltflux_1_dof_map_4::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];
+    coordinates[3][0] = 0.5*x[1][0] + 0.5*x[2][0];
+    coordinates[3][1] = 0.5*x[1][1] + 0.5*x[2][1];
+    coordinates[4][0] = 0.5*x[0][0] + 0.5*x[2][0];
+    coordinates[4][1] = 0.5*x[0][1] + 0.5*x[2][1];
+    coordinates[5][0] = 0.5*x[0][0] + 0.5*x[1][0];
+    coordinates[5][1] = 0.5*x[0][1] + 0.5*x[1][1];
+    coordinates[6][0] = x[0][0];
+    coordinates[6][1] = x[0][1];
+    coordinates[7][0] = x[1][0];
+    coordinates[7][1] = x[1][1];
+    coordinates[8][0] = x[2][0];
+    coordinates[8][1] = x[2][1];
+    coordinates[9][0] = 0.5*x[1][0] + 0.5*x[2][0];
+    coordinates[9][1] = 0.5*x[1][1] + 0.5*x[2][1];
+    coordinates[10][0] = 0.5*x[0][0] + 0.5*x[2][0];
+    coordinates[10][1] = 0.5*x[0][1] + 0.5*x[2][1];
+    coordinates[11][0] = 0.5*x[0][0] + 0.5*x[1][0];
+    coordinates[11][1] = 0.5*x[0][1] + 0.5*x[1][1];
+}
+
+/// Return the number of sub dof maps (for a mixed element)
+unsigned int meltflux_1_dof_map_4::num_sub_dof_maps() const
+{
+    return 2;
+}
+
+/// Create a new dof_map for sub dof map i (for a mixed element)
+ufc::dof_map* meltflux_1_dof_map_4::create_sub_dof_map(unsigned int i) const
+{
+    switch ( i )
+    {
+    case 0:
+      return new meltflux_1_dof_map_4_0();
+      break;
+    case 1:
+      return new meltflux_1_dof_map_4_1();
+      break;
+    }
+    return 0;
+}
+
+
+/// Constructor
+meltflux_1_dof_map_5::meltflux_1_dof_map_5() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+meltflux_1_dof_map_5::~meltflux_1_dof_map_5()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* meltflux_1_dof_map_5::signature() const
+{
+    return "FFC dof map for FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 0)";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool meltflux_1_dof_map_5::needs_mesh_entities(unsigned int d) const
+{
+    switch ( d )
+    {
+    case 0:
+      return false;
+      break;
+    case 1:
+      return false;
+      break;
+    case 2:
+      return true;
+      break;
+    }
+    return false;
+}
+
+/// Initialize dof map for mesh (return true iff init_cell() is needed)
+bool meltflux_1_dof_map_5::init_mesh(const ufc::mesh& m)
+{
+    __global_dimension = m.num_entities[2];
+    return false;
+}
+
+/// Initialize dof map for given cell
+void meltflux_1_dof_map_5::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void meltflux_1_dof_map_5::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int meltflux_1_dof_map_5::global_dimension() const
+{
+    return __global_dimension;
+}
+
+/// Return the dimension of the local finite element function space for a cell
+unsigned int meltflux_1_dof_map_5::local_dimension(const ufc::cell& c) const
+{
+    return 1;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int meltflux_1_dof_map_5::max_local_dimension() const
+{
+    return 1;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int meltflux_1_dof_map_5::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int meltflux_1_dof_map_5::num_facet_dofs() const
+{
+    return 0;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int meltflux_1_dof_map_5::num_entity_dofs(unsigned int d) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the local-to-global mapping of dofs on a cell
+void meltflux_1_dof_map_5::tabulate_dofs(unsigned int* dofs,
+                                  const ufc::mesh& m,
+                                  const ufc::cell& c) const
+{
+    dofs[0] = c.entity_indices[2][0];
+}
+
+/// Tabulate the local-to-local mapping from facet dofs to cell dofs
+void meltflux_1_dof_map_5::tabulate_facet_dofs(unsigned int* dofs,
+                                        unsigned int facet) const
+{
+    switch ( facet )
+    {
+    case 0:
+      
+      break;
+    case 1:
+      
+      break;
+    case 2:
+      
+      break;
+    }
+}
+
+/// Tabulate the local-to-local mapping of dofs on entity (d, i)
+void meltflux_1_dof_map_5::tabulate_entity_dofs(unsigned int* dofs,
+                                  unsigned int d, unsigned int i) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the coordinates of all dofs on a cell
+void meltflux_1_dof_map_5::tabulate_coordinates(double** coordinates,
+                                         const ufc::cell& c) const
+{
+    const double * const * x = c.coordinates;
+    coordinates[0][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0];
+    coordinates[0][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1];
+}
+
+/// Return the number of sub dof maps (for a mixed element)
+unsigned int meltflux_1_dof_map_5::num_sub_dof_maps() const
+{
+    return 1;
+}
+
+/// Create a new dof_map for sub dof map i (for a mixed element)
+ufc::dof_map* meltflux_1_dof_map_5::create_sub_dof_map(unsigned int i) const
+{
+    return new meltflux_1_dof_map_5();
+}
+
+
+/// Constructor
+meltflux_1_cell_integral_0_quadrature::meltflux_1_cell_integral_0_quadrature() : ufc::cell_integral()
+{
+    // Do nothing
+}
+
+/// Destructor
+meltflux_1_cell_integral_0_quadrature::~meltflux_1_cell_integral_0_quadrature()
+{
+    // Do nothing
+}
+
+/// Tabulate the tensor for the contribution from a local cell
+void meltflux_1_cell_integral_0_quadrature::tabulate_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 Jinv_00 =  J_11 / detJ;
+    const double Jinv_01 = -J_01 / detJ;
+    const double Jinv_10 = -J_10 / detJ;
+    const double Jinv_11 =  J_00 / detJ;
+    
+    // Set scale factor
+    const double det = std::abs(detJ);
+    
+    
+    // Array of quadrature weights
+    static const double W16[16] = {0.0235683681933823, 0.0353880678980859, 0.0225840492823699, 0.00542322591052525, 0.0441850885223617, 0.0663442161070497, 0.0423397245217463, 0.0101672595644788, 0.0441850885223617, 0.0663442161070497, 0.0423397245217463, 0.0101672595644788, 0.0235683681933823, 0.0353880678980859, 0.0225840492823699, 0.00542322591052525};
+    // Quadrature points on the UFC reference element: (0.0654669945550145, 0.0571041961145177), (0.0502101232113698, 0.276843013638124), (0.028912084224389, 0.583590432368917), (0.00970378512694614, 0.860240135656219), (0.311164552244357, 0.0571041961145177), (0.238648659731443, 0.276843013638124), (0.137419104134574, 0.583590432368917), (0.0461220799064521, 0.860240135656219), (0.631731251641125, 0.0571041961145177), (0.484508326630433, 0.276843013638124), (0.278990463496509, 0.583590432368917), (0.0936377844373285, 0.860240135656219), (0.877428809330468, 0.0571041961145177), (0.672946863150506, 0.276843013638124), (0.387497483406694, 0.583590432368917), (0.130056079216834, 0.860240135656219)
+    
+    // Value of basis functions at quadrature points.
+    static const double FE0[16][3] = \
+    {{0.877428809330468, 0.0654669945550145, 0.0571041961145176},
+    {0.672946863150506, 0.0502101232113698, 0.276843013638124},
+    {0.387497483406694, 0.028912084224389, 0.583590432368917},
+    {0.130056079216834, 0.0097037851269462, 0.860240135656219},
+    {0.631731251641125, 0.311164552244357, 0.0571041961145176},
+    {0.484508326630433, 0.238648659731443, 0.276843013638124},
+    {0.278990463496509, 0.137419104134574, 0.583590432368917},
+    {0.0936377844373285, 0.0461220799064521, 0.860240135656219},
+    {0.311164552244357, 0.631731251641125, 0.0571041961145176},
+    {0.238648659731443, 0.484508326630433, 0.276843013638124},
+    {0.137419104134574, 0.278990463496509, 0.583590432368917},
+    {0.0461220799064521, 0.0936377844373286, 0.860240135656219},
+    {0.0654669945550145, 0.877428809330468, 0.0571041961145176},
+    {0.05021012321137, 0.672946863150506, 0.276843013638124},
+    {0.028912084224389, 0.387497483406694, 0.583590432368917},
+    {0.00970378512694609, 0.130056079216835, 0.860240135656219}};
+    
+    // Array of non-zero columns
+    static const unsigned int nzc4[3] = {0, 1, 2};
+    // Array of non-zero columns
+    static const unsigned int nzc5[3] = {3, 4, 5};
+    static const double FE0_D01[16][2] = \
+    {{-1, 1},
+    {-1, 1},
+    {-1, 1},
+    {-1, 1},
+    {-1, 1},
+    {-1, 1},
+    {-1, 1},
+    {-1, 1},
+    {-1, 1},
+    {-1, 1},
+    {-1, 1},
+    {-1, 1},
+    {-1, 1},
+    {-1, 1},
+    {-1, 1},
+    {-1, 1}};
+    
+    // Array of non-zero columns
+    static const unsigned int nzc1[2] = {0, 1};
+    // Array of non-zero columns
+    static const unsigned int nzc0[2] = {0, 2};
+    static const double FE1[16][6] = \
+    {{0.662333821555697, -0.0568951398028818, -0.0505824176867471, 0.0149537603843903, 0.200419467218139, 0.229770508331402},
+    {0.232768098097707, -0.0451680102655679, -0.123558905237647, 0.0556012872999084, 0.745202550451633, 0.135154979653967},
+    {-0.0871888841136516, -0.0272402669959927, 0.0975651531361618, 0.0674912629327909, 0.904559295532719, 0.0448134395079726},
+    {-0.0962269117343233, -0.00951545823536616, 0.619786046331442, 0.0333903417359317, 0.447517836913622, 0.00504814498869312},
+    {0.166437496959, -0.117517795097495, -0.0505824176867471, 0.0710752064609913, 0.144298021141538, 0.786289488222712},
+    {-0.0150116894819879, -0.124742294148215, -0.123558905237647, 0.264272856643007, 0.536530981108534, 0.462509051116308},
+    {-0.123319106052515, -0.0996510837722763, 0.0975651531361618, 0.320785897590582, 0.651264660874928, 0.15335447822312},
+    {-0.0761017150886652, -0.0418675873966577, 0.619786046331442, 0.158704257101893, 0.322203921547661, 0.0172750775043265},
+    {-0.117517795097494, 0.166437496959, -0.0505824176867471, 0.144298021141538, 0.0710752064609913, 0.786289488222712},
+    {-0.124742294148215, -0.015011689481988, -0.123558905237647, 0.536530981108534, 0.264272856643007, 0.462509051116308},
+    {-0.0996510837722762, -0.123319106052515, 0.0975651531361618, 0.651264660874928, 0.320785897590582, 0.15335447822312},
+    {-0.0418675873966576, -0.0761017150886652, 0.619786046331442, 0.322203921547661, 0.158704257101893, 0.0172750775043265},
+    {-0.0568951398028817, 0.662333821555697, -0.0505824176867471, 0.200419467218139, 0.0149537603843903, 0.229770508331402},
+    {-0.0451680102655678, 0.232768098097706, -0.123558905237647, 0.745202550451633, 0.0556012872999086, 0.135154979653967},
+    {-0.0272402669959925, -0.0871888841136517, 0.0975651531361618, 0.904559295532719, 0.0674912629327908, 0.0448134395079726},
+    {-0.00951545823536599, -0.0962269117343234, 0.619786046331442, 0.447517836913623, 0.0333903417359313, 0.00504814498869309}};
+    
+    // Array of non-zero columns
+    static const unsigned int nzc6[6] = {0, 1, 2, 3, 4, 5};
+    // Array of non-zero columns
+    static const unsigned int nzc7[6] = {6, 7, 8, 9, 10, 11};
+    static const double FE1_D01[16][5] = \
+    {{-2.50971523732187, -0.77158321554193, 0.261867978220058, 3.2812984528638, -0.261867978220058},
+    {-1.69178745260203, 0.107372054552496, 0.200840492845479, 1.58441539804953, -0.200840492845479},
+    {-0.549989933626777, 1.33436172947567, 0.115648336897556, -0.784371795848891, -0.115648336897556},
+    {0.479775683132663, 2.44096054262488, 0.0388151405077859, -2.92073622575754, -0.0388151405077846},
+    {-1.5269250065645, -0.77158321554193, 1.24465820897743, 2.29850822210643, -1.24465820897743},
+    {-0.938033306521733, 0.107372054552495, 0.954594638925771, 0.830661251969238, -0.954594638925771},
+    {-0.115961853986035, 1.33436172947567, 0.549676416538298, -1.21839987548963, -0.549676416538297},
+    {0.625448862250687, 2.44096054262488, 0.184488319625809, -3.06640940487556, -0.184488319625808},
+    {-0.244658208977428, -0.77158321554193, 2.5269250065645, 1.01624142451936, -2.5269250065645},
+    {0.0454053610742288, 0.107372054552495, 1.93803330652173, -0.152777415626724, -1.93803330652173},
+    {0.450323583461703, 1.33436172947567, 1.11596185398603, -1.78468531293737, -1.11596185398603},
+    {0.815511680374193, 2.44096054262488, 0.374551137749315, -3.25647222299907, -0.374551137749314},
+    {0.738132021779943, -0.771583215541929, 3.50971523732187, 0.0334511937619876, -3.50971523732187},
+    {0.799159507154521, 0.107372054552495, 2.69178745260202, -0.906531561707015, -2.69178745260203},
+    {0.884351663102445, 1.33436172947567, 1.54998993362678, -2.21871339257811, -1.54998993362678},
+    {0.961184859492217, 2.44096054262488, 0.520224316867339, -3.40214540211709, -0.520224316867338}};
+    
+    // Array of non-zero columns
+    static const unsigned int nzc2[5] = {0, 2, 3, 4, 5};
+    static const double FE1_D10[16][5] = \
+    {{-2.50971523732187, -0.738132021779942, 0.22841678445807, -0.22841678445807, 3.24784725910181},
+    {-1.69178745260203, -0.79915950715452, 1.10737205455249, -1.10737205455249, 2.49094695975655},
+    {-0.549989933626777, -0.884351663102444, 2.33436172947567, -2.33436172947567, 1.43434159672922},
+    {0.479775683132664, -0.961184859492216, 3.44096054262488, -3.44096054262488, 0.481409176359552},
+    {-1.5269250065645, 0.244658208977428, 0.22841678445807, -0.22841678445807, 1.28226679758707},
+    {-0.938033306521733, -0.0454053610742281, 1.10737205455249, -1.10737205455249, 0.983438667595962},
+    {-0.115961853986035, -0.450323583461702, 2.33436172947567, -2.33436172947567, 0.566285437447738},
+    {0.625448862250687, -0.815511680374192, 3.44096054262488, -3.44096054262488, 0.190062818123505},
+    {-0.244658208977428, 1.5269250065645, 0.228416784458071, -0.228416784458071, -1.28226679758707},
+    {0.0454053610742284, 0.938033306521734, 1.10737205455249, -1.10737205455249, -0.983438667595961},
+    {0.450323583461703, 0.115961853986035, 2.33436172947567, -2.33436172947567, -0.566285437447738},
+    {0.815511680374193, -0.625448862250686, 3.44096054262488, -3.44096054262488, -0.190062818123506},
+    {0.738132021779942, 2.50971523732187, 0.228416784458071, -0.228416784458071, -3.24784725910181},
+    {0.79915950715452, 1.69178745260203, 1.10737205455249, -1.10737205455249, -2.49094695975655},
+    {0.884351663102444, 0.549989933626777, 2.33436172947567, -2.33436172947567, -1.43434159672922},
+    {0.961184859492217, -0.479775683132662, 3.44096054262488, -3.44096054262488, -0.481409176359554}};
+    
+    // Array of non-zero columns
+    static const unsigned int nzc3[5] = {0, 1, 3, 4, 5};
+    
+    // Number of operations to compute geometry constants: 28
+    const double G0 = -2*Jinv_00*det*w[4][0];
+    const double G1 = -2*Jinv_10*det*w[4][0];
+    const double G2 = -Jinv_00*det;
+    const double G3 = -Jinv_10*det;
+    const double G4 = -Jinv_10*det*w[4][0]*w[4][0];
+    const double G5 = -Jinv_00*det*w[4][0]*w[4][0];
+    const double G6 = -2*Jinv_01*det*w[4][0];
+    const double G7 = -2*Jinv_11*det*w[4][0];
+    const double G8 = -Jinv_01*det;
+    const double G9 = -Jinv_11*det;
+    const double G10 = -Jinv_11*det*w[4][0]*w[4][0];
+    const double G11 = -Jinv_01*det*w[4][0]*w[4][0];
+    
+    // Compute element tensor using UFL quadrature representation
+    // Optimisations: ('simplify expressions', True), ('ignore zero tables', True), ('non zero columns', True), ('remove zero terms', True), ('ignore ones', True)
+    // Total number of operations to compute element tensor: 1852
+    
+    // Loop quadrature points for integral
+    // Number of operations to compute element tensor for following IP loop = 1824
+    for (unsigned int ip = 0; ip < 16; ip++)
+    {
+      
+      // Function declarations
+      double F0 = 0;
+      double F1 = 0;
+      double F2 = 0;
+      double F3 = 0;
+      double F4 = 0;
+      double F5 = 0;
+      double F6 = 0;
+      
+      // Total number of operations to compute function values = 8
+      for (unsigned int r = 0; r < 2; r++)
+      {
+        F1 += FE0_D01[ip][r]*w[2][nzc1[r]];
+        F2 += FE0_D01[ip][r]*w[2][nzc0[r]];
+      }// end loop over 'r'
+      
+      // Total number of operations to compute function values = 20
+      for (unsigned int r = 0; r < 5; r++)
+      {
+        F5 += FE1_D10[ip][r]*w[1][nzc3[r]];
+        F6 += FE1_D01[ip][r]*w[1][nzc2[r]];
+      }// end loop over 'r'
+      
+      // Total number of operations to compute function values = 36
+      for (unsigned int r = 0; r < 6; r++)
+      {
+        F0 += FE1[ip][r]*w[0][r];
+        F3 += FE1[ip][r]*w[3][nzc6[r]];
+        F4 += FE1[ip][r]*w[3][nzc7[r]];
+      }// end loop over 'r'
+      
+      // Number of operations to compute ip constants: 38
+      // Number of operations: 18
+      const double Gip0 = W16[ip]*(F0*(F0*(G2*(F1 + F5) + G3*(F2 + F6)) + F3*det + F5*G0 + F6*G1) + F5*G5 + F6*G4);
+      
+      // Number of operations: 20
+      const double Gip1 = W16[ip]*(F0*(F4*det + F5*G6 + F6*G7) + F0*F0*(det + G8*(F1 + F5) + G9*(F2 + F6)) + F5*G11 + F6*G10);
+      
+      
+      // Number of operations for primary indices: 12
+      for (unsigned int j = 0; j < 3; j++)
+      {
+        // Number of operations to compute entry: 2
+        A[nzc4[j]] += FE0[ip][j]*Gip0;
+        // Number of operations to compute entry: 2
+        A[nzc5[j]] += FE0[ip][j]*Gip1;
+      }// end loop over 'j'
+    }// end loop over 'ip'
+}
+
+/// Constructor
+meltflux_1_cell_integral_0::meltflux_1_cell_integral_0() : ufc::cell_integral()
+{
+    // Do nothing
+}
+
+/// Destructor
+meltflux_1_cell_integral_0::~meltflux_1_cell_integral_0()
+{
+    // Do nothing
+}
+
+/// Tabulate the tensor for the contribution from a local cell
+void meltflux_1_cell_integral_0::tabulate_tensor(double* A,
+                                    const double * const * w,
+                                    const ufc::cell& c) const
+{
+    // Reset values of the element tensor block
+    for (unsigned int j = 0; j < 6; j++)
+      A[j] = 0;
+    
+    // Add all contributions to element tensor
+    integral_0_quadrature.tabulate_tensor(A, w, c);
+}
+
+/// Constructor
+meltflux_form_1::meltflux_form_1() : ufc::form()
+{
+    // Do nothing
+}
+
+/// Destructor
+meltflux_form_1::~meltflux_form_1()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the form
+const char* meltflux_form_1::signature() const
+{
+    return "Form([Integral(Sum(Product(Power(Function(FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2), 0), IntValue(2, (), (), {})), Sum(Indexed(BasisFunction(VectorElement('Lagrange', Cell('triangle', 1, Space(2)), 1, 2), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})), Product(IntValue(-1, (), (), {}), IndexSum(Product(Indexed(BasisFunction(VectorElement('Lagrange', Cell('triangle', 1, Space(2)), 1, 2), 0), MultiIndex((Index(0),), {Index(0): 2})), Indexed(ComponentTensor(SpatialDerivative(Function(FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), 2), MultiIndex((Index(1),), {Index(1): 2})), MultiIndex((Index(1),), {Index(1): 2})), MultiIndex((Index(0),), {Index(0): 2}))), MultiIndex((Index(0),), {Index(0): 2}))))), Sum(Product(Function(FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2), 0), IndexSum(Product(Indexed(BasisFunction(VectorElement('Lagrange', Cell('triangle', 1, Space(2)), 1, 2), 0), MultiIndex((Index(2),), {Index(2): 2})), Indexed(Function(VectorElement('Lagrange', Cell('triangle', 1, Space(2)), 2, 2), 3), MultiIndex((Index(2),), {Index(2): 2}))), MultiIndex((Index(2),), {Index(2): 2}))), Product(Power(Sum(Constant(Cell('triangle', 1, Space(2)), 4), Function(FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2), 0)), IntValue(2, (), (), {})), Product(IntValue(-1, (), (), {}), IndexSum(Product(Indexed(BasisFunction(VectorElement('Lagrange', Cell('triangle', 1, Space(2)), 1, 2), 0), MultiIndex((Index(3),), {Index(3): 2})), Indexed(ComponentTensor(SpatialDerivative(Function(FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2), 1), MultiIndex((Index(4),), {Index(4): 2})), MultiIndex((Index(4),), {Index(4): 2})), MultiIndex((Index(3),), {Index(3): 2}))), MultiIndex((Index(3),), {Index(3): 2})))))), Measure('cell', 0, None))])";
+}
+
+/// Return the rank of the global tensor (r)
+unsigned int meltflux_form_1::rank() const
+{
+    return 1;
+}
+
+/// Return the number of coefficients (n)
+unsigned int meltflux_form_1::num_coefficients() const
+{
+    return 5;
+}
+
+/// Return the number of cell integrals
+unsigned int meltflux_form_1::num_cell_integrals() const
+{
+    return 1;
+}
+
+/// Return the number of exterior facet integrals
+unsigned int meltflux_form_1::num_exterior_facet_integrals() const
+{
+    return 0;
+}
+
+/// Return the number of interior facet integrals
+unsigned int meltflux_form_1::num_interior_facet_integrals() const
+{
+    return 0;
+}
+
+/// Create a new finite element for argument function i
+ufc::finite_element* meltflux_form_1::create_finite_element(unsigned int i) const
+{
+    switch ( i )
+    {
+    case 0:
+      return new meltflux_1_finite_element_0();
+      break;
+    case 1:
+      return new meltflux_1_finite_element_1();
+      break;
+    case 2:
+      return new meltflux_1_finite_element_2();
+      break;
+    case 3:
+      return new meltflux_1_finite_element_3();
+      break;
+    case 4:
+      return new meltflux_1_finite_element_4();
+      break;
+    case 5:
+      return new meltflux_1_finite_element_5();
+      break;
+    }
+    return 0;
+}
+
+/// Create a new dof map for argument function i
+ufc::dof_map* meltflux_form_1::create_dof_map(unsigned int i) const
+{
+    switch ( i )
+    {
+    case 0:
+      return new meltflux_1_dof_map_0();
+      break;
+    case 1:
+      return new meltflux_1_dof_map_1();
+      break;
+    case 2:
+      return new meltflux_1_dof_map_2();
+      break;
+    case 3:
+      return new meltflux_1_dof_map_3();
+      break;
+    case 4:
+      return new meltflux_1_dof_map_4();
+      break;
+    case 5:
+      return new meltflux_1_dof_map_5();
+      break;
+    }
+    return 0;
+}
+
+/// Create a new cell integral on sub domain i
+ufc::cell_integral* meltflux_form_1::create_cell_integral(unsigned int i) const
+{
+    return new meltflux_1_cell_integral_0();
+}
+
+/// Create a new exterior facet integral on sub domain i
+ufc::exterior_facet_integral* meltflux_form_1::create_exterior_facet_integral(unsigned int i) const
+{
+    return 0;
+}
+
+/// Create a new interior facet integral on sub domain i
+ufc::interior_facet_integral* meltflux_form_1::create_interior_facet_integral(unsigned int i) const
+{
+    return 0;
+}
+
diff -r 18d756141ac1 -r 137baa77335a MADDs-5/MADDs-5a/cpp/MeltFlux.ufl
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MADDs-5/MADDs-5a/cpp/MeltFlux.ufl	Tue Dec 08 23:31:34 2009 -0500
@@ -0,0 +1,1 @@
+forms/MeltFlux_P2.ufl
\ No newline at end of file
diff -r 18d756141ac1 -r 137baa77335a MADDs-5/MADDs-5a/cpp/Projection.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MADDs-5/MADDs-5a/cpp/Projection.cpp	Tue Dec 08 23:31:34 2009 -0500
@@ -0,0 +1,9038 @@
+#include "Projection.h"
+
+/// Constructor
+projection_0_finite_element_0_0::projection_0_finite_element_0_0() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+projection_0_finite_element_0_0::~projection_0_finite_element_0_0()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* projection_0_finite_element_0_0::signature() const
+{
+    return "FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
+}
+
+/// Return the cell shape
+ufc::shape projection_0_finite_element_0_0::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int projection_0_finite_element_0_0::space_dimension() const
+{
+    return 6;
+}
+
+/// Return the rank of the value space
+unsigned int projection_0_finite_element_0_0::value_rank() const
+{
+    return 0;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int projection_0_finite_element_0_0::value_dimension(unsigned int i) const
+{
+    return 1;
+}
+
+/// Evaluate basis function i at given point in cell
+void projection_0_finite_element_0_0::evaluate_basis(unsigned int i,
+                                   double* values,
+                                   const double* coordinates,
+                                   const ufc::cell& c) const
+{
+    // Extract vertex coordinates
+    const double * const * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Reset values
+    *values = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+    const double psitilde_bs_1_0 = 1;
+    const double psitilde_bs_1_1 = 2.5*y + 1.5;
+    const double psitilde_bs_2_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+    const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+    const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[6][6] = \
+    {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+    {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+    {0, 0, 0.2, 0, 0, 0.163299316185545},
+    {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+    {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+    {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+    // Extract relevant coefficients
+    const double coeff0_0 = coefficients0[dof][0];
+    const double coeff0_1 = coefficients0[dof][1];
+    const double coeff0_2 = coefficients0[dof][2];
+    const double coeff0_3 = coefficients0[dof][3];
+    const double coeff0_4 = coefficients0[dof][4];
+    const double coeff0_5 = coefficients0[dof][5];
+    
+    // Compute value(s)
+    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
+}
+
+/// Evaluate all basis functions at given point in cell
+void projection_0_finite_element_0_0::evaluate_basis_all(double* values,
+                                       const double* coordinates,
+                                       const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
+}
+
+/// Evaluate order n derivatives of basis function i at given point in cell
+void projection_0_finite_element_0_0::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 * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 2;
+    
+    
+    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
+    unsigned int **combinations = new unsigned int *[num_derivatives];
+    
+    for (unsigned int j = 0; j < num_derivatives; j++)
+    {
+      combinations[j] = new unsigned int [n];
+      for (unsigned int k = 0; k < n; k++)
+        combinations[j][k] = 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] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
+    
+    // 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
+    for (unsigned int j = 0; j < 1*num_derivatives; j++)
+      values[j] = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+    const double psitilde_bs_1_0 = 1;
+    const double psitilde_bs_1_1 = 2.5*y + 1.5;
+    const double psitilde_bs_2_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+    const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+    const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[6][6] = \
+    {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+    {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+    {0, 0, 0.2, 0, 0, 0.163299316185545},
+    {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+    {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+    {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+    // Interesting (new) part
+    // Tables of derivatives of the polynomial base (transpose)
+    static const double dmats0[6][6] = \
+    {{0, 0, 0, 0, 0, 0},
+    {4.89897948556636, 0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0},
+    {0, 9.48683298050514, 0, 0, 0, 0},
+    {4, 0, 7.07106781186548, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0}};
+    
+    static const double dmats1[6][6] = \
+    {{0, 0, 0, 0, 0, 0},
+    {2.44948974278318, 0, 0, 0, 0, 0},
+    {4.24264068711928, 0, 0, 0, 0, 0},
+    {2.58198889747161, 4.74341649025257, -0.912870929175277, 0, 0, 0},
+    {2, 6.12372435695795, 3.53553390593274, 0, 0, 0},
+    {-2.3094010767585, 0, 8.16496580927726, 0, 0, 0}};
+    
+    // Compute reference derivatives
+    // Declare pointer to array of derivatives on FIAT element
+    double *derivatives = new double [num_derivatives];
+    
+    // Declare coefficients
+    double coeff0_0 = 0;
+    double coeff0_1 = 0;
+    double coeff0_2 = 0;
+    double coeff0_3 = 0;
+    double coeff0_4 = 0;
+    double coeff0_5 = 0;
+    
+    // Declare new coefficients
+    double new_coeff0_0 = 0;
+    double new_coeff0_1 = 0;
+    double new_coeff0_2 = 0;
+    double new_coeff0_3 = 0;
+    double new_coeff0_4 = 0;
+    double new_coeff0_5 = 0;
+    
+    // Loop possible derivatives
+    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+    {
+      // Get values from coefficients array
+      new_coeff0_0 = coefficients0[dof][0];
+      new_coeff0_1 = coefficients0[dof][1];
+      new_coeff0_2 = coefficients0[dof][2];
+      new_coeff0_3 = coefficients0[dof][3];
+      new_coeff0_4 = coefficients0[dof][4];
+      new_coeff0_5 = coefficients0[dof][5];
+    
+      // Loop derivative order
+      for (unsigned int j = 0; j < n; j++)
+      {
+        // Update old coefficients
+        coeff0_0 = new_coeff0_0;
+        coeff0_1 = new_coeff0_1;
+        coeff0_2 = new_coeff0_2;
+        coeff0_3 = new_coeff0_3;
+        coeff0_4 = new_coeff0_4;
+        coeff0_5 = new_coeff0_5;
+    
+        if(combinations[deriv_num][j] == 0)
+        {
+          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
+          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
+          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
+          new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
+          new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
+          new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
+        }
+        if(combinations[deriv_num][j] == 1)
+        {
+          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
+          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
+          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
+          new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
+          new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
+          new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
+        }
+    
+      }
+      // Compute derivatives on reference element as dot product of coefficients and basisvalues
+      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
+    }
+    
+    // Transform derivatives back to physical element
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      for (unsigned int col = 0; col < num_derivatives; col++)
+      {
+        values[row] += transform[row][col]*derivatives[col];
+      }
+    }
+    // Delete pointer to array of derivatives on FIAT element
+    delete [] derivatives;
+    
+    // Delete pointer to array of combinations of derivatives and transform
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      delete [] combinations[row];
+      delete [] transform[row];
+    }
+    
+    delete [] combinations;
+    delete [] transform;
+}
+
+/// Evaluate order n derivatives of all basis functions at given point in cell
+void projection_0_finite_element_0_0::evaluate_basis_derivatives_all(unsigned int n,
+                                                   double* values,
+                                                   const double* coordinates,
+                                                   const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
+}
+
+/// Evaluate linear functional for dof i on the function f
+double projection_0_finite_element_0_0::evaluate_dof(unsigned int i,
+                                   const ufc::function& f,
+                                   const ufc::cell& c) const
+{
+    // The reference points, direction and weights:
+    static const double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}};
+    static const double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
+    static const double D[6][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}, {{1}}, {{1}}};
+    
+    const double * const * x = c.coordinates;
+    double result = 0.0;
+    // Iterate over the points:
+    // Evaluate basis functions for affine mapping
+    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    
+    // Compute affine mapping y = F(X)
+    double y[2];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
+    
+    // Evaluate function at physical points
+    double values[1];
+    f.evaluate(values, y, c);
+    
+    // Map function values using appropriate mapping
+    // Affine map: Do nothing
+    
+    // Note that we do not map the weights (yet).
+    
+    // Take directional components
+    for(int k = 0; k < 1; k++)
+      result += values[k]*D[i][0][k];
+    // Multiply by weights
+    result *= W[i][0];
+    
+    return result;
+}
+
+/// Evaluate linear functionals for all dofs on the function f
+void projection_0_finite_element_0_0::evaluate_dofs(double* values,
+                                  const ufc::function& f,
+                                  const ufc::cell& c) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Interpolate vertex values from dof values
+void projection_0_finite_element_0_0::interpolate_vertex_values(double* vertex_values,
+                                              const double* dof_values,
+                                              const ufc::cell& c) const
+{
+    // Evaluate at vertices and use affine mapping
+    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)
+unsigned int projection_0_finite_element_0_0::num_sub_elements() const
+{
+    return 1;
+}
+
+/// Create a new finite element for sub element i (for a mixed element)
+ufc::finite_element* projection_0_finite_element_0_0::create_sub_element(unsigned int i) const
+{
+    return new projection_0_finite_element_0_0();
+}
+
+
+/// Constructor
+projection_0_finite_element_0_1::projection_0_finite_element_0_1() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+projection_0_finite_element_0_1::~projection_0_finite_element_0_1()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* projection_0_finite_element_0_1::signature() const
+{
+    return "FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
+}
+
+/// Return the cell shape
+ufc::shape projection_0_finite_element_0_1::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int projection_0_finite_element_0_1::space_dimension() const
+{
+    return 6;
+}
+
+/// Return the rank of the value space
+unsigned int projection_0_finite_element_0_1::value_rank() const
+{
+    return 0;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int projection_0_finite_element_0_1::value_dimension(unsigned int i) const
+{
+    return 1;
+}
+
+/// Evaluate basis function i at given point in cell
+void projection_0_finite_element_0_1::evaluate_basis(unsigned int i,
+                                   double* values,
+                                   const double* coordinates,
+                                   const ufc::cell& c) const
+{
+    // Extract vertex coordinates
+    const double * const * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Reset values
+    *values = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+    const double psitilde_bs_1_0 = 1;
+    const double psitilde_bs_1_1 = 2.5*y + 1.5;
+    const double psitilde_bs_2_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+    const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+    const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[6][6] = \
+    {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+    {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+    {0, 0, 0.2, 0, 0, 0.163299316185545},
+    {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+    {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+    {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+    // Extract relevant coefficients
+    const double coeff0_0 = coefficients0[dof][0];
+    const double coeff0_1 = coefficients0[dof][1];
+    const double coeff0_2 = coefficients0[dof][2];
+    const double coeff0_3 = coefficients0[dof][3];
+    const double coeff0_4 = coefficients0[dof][4];
+    const double coeff0_5 = coefficients0[dof][5];
+    
+    // Compute value(s)
+    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
+}
+
+/// Evaluate all basis functions at given point in cell
+void projection_0_finite_element_0_1::evaluate_basis_all(double* values,
+                                       const double* coordinates,
+                                       const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
+}
+
+/// Evaluate order n derivatives of basis function i at given point in cell
+void projection_0_finite_element_0_1::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 * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 2;
+    
+    
+    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
+    unsigned int **combinations = new unsigned int *[num_derivatives];
+    
+    for (unsigned int j = 0; j < num_derivatives; j++)
+    {
+      combinations[j] = new unsigned int [n];
+      for (unsigned int k = 0; k < n; k++)
+        combinations[j][k] = 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] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
+    
+    // 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
+    for (unsigned int j = 0; j < 1*num_derivatives; j++)
+      values[j] = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+    const double psitilde_bs_1_0 = 1;
+    const double psitilde_bs_1_1 = 2.5*y + 1.5;
+    const double psitilde_bs_2_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+    const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+    const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[6][6] = \
+    {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+    {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+    {0, 0, 0.2, 0, 0, 0.163299316185545},
+    {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+    {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+    {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+    // Interesting (new) part
+    // Tables of derivatives of the polynomial base (transpose)
+    static const double dmats0[6][6] = \
+    {{0, 0, 0, 0, 0, 0},
+    {4.89897948556636, 0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0},
+    {0, 9.48683298050514, 0, 0, 0, 0},
+    {4, 0, 7.07106781186548, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0}};
+    
+    static const double dmats1[6][6] = \
+    {{0, 0, 0, 0, 0, 0},
+    {2.44948974278318, 0, 0, 0, 0, 0},
+    {4.24264068711928, 0, 0, 0, 0, 0},
+    {2.58198889747161, 4.74341649025257, -0.912870929175277, 0, 0, 0},
+    {2, 6.12372435695795, 3.53553390593274, 0, 0, 0},
+    {-2.3094010767585, 0, 8.16496580927726, 0, 0, 0}};
+    
+    // Compute reference derivatives
+    // Declare pointer to array of derivatives on FIAT element
+    double *derivatives = new double [num_derivatives];
+    
+    // Declare coefficients
+    double coeff0_0 = 0;
+    double coeff0_1 = 0;
+    double coeff0_2 = 0;
+    double coeff0_3 = 0;
+    double coeff0_4 = 0;
+    double coeff0_5 = 0;
+    
+    // Declare new coefficients
+    double new_coeff0_0 = 0;
+    double new_coeff0_1 = 0;
+    double new_coeff0_2 = 0;
+    double new_coeff0_3 = 0;
+    double new_coeff0_4 = 0;
+    double new_coeff0_5 = 0;
+    
+    // Loop possible derivatives
+    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+    {
+      // Get values from coefficients array
+      new_coeff0_0 = coefficients0[dof][0];
+      new_coeff0_1 = coefficients0[dof][1];
+      new_coeff0_2 = coefficients0[dof][2];
+      new_coeff0_3 = coefficients0[dof][3];
+      new_coeff0_4 = coefficients0[dof][4];
+      new_coeff0_5 = coefficients0[dof][5];
+    
+      // Loop derivative order
+      for (unsigned int j = 0; j < n; j++)
+      {
+        // Update old coefficients
+        coeff0_0 = new_coeff0_0;
+        coeff0_1 = new_coeff0_1;
+        coeff0_2 = new_coeff0_2;
+        coeff0_3 = new_coeff0_3;
+        coeff0_4 = new_coeff0_4;
+        coeff0_5 = new_coeff0_5;
+    
+        if(combinations[deriv_num][j] == 0)
+        {
+          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
+          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
+          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
+          new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
+          new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
+          new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
+        }
+        if(combinations[deriv_num][j] == 1)
+        {
+          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
+          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
+          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
+          new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
+          new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
+          new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
+        }
+    
+      }
+      // Compute derivatives on reference element as dot product of coefficients and basisvalues
+      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
+    }
+    
+    // Transform derivatives back to physical element
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      for (unsigned int col = 0; col < num_derivatives; col++)
+      {
+        values[row] += transform[row][col]*derivatives[col];
+      }
+    }
+    // Delete pointer to array of derivatives on FIAT element
+    delete [] derivatives;
+    
+    // Delete pointer to array of combinations of derivatives and transform
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      delete [] combinations[row];
+      delete [] transform[row];
+    }
+    
+    delete [] combinations;
+    delete [] transform;
+}
+
+/// Evaluate order n derivatives of all basis functions at given point in cell
+void projection_0_finite_element_0_1::evaluate_basis_derivatives_all(unsigned int n,
+                                                   double* values,
+                                                   const double* coordinates,
+                                                   const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
+}
+
+/// Evaluate linear functional for dof i on the function f
+double projection_0_finite_element_0_1::evaluate_dof(unsigned int i,
+                                   const ufc::function& f,
+                                   const ufc::cell& c) const
+{
+    // The reference points, direction and weights:
+    static const double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}};
+    static const double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
+    static const double D[6][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}, {{1}}, {{1}}};
+    
+    const double * const * x = c.coordinates;
+    double result = 0.0;
+    // Iterate over the points:
+    // Evaluate basis functions for affine mapping
+    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    
+    // Compute affine mapping y = F(X)
+    double y[2];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
+    
+    // Evaluate function at physical points
+    double values[1];
+    f.evaluate(values, y, c);
+    
+    // Map function values using appropriate mapping
+    // Affine map: Do nothing
+    
+    // Note that we do not map the weights (yet).
+    
+    // Take directional components
+    for(int k = 0; k < 1; k++)
+      result += values[k]*D[i][0][k];
+    // Multiply by weights
+    result *= W[i][0];
+    
+    return result;
+}
+
+/// Evaluate linear functionals for all dofs on the function f
+void projection_0_finite_element_0_1::evaluate_dofs(double* values,
+                                  const ufc::function& f,
+                                  const ufc::cell& c) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Interpolate vertex values from dof values
+void projection_0_finite_element_0_1::interpolate_vertex_values(double* vertex_values,
+                                              const double* dof_values,
+                                              const ufc::cell& c) const
+{
+    // Evaluate at vertices and use affine mapping
+    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)
+unsigned int projection_0_finite_element_0_1::num_sub_elements() const
+{
+    return 1;
+}
+
+/// Create a new finite element for sub element i (for a mixed element)
+ufc::finite_element* projection_0_finite_element_0_1::create_sub_element(unsigned int i) const
+{
+    return new projection_0_finite_element_0_1();
+}
+
+
+/// Constructor
+projection_0_finite_element_0::projection_0_finite_element_0() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+projection_0_finite_element_0::~projection_0_finite_element_0()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* projection_0_finite_element_0::signature() const
+{
+    return "VectorElement('Lagrange', Cell('triangle', 1, Space(2)), 2, 2)";
+}
+
+/// Return the cell shape
+ufc::shape projection_0_finite_element_0::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int projection_0_finite_element_0::space_dimension() const
+{
+    return 12;
+}
+
+/// Return the rank of the value space
+unsigned int projection_0_finite_element_0::value_rank() const
+{
+    return 1;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int projection_0_finite_element_0::value_dimension(unsigned int i) const
+{
+    return 2;
+}
+
+/// Evaluate basis function i at given point in cell
+void projection_0_finite_element_0::evaluate_basis(unsigned int i,
+                                   double* values,
+                                   const double* coordinates,
+                                   const ufc::cell& c) const
+{
+    // Extract vertex coordinates
+    const double * const * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Reset values
+    values[0] = 0;
+    values[1] = 0;
+    
+    if (0 <= i && i <= 5)
+    {
+      // Map degree of freedom to element degree of freedom
+      const unsigned int dof = i;
+    
+      // Generate scalings
+      const double scalings_y_0 = 1;
+      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+      const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+      // Compute psitilde_a
+      const double psitilde_a_0 = 1;
+      const double psitilde_a_1 = x;
+      const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+      // Compute psitilde_bs
+      const double psitilde_bs_0_0 = 1;
+      const double psitilde_bs_0_1 = 1.5*y + 0.5;
+      const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+      const double psitilde_bs_1_0 = 1;
+      const double psitilde_bs_1_1 = 2.5*y + 1.5;
+      const double psitilde_bs_2_0 = 1;
+    
+      // Compute basisvalues
+      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+      const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+      const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+      const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+      // Table(s) of coefficients
+      static const double coefficients0[6][6] =   \
+      {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+      {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+      {0, 0, 0.2, 0, 0, 0.163299316185545},
+      {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+      {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+      {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+      // Extract relevant coefficients
+      const double coeff0_0 =   coefficients0[dof][0];
+      const double coeff0_1 =   coefficients0[dof][1];
+      const double coeff0_2 =   coefficients0[dof][2];
+      const double coeff0_3 =   coefficients0[dof][3];
+      const double coeff0_4 =   coefficients0[dof][4];
+      const double coeff0_5 =   coefficients0[dof][5];
+    
+      // Compute value(s)
+      values[0] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
+    }
+    
+    if (6 <= i && i <= 11)
+    {
+      // Map degree of freedom to element degree of freedom
+      const unsigned int dof = i - 6;
+    
+      // Generate scalings
+      const double scalings_y_0 = 1;
+      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+      const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+      // Compute psitilde_a
+      const double psitilde_a_0 = 1;
+      const double psitilde_a_1 = x;
+      const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+      // Compute psitilde_bs
+      const double psitilde_bs_0_0 = 1;
+      const double psitilde_bs_0_1 = 1.5*y + 0.5;
+      const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+      const double psitilde_bs_1_0 = 1;
+      const double psitilde_bs_1_1 = 2.5*y + 1.5;
+      const double psitilde_bs_2_0 = 1;
+    
+      // Compute basisvalues
+      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+      const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+      const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+      const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+      // Table(s) of coefficients
+      static const double coefficients0[6][6] =   \
+      {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+      {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+      {0, 0, 0.2, 0, 0, 0.163299316185545},
+      {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+      {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+      {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+      // Extract relevant coefficients
+      const double coeff0_0 =   coefficients0[dof][0];
+      const double coeff0_1 =   coefficients0[dof][1];
+      const double coeff0_2 =   coefficients0[dof][2];
+      const double coeff0_3 =   coefficients0[dof][3];
+      const double coeff0_4 =   coefficients0[dof][4];
+      const double coeff0_5 =   coefficients0[dof][5];
+    
+      // Compute value(s)
+      values[1] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
+    }
+    
+}
+
+/// Evaluate all basis functions at given point in cell
+void projection_0_finite_element_0::evaluate_basis_all(double* values,
+                                       const double* coordinates,
+                                       const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
+}
+
+/// Evaluate order n derivatives of basis function i at given point in cell
+void projection_0_finite_element_0::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 * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 2;
+    
+    
+    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
+    unsigned int **combinations = new unsigned int *[num_derivatives];
+    
+    for (unsigned int j = 0; j < num_derivatives; j++)
+    {
+      combinations[j] = new unsigned int [n];
+      for (unsigned int k = 0; k < n; k++)
+        combinations[j][k] = 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] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
+    
+    // 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
+    for (unsigned int j = 0; j < 2*num_derivatives; j++)
+      values[j] = 0;
+    
+    if (0 <= i && i <= 5)
+    {
+      // Map degree of freedom to element degree of freedom
+      const unsigned int dof = i;
+    
+      // Generate scalings
+      const double scalings_y_0 = 1;
+      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+      const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+      // Compute psitilde_a
+      const double psitilde_a_0 = 1;
+      const double psitilde_a_1 = x;
+      const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+      // Compute psitilde_bs
+      const double psitilde_bs_0_0 = 1;
+      const double psitilde_bs_0_1 = 1.5*y + 0.5;
+      const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+      const double psitilde_bs_1_0 = 1;
+      const double psitilde_bs_1_1 = 2.5*y + 1.5;
+      const double psitilde_bs_2_0 = 1;
+    
+      // Compute basisvalues
+      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+      const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+      const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+      const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+      // Table(s) of coefficients
+      static const double coefficients0[6][6] =   \
+      {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+      {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+      {0, 0, 0.2, 0, 0, 0.163299316185545},
+      {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+      {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+      {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+      // Interesting (new) part
+      // Tables of derivatives of the polynomial base (transpose)
+      static const double dmats0[6][6] =   \
+      {{0, 0, 0, 0, 0, 0},
+      {4.89897948556636, 0, 0, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0},
+      {0, 9.48683298050514, 0, 0, 0, 0},
+      {4, 0, 7.07106781186548, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0}};
+    
+      static const double dmats1[6][6] =   \
+      {{0, 0, 0, 0, 0, 0},
+      {2.44948974278318, 0, 0, 0, 0, 0},
+      {4.24264068711928, 0, 0, 0, 0, 0},
+      {2.58198889747161, 4.74341649025257, -0.912870929175277, 0, 0, 0},
+      {2, 6.12372435695795, 3.53553390593274, 0, 0, 0},
+      {-2.3094010767585, 0, 8.16496580927726, 0, 0, 0}};
+    
+      // Compute reference derivatives
+      // Declare pointer to array of derivatives on FIAT element
+      double *derivatives = new double [num_derivatives];
+    
+      // Declare coefficients
+      double coeff0_0 = 0;
+      double coeff0_1 = 0;
+      double coeff0_2 = 0;
+      double coeff0_3 = 0;
+      double coeff0_4 = 0;
+      double coeff0_5 = 0;
+    
+      // Declare new coefficients
+      double new_coeff0_0 = 0;
+      double new_coeff0_1 = 0;
+      double new_coeff0_2 = 0;
+      double new_coeff0_3 = 0;
+      double new_coeff0_4 = 0;
+      double new_coeff0_5 = 0;
+    
+      // Loop possible derivatives
+      for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+      {
+        // Get values from coefficients array
+        new_coeff0_0 = coefficients0[dof][0];
+        new_coeff0_1 = coefficients0[dof][1];
+        new_coeff0_2 = coefficients0[dof][2];
+        new_coeff0_3 = coefficients0[dof][3];
+        new_coeff0_4 = coefficients0[dof][4];
+        new_coeff0_5 = coefficients0[dof][5];
+    
+        // Loop derivative order
+        for (unsigned int j = 0; j < n; j++)
+        {
+          // Update old coefficients
+          coeff0_0 = new_coeff0_0;
+          coeff0_1 = new_coeff0_1;
+          coeff0_2 = new_coeff0_2;
+          coeff0_3 = new_coeff0_3;
+          coeff0_4 = new_coeff0_4;
+          coeff0_5 = new_coeff0_5;
+    
+          if(combinations[deriv_num][j] == 0)
+          {
+            new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
+            new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
+            new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
+            new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
+            new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
+            new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
+          }
+          if(combinations[deriv_num][j] == 1)
+          {
+            new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
+            new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
+            new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
+            new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
+            new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
+            new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
+          }
+    
+        }
+        // Compute derivatives on reference element as dot product of coefficients and basisvalues
+        derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
+      }
+    
+      // Transform derivatives back to physical element
+      for (unsigned int row = 0; row < num_derivatives; row++)
+      {
+        for (unsigned int col = 0; col < num_derivatives; col++)
+        {
+          values[row] += transform[row][col]*derivatives[col];
+        }
+      }
+      // Delete pointer to array of derivatives on FIAT element
+      delete [] derivatives;
+    
+      // Delete pointer to array of combinations of derivatives and transform
+      for (unsigned int row = 0; row < num_derivatives; row++)
+      {
+        delete [] combinations[row];
+        delete [] transform[row];
+      }
+    
+      delete [] combinations;
+      delete [] transform;
+    }
+    
+    if (6 <= i && i <= 11)
+    {
+      // Map degree of freedom to element degree of freedom
+      const unsigned int dof = i - 6;
+    
+      // Generate scalings
+      const double scalings_y_0 = 1;
+      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+      const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+      // Compute psitilde_a
+      const double psitilde_a_0 = 1;
+      const double psitilde_a_1 = x;
+      const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+      // Compute psitilde_bs
+      const double psitilde_bs_0_0 = 1;
+      const double psitilde_bs_0_1 = 1.5*y + 0.5;
+      const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+      const double psitilde_bs_1_0 = 1;
+      const double psitilde_bs_1_1 = 2.5*y + 1.5;
+      const double psitilde_bs_2_0 = 1;
+    
+      // Compute basisvalues
+      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+      const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+      const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+      const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+      // Table(s) of coefficients
+      static const double coefficients0[6][6] =   \
+      {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+      {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+      {0, 0, 0.2, 0, 0, 0.163299316185545},
+      {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+      {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+      {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+      // Interesting (new) part
+      // Tables of derivatives of the polynomial base (transpose)
+      static const double dmats0[6][6] =   \
+      {{0, 0, 0, 0, 0, 0},
+      {4.89897948556636, 0, 0, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0},
+      {0, 9.48683298050514, 0, 0, 0, 0},
+      {4, 0, 7.07106781186548, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0}};
+    
+      static const double dmats1[6][6] =   \
+      {{0, 0, 0, 0, 0, 0},
+      {2.44948974278318, 0, 0, 0, 0, 0},
+      {4.24264068711928, 0, 0, 0, 0, 0},
+      {2.58198889747161, 4.74341649025257, -0.912870929175277, 0, 0, 0},
+      {2, 6.12372435695795, 3.53553390593274, 0, 0, 0},
+      {-2.3094010767585, 0, 8.16496580927726, 0, 0, 0}};
+    
+      // Compute reference derivatives
+      // Declare pointer to array of derivatives on FIAT element
+      double *derivatives = new double [num_derivatives];
+    
+      // Declare coefficients
+      double coeff0_0 = 0;
+      double coeff0_1 = 0;
+      double coeff0_2 = 0;
+      double coeff0_3 = 0;
+      double coeff0_4 = 0;
+      double coeff0_5 = 0;
+    
+      // Declare new coefficients
+      double new_coeff0_0 = 0;
+      double new_coeff0_1 = 0;
+      double new_coeff0_2 = 0;
+      double new_coeff0_3 = 0;
+      double new_coeff0_4 = 0;
+      double new_coeff0_5 = 0;
+    
+      // Loop possible derivatives
+      for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+      {
+        // Get values from coefficients array
+        new_coeff0_0 = coefficients0[dof][0];
+        new_coeff0_1 = coefficients0[dof][1];
+        new_coeff0_2 = coefficients0[dof][2];
+        new_coeff0_3 = coefficients0[dof][3];
+        new_coeff0_4 = coefficients0[dof][4];
+        new_coeff0_5 = coefficients0[dof][5];
+    
+        // Loop derivative order
+        for (unsigned int j = 0; j < n; j++)
+        {
+          // Update old coefficients
+          coeff0_0 = new_coeff0_0;
+          coeff0_1 = new_coeff0_1;
+          coeff0_2 = new_coeff0_2;
+          coeff0_3 = new_coeff0_3;
+          coeff0_4 = new_coeff0_4;
+          coeff0_5 = new_coeff0_5;
+    
+          if(combinations[deriv_num][j] == 0)
+          {
+            new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
+            new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
+            new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
+            new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
+            new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
+            new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
+          }
+          if(combinations[deriv_num][j] == 1)
+          {
+            new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
+            new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
+            new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
+            new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
+            new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
+            new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
+          }
+    
+        }
+        // Compute derivatives on reference element as dot product of coefficients and basisvalues
+        derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
+      }
+    
+      // Transform derivatives back to physical element
+      for (unsigned int row = 0; row < num_derivatives; row++)
+      {
+        for (unsigned int col = 0; col < num_derivatives; col++)
+        {
+          values[num_derivatives + row] += transform[row][col]*derivatives[col];
+        }
+      }
+      // Delete pointer to array of derivatives on FIAT element
+      delete [] derivatives;
+    
+      // Delete pointer to array of combinations of derivatives and transform
+      for (unsigned int row = 0; row < num_derivatives; row++)
+      {
+        delete [] combinations[row];
+        delete [] transform[row];
+      }
+    
+      delete [] combinations;
+      delete [] transform;
+    }
+    
+}
+
+/// Evaluate order n derivatives of all basis functions at given point in cell
+void projection_0_finite_element_0::evaluate_basis_derivatives_all(unsigned int n,
+                                                   double* values,
+                                                   const double* coordinates,
+                                                   const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
+}
+
+/// Evaluate linear functional for dof i on the function f
+double projection_0_finite_element_0::evaluate_dof(unsigned int i,
+                                   const ufc::function& f,
+                                   const ufc::cell& c) const
+{
+    // The reference points, direction and weights:
+    static const double X[12][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}, {{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}};
+    static const double W[12][1] = {{1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}};
+    static const double D[12][1][2] = {{{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{0, 1}}, {{0, 1}}, {{0, 1}}, {{0, 1}}, {{0, 1}}, {{0, 1}}};
+    
+    const double * const * x = c.coordinates;
+    double result = 0.0;
+    // Iterate over the points:
+    // Evaluate basis functions for affine mapping
+    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    
+    // Compute affine mapping y = F(X)
+    double y[2];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
+    
+    // Evaluate function at physical points
+    double values[2];
+    f.evaluate(values, y, c);
+    
+    // Map function values using appropriate mapping
+    // Affine map: Do nothing
+    
+    // Note that we do not map the weights (yet).
+    
+    // Take directional components
+    for(int k = 0; k < 2; k++)
+      result += values[k]*D[i][0][k];
+    // Multiply by weights
+    result *= W[i][0];
+    
+    return result;
+}
+
+/// Evaluate linear functionals for all dofs on the function f
+void projection_0_finite_element_0::evaluate_dofs(double* values,
+                                  const ufc::function& f,
+                                  const ufc::cell& c) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Interpolate vertex values from dof values
+void projection_0_finite_element_0::interpolate_vertex_values(double* vertex_values,
+                                              const double* dof_values,
+                                              const ufc::cell& c) const
+{
+    // Evaluate at vertices and use affine mapping
+    vertex_values[0] = dof_values[0];
+    vertex_values[2] = dof_values[1];
+    vertex_values[4] = dof_values[2];
+    // Evaluate at vertices and use affine mapping
+    vertex_values[1] = dof_values[6];
+    vertex_values[3] = dof_values[7];
+    vertex_values[5] = dof_values[8];
+}
+
+/// Return the number of sub elements (for a mixed element)
+unsigned int projection_0_finite_element_0::num_sub_elements() const
+{
+    return 2;
+}
+
+/// Create a new finite element for sub element i (for a mixed element)
+ufc::finite_element* projection_0_finite_element_0::create_sub_element(unsigned int i) const
+{
+    switch ( i )
+    {
+    case 0:
+      return new projection_0_finite_element_0_0();
+      break;
+    case 1:
+      return new projection_0_finite_element_0_1();
+      break;
+    }
+    return 0;
+}
+
+
+/// Constructor
+projection_0_finite_element_1_0::projection_0_finite_element_1_0() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+projection_0_finite_element_1_0::~projection_0_finite_element_1_0()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* projection_0_finite_element_1_0::signature() const
+{
+    return "FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
+}
+
+/// Return the cell shape
+ufc::shape projection_0_finite_element_1_0::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int projection_0_finite_element_1_0::space_dimension() const
+{
+    return 6;
+}
+
+/// Return the rank of the value space
+unsigned int projection_0_finite_element_1_0::value_rank() const
+{
+    return 0;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int projection_0_finite_element_1_0::value_dimension(unsigned int i) const
+{
+    return 1;
+}
+
+/// Evaluate basis function i at given point in cell
+void projection_0_finite_element_1_0::evaluate_basis(unsigned int i,
+                                   double* values,
+                                   const double* coordinates,
+                                   const ufc::cell& c) const
+{
+    // Extract vertex coordinates
+    const double * const * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Reset values
+    *values = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+    const double psitilde_bs_1_0 = 1;
+    const double psitilde_bs_1_1 = 2.5*y + 1.5;
+    const double psitilde_bs_2_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+    const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+    const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[6][6] = \
+    {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+    {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+    {0, 0, 0.2, 0, 0, 0.163299316185545},
+    {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+    {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+    {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+    // Extract relevant coefficients
+    const double coeff0_0 = coefficients0[dof][0];
+    const double coeff0_1 = coefficients0[dof][1];
+    const double coeff0_2 = coefficients0[dof][2];
+    const double coeff0_3 = coefficients0[dof][3];
+    const double coeff0_4 = coefficients0[dof][4];
+    const double coeff0_5 = coefficients0[dof][5];
+    
+    // Compute value(s)
+    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
+}
+
+/// Evaluate all basis functions at given point in cell
+void projection_0_finite_element_1_0::evaluate_basis_all(double* values,
+                                       const double* coordinates,
+                                       const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
+}
+
+/// Evaluate order n derivatives of basis function i at given point in cell
+void projection_0_finite_element_1_0::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 * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 2;
+    
+    
+    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
+    unsigned int **combinations = new unsigned int *[num_derivatives];
+    
+    for (unsigned int j = 0; j < num_derivatives; j++)
+    {
+      combinations[j] = new unsigned int [n];
+      for (unsigned int k = 0; k < n; k++)
+        combinations[j][k] = 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] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
+    
+    // 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
+    for (unsigned int j = 0; j < 1*num_derivatives; j++)
+      values[j] = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+    const double psitilde_bs_1_0 = 1;
+    const double psitilde_bs_1_1 = 2.5*y + 1.5;
+    const double psitilde_bs_2_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+    const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+    const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[6][6] = \
+    {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+    {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+    {0, 0, 0.2, 0, 0, 0.163299316185545},
+    {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+    {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+    {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+    // Interesting (new) part
+    // Tables of derivatives of the polynomial base (transpose)
+    static const double dmats0[6][6] = \
+    {{0, 0, 0, 0, 0, 0},
+    {4.89897948556636, 0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0},
+    {0, 9.48683298050514, 0, 0, 0, 0},
+    {4, 0, 7.07106781186548, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0}};
+    
+    static const double dmats1[6][6] = \
+    {{0, 0, 0, 0, 0, 0},
+    {2.44948974278318, 0, 0, 0, 0, 0},
+    {4.24264068711928, 0, 0, 0, 0, 0},
+    {2.58198889747161, 4.74341649025257, -0.912870929175277, 0, 0, 0},
+    {2, 6.12372435695795, 3.53553390593274, 0, 0, 0},
+    {-2.3094010767585, 0, 8.16496580927726, 0, 0, 0}};
+    
+    // Compute reference derivatives
+    // Declare pointer to array of derivatives on FIAT element
+    double *derivatives = new double [num_derivatives];
+    
+    // Declare coefficients
+    double coeff0_0 = 0;
+    double coeff0_1 = 0;
+    double coeff0_2 = 0;
+    double coeff0_3 = 0;
+    double coeff0_4 = 0;
+    double coeff0_5 = 0;
+    
+    // Declare new coefficients
+    double new_coeff0_0 = 0;
+    double new_coeff0_1 = 0;
+    double new_coeff0_2 = 0;
+    double new_coeff0_3 = 0;
+    double new_coeff0_4 = 0;
+    double new_coeff0_5 = 0;
+    
+    // Loop possible derivatives
+    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+    {
+      // Get values from coefficients array
+      new_coeff0_0 = coefficients0[dof][0];
+      new_coeff0_1 = coefficients0[dof][1];
+      new_coeff0_2 = coefficients0[dof][2];
+      new_coeff0_3 = coefficients0[dof][3];
+      new_coeff0_4 = coefficients0[dof][4];
+      new_coeff0_5 = coefficients0[dof][5];
+    
+      // Loop derivative order
+      for (unsigned int j = 0; j < n; j++)
+      {
+        // Update old coefficients
+        coeff0_0 = new_coeff0_0;
+        coeff0_1 = new_coeff0_1;
+        coeff0_2 = new_coeff0_2;
+        coeff0_3 = new_coeff0_3;
+        coeff0_4 = new_coeff0_4;
+        coeff0_5 = new_coeff0_5;
+    
+        if(combinations[deriv_num][j] == 0)
+        {
+          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
+          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
+          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
+          new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
+          new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
+          new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
+        }
+        if(combinations[deriv_num][j] == 1)
+        {
+          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
+          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
+          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
+          new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
+          new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
+          new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
+        }
+    
+      }
+      // Compute derivatives on reference element as dot product of coefficients and basisvalues
+      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
+    }
+    
+    // Transform derivatives back to physical element
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      for (unsigned int col = 0; col < num_derivatives; col++)
+      {
+        values[row] += transform[row][col]*derivatives[col];
+      }
+    }
+    // Delete pointer to array of derivatives on FIAT element
+    delete [] derivatives;
+    
+    // Delete pointer to array of combinations of derivatives and transform
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      delete [] combinations[row];
+      delete [] transform[row];
+    }
+    
+    delete [] combinations;
+    delete [] transform;
+}
+
+/// Evaluate order n derivatives of all basis functions at given point in cell
+void projection_0_finite_element_1_0::evaluate_basis_derivatives_all(unsigned int n,
+                                                   double* values,
+                                                   const double* coordinates,
+                                                   const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
+}
+
+/// Evaluate linear functional for dof i on the function f
+double projection_0_finite_element_1_0::evaluate_dof(unsigned int i,
+                                   const ufc::function& f,
+                                   const ufc::cell& c) const
+{
+    // The reference points, direction and weights:
+    static const double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}};
+    static const double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
+    static const double D[6][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}, {{1}}, {{1}}};
+    
+    const double * const * x = c.coordinates;
+    double result = 0.0;
+    // Iterate over the points:
+    // Evaluate basis functions for affine mapping
+    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    
+    // Compute affine mapping y = F(X)
+    double y[2];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
+    
+    // Evaluate function at physical points
+    double values[1];
+    f.evaluate(values, y, c);
+    
+    // Map function values using appropriate mapping
+    // Affine map: Do nothing
+    
+    // Note that we do not map the weights (yet).
+    
+    // Take directional components
+    for(int k = 0; k < 1; k++)
+      result += values[k]*D[i][0][k];
+    // Multiply by weights
+    result *= W[i][0];
+    
+    return result;
+}
+
+/// Evaluate linear functionals for all dofs on the function f
+void projection_0_finite_element_1_0::evaluate_dofs(double* values,
+                                  const ufc::function& f,
+                                  const ufc::cell& c) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Interpolate vertex values from dof values
+void projection_0_finite_element_1_0::interpolate_vertex_values(double* vertex_values,
+                                              const double* dof_values,
+                                              const ufc::cell& c) const
+{
+    // Evaluate at vertices and use affine mapping
+    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)
+unsigned int projection_0_finite_element_1_0::num_sub_elements() const
+{
+    return 1;
+}
+
+/// Create a new finite element for sub element i (for a mixed element)
+ufc::finite_element* projection_0_finite_element_1_0::create_sub_element(unsigned int i) const
+{
+    return new projection_0_finite_element_1_0();
+}
+
+
+/// Constructor
+projection_0_finite_element_1_1::projection_0_finite_element_1_1() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+projection_0_finite_element_1_1::~projection_0_finite_element_1_1()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* projection_0_finite_element_1_1::signature() const
+{
+    return "FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
+}
+
+/// Return the cell shape
+ufc::shape projection_0_finite_element_1_1::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int projection_0_finite_element_1_1::space_dimension() const
+{
+    return 6;
+}
+
+/// Return the rank of the value space
+unsigned int projection_0_finite_element_1_1::value_rank() const
+{
+    return 0;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int projection_0_finite_element_1_1::value_dimension(unsigned int i) const
+{
+    return 1;
+}
+
+/// Evaluate basis function i at given point in cell
+void projection_0_finite_element_1_1::evaluate_basis(unsigned int i,
+                                   double* values,
+                                   const double* coordinates,
+                                   const ufc::cell& c) const
+{
+    // Extract vertex coordinates
+    const double * const * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Reset values
+    *values = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+    const double psitilde_bs_1_0 = 1;
+    const double psitilde_bs_1_1 = 2.5*y + 1.5;
+    const double psitilde_bs_2_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+    const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+    const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[6][6] = \
+    {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+    {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+    {0, 0, 0.2, 0, 0, 0.163299316185545},
+    {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+    {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+    {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+    // Extract relevant coefficients
+    const double coeff0_0 = coefficients0[dof][0];
+    const double coeff0_1 = coefficients0[dof][1];
+    const double coeff0_2 = coefficients0[dof][2];
+    const double coeff0_3 = coefficients0[dof][3];
+    const double coeff0_4 = coefficients0[dof][4];
+    const double coeff0_5 = coefficients0[dof][5];
+    
+    // Compute value(s)
+    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
+}
+
+/// Evaluate all basis functions at given point in cell
+void projection_0_finite_element_1_1::evaluate_basis_all(double* values,
+                                       const double* coordinates,
+                                       const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
+}
+
+/// Evaluate order n derivatives of basis function i at given point in cell
+void projection_0_finite_element_1_1::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 * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 2;
+    
+    
+    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
+    unsigned int **combinations = new unsigned int *[num_derivatives];
+    
+    for (unsigned int j = 0; j < num_derivatives; j++)
+    {
+      combinations[j] = new unsigned int [n];
+      for (unsigned int k = 0; k < n; k++)
+        combinations[j][k] = 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] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
+    
+    // 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
+    for (unsigned int j = 0; j < 1*num_derivatives; j++)
+      values[j] = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+    const double psitilde_bs_1_0 = 1;
+    const double psitilde_bs_1_1 = 2.5*y + 1.5;
+    const double psitilde_bs_2_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+    const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+    const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[6][6] = \
+    {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+    {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+    {0, 0, 0.2, 0, 0, 0.163299316185545},
+    {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+    {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+    {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+    // Interesting (new) part
+    // Tables of derivatives of the polynomial base (transpose)
+    static const double dmats0[6][6] = \
+    {{0, 0, 0, 0, 0, 0},
+    {4.89897948556636, 0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0},
+    {0, 9.48683298050514, 0, 0, 0, 0},
+    {4, 0, 7.07106781186548, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0}};
+    
+    static const double dmats1[6][6] = \
+    {{0, 0, 0, 0, 0, 0},
+    {2.44948974278318, 0, 0, 0, 0, 0},
+    {4.24264068711928, 0, 0, 0, 0, 0},
+    {2.58198889747161, 4.74341649025257, -0.912870929175277, 0, 0, 0},
+    {2, 6.12372435695795, 3.53553390593274, 0, 0, 0},
+    {-2.3094010767585, 0, 8.16496580927726, 0, 0, 0}};
+    
+    // Compute reference derivatives
+    // Declare pointer to array of derivatives on FIAT element
+    double *derivatives = new double [num_derivatives];
+    
+    // Declare coefficients
+    double coeff0_0 = 0;
+    double coeff0_1 = 0;
+    double coeff0_2 = 0;
+    double coeff0_3 = 0;
+    double coeff0_4 = 0;
+    double coeff0_5 = 0;
+    
+    // Declare new coefficients
+    double new_coeff0_0 = 0;
+    double new_coeff0_1 = 0;
+    double new_coeff0_2 = 0;
+    double new_coeff0_3 = 0;
+    double new_coeff0_4 = 0;
+    double new_coeff0_5 = 0;
+    
+    // Loop possible derivatives
+    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+    {
+      // Get values from coefficients array
+      new_coeff0_0 = coefficients0[dof][0];
+      new_coeff0_1 = coefficients0[dof][1];
+      new_coeff0_2 = coefficients0[dof][2];
+      new_coeff0_3 = coefficients0[dof][3];
+      new_coeff0_4 = coefficients0[dof][4];
+      new_coeff0_5 = coefficients0[dof][5];
+    
+      // Loop derivative order
+      for (unsigned int j = 0; j < n; j++)
+      {
+        // Update old coefficients
+        coeff0_0 = new_coeff0_0;
+        coeff0_1 = new_coeff0_1;
+        coeff0_2 = new_coeff0_2;
+        coeff0_3 = new_coeff0_3;
+        coeff0_4 = new_coeff0_4;
+        coeff0_5 = new_coeff0_5;
+    
+        if(combinations[deriv_num][j] == 0)
+        {
+          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
+          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
+          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
+          new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
+          new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
+          new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
+        }
+        if(combinations[deriv_num][j] == 1)
+        {
+          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
+          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
+          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
+          new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
+          new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
+          new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
+        }
+    
+      }
+      // Compute derivatives on reference element as dot product of coefficients and basisvalues
+      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
+    }
+    
+    // Transform derivatives back to physical element
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      for (unsigned int col = 0; col < num_derivatives; col++)
+      {
+        values[row] += transform[row][col]*derivatives[col];
+      }
+    }
+    // Delete pointer to array of derivatives on FIAT element
+    delete [] derivatives;
+    
+    // Delete pointer to array of combinations of derivatives and transform
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      delete [] combinations[row];
+      delete [] transform[row];
+    }
+    
+    delete [] combinations;
+    delete [] transform;
+}
+
+/// Evaluate order n derivatives of all basis functions at given point in cell
+void projection_0_finite_element_1_1::evaluate_basis_derivatives_all(unsigned int n,
+                                                   double* values,
+                                                   const double* coordinates,
+                                                   const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
+}
+
+/// Evaluate linear functional for dof i on the function f
+double projection_0_finite_element_1_1::evaluate_dof(unsigned int i,
+                                   const ufc::function& f,
+                                   const ufc::cell& c) const
+{
+    // The reference points, direction and weights:
+    static const double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}};
+    static const double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
+    static const double D[6][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}, {{1}}, {{1}}};
+    
+    const double * const * x = c.coordinates;
+    double result = 0.0;
+    // Iterate over the points:
+    // Evaluate basis functions for affine mapping
+    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    
+    // Compute affine mapping y = F(X)
+    double y[2];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
+    
+    // Evaluate function at physical points
+    double values[1];
+    f.evaluate(values, y, c);
+    
+    // Map function values using appropriate mapping
+    // Affine map: Do nothing
+    
+    // Note that we do not map the weights (yet).
+    
+    // Take directional components
+    for(int k = 0; k < 1; k++)
+      result += values[k]*D[i][0][k];
+    // Multiply by weights
+    result *= W[i][0];
+    
+    return result;
+}
+
+/// Evaluate linear functionals for all dofs on the function f
+void projection_0_finite_element_1_1::evaluate_dofs(double* values,
+                                  const ufc::function& f,
+                                  const ufc::cell& c) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Interpolate vertex values from dof values
+void projection_0_finite_element_1_1::interpolate_vertex_values(double* vertex_values,
+                                              const double* dof_values,
+                                              const ufc::cell& c) const
+{
+    // Evaluate at vertices and use affine mapping
+    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)
+unsigned int projection_0_finite_element_1_1::num_sub_elements() const
+{
+    return 1;
+}
+
+/// Create a new finite element for sub element i (for a mixed element)
+ufc::finite_element* projection_0_finite_element_1_1::create_sub_element(unsigned int i) const
+{
+    return new projection_0_finite_element_1_1();
+}
+
+
+/// Constructor
+projection_0_finite_element_1::projection_0_finite_element_1() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+projection_0_finite_element_1::~projection_0_finite_element_1()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* projection_0_finite_element_1::signature() const
+{
+    return "VectorElement('Lagrange', Cell('triangle', 1, Space(2)), 2, 2)";
+}
+
+/// Return the cell shape
+ufc::shape projection_0_finite_element_1::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int projection_0_finite_element_1::space_dimension() const
+{
+    return 12;
+}
+
+/// Return the rank of the value space
+unsigned int projection_0_finite_element_1::value_rank() const
+{
+    return 1;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int projection_0_finite_element_1::value_dimension(unsigned int i) const
+{
+    return 2;
+}
+
+/// Evaluate basis function i at given point in cell
+void projection_0_finite_element_1::evaluate_basis(unsigned int i,
+                                   double* values,
+                                   const double* coordinates,
+                                   const ufc::cell& c) const
+{
+    // Extract vertex coordinates
+    const double * const * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Reset values
+    values[0] = 0;
+    values[1] = 0;
+    
+    if (0 <= i && i <= 5)
+    {
+      // Map degree of freedom to element degree of freedom
+      const unsigned int dof = i;
+    
+      // Generate scalings
+      const double scalings_y_0 = 1;
+      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+      const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+      // Compute psitilde_a
+      const double psitilde_a_0 = 1;
+      const double psitilde_a_1 = x;
+      const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+      // Compute psitilde_bs
+      const double psitilde_bs_0_0 = 1;
+      const double psitilde_bs_0_1 = 1.5*y + 0.5;
+      const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+      const double psitilde_bs_1_0 = 1;
+      const double psitilde_bs_1_1 = 2.5*y + 1.5;
+      const double psitilde_bs_2_0 = 1;
+    
+      // Compute basisvalues
+      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+      const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+      const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+      const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+      // Table(s) of coefficients
+      static const double coefficients0[6][6] =   \
+      {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+      {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+      {0, 0, 0.2, 0, 0, 0.163299316185545},
+      {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+      {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+      {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+      // Extract relevant coefficients
+      const double coeff0_0 =   coefficients0[dof][0];
+      const double coeff0_1 =   coefficients0[dof][1];
+      const double coeff0_2 =   coefficients0[dof][2];
+      const double coeff0_3 =   coefficients0[dof][3];
+      const double coeff0_4 =   coefficients0[dof][4];
+      const double coeff0_5 =   coefficients0[dof][5];
+    
+      // Compute value(s)
+      values[0] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
+    }
+    
+    if (6 <= i && i <= 11)
+    {
+      // Map degree of freedom to element degree of freedom
+      const unsigned int dof = i - 6;
+    
+      // Generate scalings
+      const double scalings_y_0 = 1;
+      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+      const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+      // Compute psitilde_a
+      const double psitilde_a_0 = 1;
+      const double psitilde_a_1 = x;
+      const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+      // Compute psitilde_bs
+      const double psitilde_bs_0_0 = 1;
+      const double psitilde_bs_0_1 = 1.5*y + 0.5;
+      const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+      const double psitilde_bs_1_0 = 1;
+      const double psitilde_bs_1_1 = 2.5*y + 1.5;
+      const double psitilde_bs_2_0 = 1;
+    
+      // Compute basisvalues
+      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+      const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+      const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+      const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+      // Table(s) of coefficients
+      static const double coefficients0[6][6] =   \
+      {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+      {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+      {0, 0, 0.2, 0, 0, 0.163299316185545},
+      {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+      {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+      {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+      // Extract relevant coefficients
+      const double coeff0_0 =   coefficients0[dof][0];
+      const double coeff0_1 =   coefficients0[dof][1];
+      const double coeff0_2 =   coefficients0[dof][2];
+      const double coeff0_3 =   coefficients0[dof][3];
+      const double coeff0_4 =   coefficients0[dof][4];
+      const double coeff0_5 =   coefficients0[dof][5];
+    
+      // Compute value(s)
+      values[1] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
+    }
+    
+}
+
+/// Evaluate all basis functions at given point in cell
+void projection_0_finite_element_1::evaluate_basis_all(double* values,
+                                       const double* coordinates,
+                                       const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
+}
+
+/// Evaluate order n derivatives of basis function i at given point in cell
+void projection_0_finite_element_1::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 * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 2;
+    
+    
+    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
+    unsigned int **combinations = new unsigned int *[num_derivatives];
+    
+    for (unsigned int j = 0; j < num_derivatives; j++)
+    {
+      combinations[j] = new unsigned int [n];
+      for (unsigned int k = 0; k < n; k++)
+        combinations[j][k] = 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] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
+    
+    // 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
+    for (unsigned int j = 0; j < 2*num_derivatives; j++)
+      values[j] = 0;
+    
+    if (0 <= i && i <= 5)
+    {
+      // Map degree of freedom to element degree of freedom
+      const unsigned int dof = i;
+    
+      // Generate scalings
+      const double scalings_y_0 = 1;
+      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+      const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+      // Compute psitilde_a
+      const double psitilde_a_0 = 1;
+      const double psitilde_a_1 = x;
+      const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+      // Compute psitilde_bs
+      const double psitilde_bs_0_0 = 1;
+      const double psitilde_bs_0_1 = 1.5*y + 0.5;
+      const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+      const double psitilde_bs_1_0 = 1;
+      const double psitilde_bs_1_1 = 2.5*y + 1.5;
+      const double psitilde_bs_2_0 = 1;
+    
+      // Compute basisvalues
+      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+      const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+      const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+      const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+      // Table(s) of coefficients
+      static const double coefficients0[6][6] =   \
+      {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+      {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+      {0, 0, 0.2, 0, 0, 0.163299316185545},
+      {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+      {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+      {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+      // Interesting (new) part
+      // Tables of derivatives of the polynomial base (transpose)
+      static const double dmats0[6][6] =   \
+      {{0, 0, 0, 0, 0, 0},
+      {4.89897948556636, 0, 0, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0},
+      {0, 9.48683298050514, 0, 0, 0, 0},
+      {4, 0, 7.07106781186548, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0}};
+    
+      static const double dmats1[6][6] =   \
+      {{0, 0, 0, 0, 0, 0},
+      {2.44948974278318, 0, 0, 0, 0, 0},
+      {4.24264068711928, 0, 0, 0, 0, 0},
+      {2.58198889747161, 4.74341649025257, -0.912870929175277, 0, 0, 0},
+      {2, 6.12372435695795, 3.53553390593274, 0, 0, 0},
+      {-2.3094010767585, 0, 8.16496580927726, 0, 0, 0}};
+    
+      // Compute reference derivatives
+      // Declare pointer to array of derivatives on FIAT element
+      double *derivatives = new double [num_derivatives];
+    
+      // Declare coefficients
+      double coeff0_0 = 0;
+      double coeff0_1 = 0;
+      double coeff0_2 = 0;
+      double coeff0_3 = 0;
+      double coeff0_4 = 0;
+      double coeff0_5 = 0;
+    
+      // Declare new coefficients
+      double new_coeff0_0 = 0;
+      double new_coeff0_1 = 0;
+      double new_coeff0_2 = 0;
+      double new_coeff0_3 = 0;
+      double new_coeff0_4 = 0;
+      double new_coeff0_5 = 0;
+    
+      // Loop possible derivatives
+      for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+      {
+        // Get values from coefficients array
+        new_coeff0_0 = coefficients0[dof][0];
+        new_coeff0_1 = coefficients0[dof][1];
+        new_coeff0_2 = coefficients0[dof][2];
+        new_coeff0_3 = coefficients0[dof][3];
+        new_coeff0_4 = coefficients0[dof][4];
+        new_coeff0_5 = coefficients0[dof][5];
+    
+        // Loop derivative order
+        for (unsigned int j = 0; j < n; j++)
+        {
+          // Update old coefficients
+          coeff0_0 = new_coeff0_0;
+          coeff0_1 = new_coeff0_1;
+          coeff0_2 = new_coeff0_2;
+          coeff0_3 = new_coeff0_3;
+          coeff0_4 = new_coeff0_4;
+          coeff0_5 = new_coeff0_5;
+    
+          if(combinations[deriv_num][j] == 0)
+          {
+            new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
+            new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
+            new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
+            new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
+            new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
+            new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
+          }
+          if(combinations[deriv_num][j] == 1)
+          {
+            new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
+            new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
+            new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
+            new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
+            new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
+            new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
+          }
+    
+        }
+        // Compute derivatives on reference element as dot product of coefficients and basisvalues
+        derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
+      }
+    
+      // Transform derivatives back to physical element
+      for (unsigned int row = 0; row < num_derivatives; row++)
+      {
+        for (unsigned int col = 0; col < num_derivatives; col++)
+        {
+          values[row] += transform[row][col]*derivatives[col];
+        }
+      }
+      // Delete pointer to array of derivatives on FIAT element
+      delete [] derivatives;
+    
+      // Delete pointer to array of combinations of derivatives and transform
+      for (unsigned int row = 0; row < num_derivatives; row++)
+      {
+        delete [] combinations[row];
+        delete [] transform[row];
+      }
+    
+      delete [] combinations;
+      delete [] transform;
+    }
+    
+    if (6 <= i && i <= 11)
+    {
+      // Map degree of freedom to element degree of freedom
+      const unsigned int dof = i - 6;
+    
+      // Generate scalings
+      const double scalings_y_0 = 1;
+      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+      const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+      // Compute psitilde_a
+      const double psitilde_a_0 = 1;
+      const double psitilde_a_1 = x;
+      const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+      // Compute psitilde_bs
+      const double psitilde_bs_0_0 = 1;
+      const double psitilde_bs_0_1 = 1.5*y + 0.5;
+      const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+      const double psitilde_bs_1_0 = 1;
+      const double psitilde_bs_1_1 = 2.5*y + 1.5;
+      const double psitilde_bs_2_0 = 1;
+    
+      // Compute basisvalues
+      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+      const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+      const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+      const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+      // Table(s) of coefficients
+      static const double coefficients0[6][6] =   \
+      {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+      {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+      {0, 0, 0.2, 0, 0, 0.163299316185545},
+      {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+      {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+      {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+      // Interesting (new) part
+      // Tables of derivatives of the polynomial base (transpose)
+      static const double dmats0[6][6] =   \
+      {{0, 0, 0, 0, 0, 0},
+      {4.89897948556636, 0, 0, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0},
+      {0, 9.48683298050514, 0, 0, 0, 0},
+      {4, 0, 7.07106781186548, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0}};
+    
+      static const double dmats1[6][6] =   \
+      {{0, 0, 0, 0, 0, 0},
+      {2.44948974278318, 0, 0, 0, 0, 0},
+      {4.24264068711928, 0, 0, 0, 0, 0},
+      {2.58198889747161, 4.74341649025257, -0.912870929175277, 0, 0, 0},
+      {2, 6.12372435695795, 3.53553390593274, 0, 0, 0},
+      {-2.3094010767585, 0, 8.16496580927726, 0, 0, 0}};
+    
+      // Compute reference derivatives
+      // Declare pointer to array of derivatives on FIAT element
+      double *derivatives = new double [num_derivatives];
+    
+      // Declare coefficients
+      double coeff0_0 = 0;
+      double coeff0_1 = 0;
+      double coeff0_2 = 0;
+      double coeff0_3 = 0;
+      double coeff0_4 = 0;
+      double coeff0_5 = 0;
+    
+      // Declare new coefficients
+      double new_coeff0_0 = 0;
+      double new_coeff0_1 = 0;
+      double new_coeff0_2 = 0;
+      double new_coeff0_3 = 0;
+      double new_coeff0_4 = 0;
+      double new_coeff0_5 = 0;
+    
+      // Loop possible derivatives
+      for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+      {
+        // Get values from coefficients array
+        new_coeff0_0 = coefficients0[dof][0];
+        new_coeff0_1 = coefficients0[dof][1];
+        new_coeff0_2 = coefficients0[dof][2];
+        new_coeff0_3 = coefficients0[dof][3];
+        new_coeff0_4 = coefficients0[dof][4];
+        new_coeff0_5 = coefficients0[dof][5];
+    
+        // Loop derivative order
+        for (unsigned int j = 0; j < n; j++)
+        {
+          // Update old coefficients
+          coeff0_0 = new_coeff0_0;
+          coeff0_1 = new_coeff0_1;
+          coeff0_2 = new_coeff0_2;
+          coeff0_3 = new_coeff0_3;
+          coeff0_4 = new_coeff0_4;
+          coeff0_5 = new_coeff0_5;
+    
+          if(combinations[deriv_num][j] == 0)
+          {
+            new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
+            new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
+            new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
+            new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
+            new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
+            new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
+          }
+          if(combinations[deriv_num][j] == 1)
+          {
+            new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
+            new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
+            new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
+            new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
+            new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
+            new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
+          }
+    
+        }
+        // Compute derivatives on reference element as dot product of coefficients and basisvalues
+        derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
+      }
+    
+      // Transform derivatives back to physical element
+      for (unsigned int row = 0; row < num_derivatives; row++)
+      {
+        for (unsigned int col = 0; col < num_derivatives; col++)
+        {
+          values[num_derivatives + row] += transform[row][col]*derivatives[col];
+        }
+      }
+      // Delete pointer to array of derivatives on FIAT element
+      delete [] derivatives;
+    
+      // Delete pointer to array of combinations of derivatives and transform
+      for (unsigned int row = 0; row < num_derivatives; row++)
+      {
+        delete [] combinations[row];
+        delete [] transform[row];
+      }
+    
+      delete [] combinations;
+      delete [] transform;
+    }
+    
+}
+
+/// Evaluate order n derivatives of all basis functions at given point in cell
+void projection_0_finite_element_1::evaluate_basis_derivatives_all(unsigned int n,
+                                                   double* values,
+                                                   const double* coordinates,
+                                                   const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
+}
+
+/// Evaluate linear functional for dof i on the function f
+double projection_0_finite_element_1::evaluate_dof(unsigned int i,
+                                   const ufc::function& f,
+                                   const ufc::cell& c) const
+{
+    // The reference points, direction and weights:
+    static const double X[12][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}, {{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}};
+    static const double W[12][1] = {{1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}};
+    static const double D[12][1][2] = {{{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{0, 1}}, {{0, 1}}, {{0, 1}}, {{0, 1}}, {{0, 1}}, {{0, 1}}};
+    
+    const double * const * x = c.coordinates;
+    double result = 0.0;
+    // Iterate over the points:
+    // Evaluate basis functions for affine mapping
+    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    
+    // Compute affine mapping y = F(X)
+    double y[2];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
+    
+    // Evaluate function at physical points
+    double values[2];
+    f.evaluate(values, y, c);
+    
+    // Map function values using appropriate mapping
+    // Affine map: Do nothing
+    
+    // Note that we do not map the weights (yet).
+    
+    // Take directional components
+    for(int k = 0; k < 2; k++)
+      result += values[k]*D[i][0][k];
+    // Multiply by weights
+    result *= W[i][0];
+    
+    return result;
+}
+
+/// Evaluate linear functionals for all dofs on the function f
+void projection_0_finite_element_1::evaluate_dofs(double* values,
+                                  const ufc::function& f,
+                                  const ufc::cell& c) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Interpolate vertex values from dof values
+void projection_0_finite_element_1::interpolate_vertex_values(double* vertex_values,
+                                              const double* dof_values,
+                                              const ufc::cell& c) const
+{
+    // Evaluate at vertices and use affine mapping
+    vertex_values[0] = dof_values[0];
+    vertex_values[2] = dof_values[1];
+    vertex_values[4] = dof_values[2];
+    // Evaluate at vertices and use affine mapping
+    vertex_values[1] = dof_values[6];
+    vertex_values[3] = dof_values[7];
+    vertex_values[5] = dof_values[8];
+}
+
+/// Return the number of sub elements (for a mixed element)
+unsigned int projection_0_finite_element_1::num_sub_elements() const
+{
+    return 2;
+}
+
+/// Create a new finite element for sub element i (for a mixed element)
+ufc::finite_element* projection_0_finite_element_1::create_sub_element(unsigned int i) const
+{
+    switch ( i )
+    {
+    case 0:
+      return new projection_0_finite_element_1_0();
+      break;
+    case 1:
+      return new projection_0_finite_element_1_1();
+      break;
+    }
+    return 0;
+}
+
+/// Constructor
+projection_0_dof_map_0_0::projection_0_dof_map_0_0() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+projection_0_dof_map_0_0::~projection_0_dof_map_0_0()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* projection_0_dof_map_0_0::signature() const
+{
+    return "FFC dof map for FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool projection_0_dof_map_0_0::needs_mesh_entities(unsigned int d) const
+{
+    switch ( d )
+    {
+    case 0:
+      return true;
+      break;
+    case 1:
+      return true;
+      break;
+    case 2:
+      return false;
+      break;
+    }
+    return false;
+}
+
+/// Initialize dof map for mesh (return true iff init_cell() is needed)
+bool projection_0_dof_map_0_0::init_mesh(const ufc::mesh& m)
+{
+    __global_dimension = m.num_entities[0] + m.num_entities[1];
+    return false;
+}
+
+/// Initialize dof map for given cell
+void projection_0_dof_map_0_0::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void projection_0_dof_map_0_0::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int projection_0_dof_map_0_0::global_dimension() const
+{
+    return __global_dimension;
+}
+
+/// Return the dimension of the local finite element function space for a cell
+unsigned int projection_0_dof_map_0_0::local_dimension(const ufc::cell& c) const
+{
+    return 6;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int projection_0_dof_map_0_0::max_local_dimension() const
+{
+    return 6;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int projection_0_dof_map_0_0::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int projection_0_dof_map_0_0::num_facet_dofs() const
+{
+    return 3;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int projection_0_dof_map_0_0::num_entity_dofs(unsigned int d) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the local-to-global mapping of dofs on a cell
+void projection_0_dof_map_0_0::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];
+    unsigned int offset = m.num_entities[0];
+    dofs[3] = offset + c.entity_indices[1][0];
+    dofs[4] = offset + c.entity_indices[1][1];
+    dofs[5] = offset + c.entity_indices[1][2];
+}
+
+/// Tabulate the local-to-local mapping from facet dofs to cell dofs
+void projection_0_dof_map_0_0::tabulate_facet_dofs(unsigned int* dofs,
+                                        unsigned int facet) const
+{
+    switch ( facet )
+    {
+    case 0:
+      dofs[0] = 1;
+      dofs[1] = 2;
+      dofs[2] = 3;
+      break;
+    case 1:
+      dofs[0] = 0;
+      dofs[1] = 2;
+      dofs[2] = 4;
+      break;
+    case 2:
+      dofs[0] = 0;
+      dofs[1] = 1;
+      dofs[2] = 5;
+      break;
+    }
+}
+
+/// Tabulate the local-to-local mapping of dofs on entity (d, i)
+void projection_0_dof_map_0_0::tabulate_entity_dofs(unsigned int* dofs,
+                                  unsigned int d, unsigned int i) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the coordinates of all dofs on a cell
+void projection_0_dof_map_0_0::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];
+    coordinates[3][0] = 0.5*x[1][0] + 0.5*x[2][0];
+    coordinates[3][1] = 0.5*x[1][1] + 0.5*x[2][1];
+    coordinates[4][0] = 0.5*x[0][0] + 0.5*x[2][0];
+    coordinates[4][1] = 0.5*x[0][1] + 0.5*x[2][1];
+    coordinates[5][0] = 0.5*x[0][0] + 0.5*x[1][0];
+    coordinates[5][1] = 0.5*x[0][1] + 0.5*x[1][1];
+}
+
+/// Return the number of sub dof maps (for a mixed element)
+unsigned int projection_0_dof_map_0_0::num_sub_dof_maps() const
+{
+    return 1;
+}
+
+/// Create a new dof_map for sub dof map i (for a mixed element)
+ufc::dof_map* projection_0_dof_map_0_0::create_sub_dof_map(unsigned int i) const
+{
+    return new projection_0_dof_map_0_0();
+}
+
+
+/// Constructor
+projection_0_dof_map_0_1::projection_0_dof_map_0_1() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+projection_0_dof_map_0_1::~projection_0_dof_map_0_1()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* projection_0_dof_map_0_1::signature() const
+{
+    return "FFC dof map for FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool projection_0_dof_map_0_1::needs_mesh_entities(unsigned int d) const
+{
+    switch ( d )
+    {
+    case 0:
+      return true;
+      break;
+    case 1:
+      return true;
+      break;
+    case 2:
+      return false;
+      break;
+    }
+    return false;
+}
+
+/// Initialize dof map for mesh (return true iff init_cell() is needed)
+bool projection_0_dof_map_0_1::init_mesh(const ufc::mesh& m)
+{
+    __global_dimension = m.num_entities[0] + m.num_entities[1];
+    return false;
+}
+
+/// Initialize dof map for given cell
+void projection_0_dof_map_0_1::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void projection_0_dof_map_0_1::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int projection_0_dof_map_0_1::global_dimension() const
+{
+    return __global_dimension;
+}
+
+/// Return the dimension of the local finite element function space for a cell
+unsigned int projection_0_dof_map_0_1::local_dimension(const ufc::cell& c) const
+{
+    return 6;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int projection_0_dof_map_0_1::max_local_dimension() const
+{
+    return 6;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int projection_0_dof_map_0_1::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int projection_0_dof_map_0_1::num_facet_dofs() const
+{
+    return 3;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int projection_0_dof_map_0_1::num_entity_dofs(unsigned int d) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the local-to-global mapping of dofs on a cell
+void projection_0_dof_map_0_1::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];
+    unsigned int offset = m.num_entities[0];
+    dofs[3] = offset + c.entity_indices[1][0];
+    dofs[4] = offset + c.entity_indices[1][1];
+    dofs[5] = offset + c.entity_indices[1][2];
+}
+
+/// Tabulate the local-to-local mapping from facet dofs to cell dofs
+void projection_0_dof_map_0_1::tabulate_facet_dofs(unsigned int* dofs,
+                                        unsigned int facet) const
+{
+    switch ( facet )
+    {
+    case 0:
+      dofs[0] = 1;
+      dofs[1] = 2;
+      dofs[2] = 3;
+      break;
+    case 1:
+      dofs[0] = 0;
+      dofs[1] = 2;
+      dofs[2] = 4;
+      break;
+    case 2:
+      dofs[0] = 0;
+      dofs[1] = 1;
+      dofs[2] = 5;
+      break;
+    }
+}
+
+/// Tabulate the local-to-local mapping of dofs on entity (d, i)
+void projection_0_dof_map_0_1::tabulate_entity_dofs(unsigned int* dofs,
+                                  unsigned int d, unsigned int i) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the coordinates of all dofs on a cell
+void projection_0_dof_map_0_1::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];
+    coordinates[3][0] = 0.5*x[1][0] + 0.5*x[2][0];
+    coordinates[3][1] = 0.5*x[1][1] + 0.5*x[2][1];
+    coordinates[4][0] = 0.5*x[0][0] + 0.5*x[2][0];
+    coordinates[4][1] = 0.5*x[0][1] + 0.5*x[2][1];
+    coordinates[5][0] = 0.5*x[0][0] + 0.5*x[1][0];
+    coordinates[5][1] = 0.5*x[0][1] + 0.5*x[1][1];
+}
+
+/// Return the number of sub dof maps (for a mixed element)
+unsigned int projection_0_dof_map_0_1::num_sub_dof_maps() const
+{
+    return 1;
+}
+
+/// Create a new dof_map for sub dof map i (for a mixed element)
+ufc::dof_map* projection_0_dof_map_0_1::create_sub_dof_map(unsigned int i) const
+{
+    return new projection_0_dof_map_0_1();
+}
+
+
+/// Constructor
+projection_0_dof_map_0::projection_0_dof_map_0() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+projection_0_dof_map_0::~projection_0_dof_map_0()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* projection_0_dof_map_0::signature() const
+{
+    return "FFC dof map for VectorElement('Lagrange', Cell('triangle', 1, Space(2)), 2, 2)";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool projection_0_dof_map_0::needs_mesh_entities(unsigned int d) const
+{
+    switch ( d )
+    {
+    case 0:
+      return true;
+      break;
+    case 1:
+      return true;
+      break;
+    case 2:
+      return false;
+      break;
+    }
+    return false;
+}
+
+/// Initialize dof map for mesh (return true iff init_cell() is needed)
+bool projection_0_dof_map_0::init_mesh(const ufc::mesh& m)
+{
+    __global_dimension = 2*m.num_entities[0] + 2*m.num_entities[1];
+    return false;
+}
+
+/// Initialize dof map for given cell
+void projection_0_dof_map_0::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void projection_0_dof_map_0::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int projection_0_dof_map_0::global_dimension() const
+{
+    return __global_dimension;
+}
+
+/// Return the dimension of the local finite element function space for a cell
+unsigned int projection_0_dof_map_0::local_dimension(const ufc::cell& c) const
+{
+    return 12;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int projection_0_dof_map_0::max_local_dimension() const
+{
+    return 12;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int projection_0_dof_map_0::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int projection_0_dof_map_0::num_facet_dofs() const
+{
+    return 6;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int projection_0_dof_map_0::num_entity_dofs(unsigned int d) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the local-to-global mapping of dofs on a cell
+void projection_0_dof_map_0::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];
+    unsigned int offset = m.num_entities[0];
+    dofs[3] = offset + c.entity_indices[1][0];
+    dofs[4] = offset + c.entity_indices[1][1];
+    dofs[5] = offset + c.entity_indices[1][2];
+    offset = offset + m.num_entities[1];
+    dofs[6] = offset + c.entity_indices[0][0];
+    dofs[7] = offset + c.entity_indices[0][1];
+    dofs[8] = offset + c.entity_indices[0][2];
+    offset = offset + m.num_entities[0];
+    dofs[9] = offset + c.entity_indices[1][0];
+    dofs[10] = offset + c.entity_indices[1][1];
+    dofs[11] = offset + c.entity_indices[1][2];
+}
+
+/// Tabulate the local-to-local mapping from facet dofs to cell dofs
+void projection_0_dof_map_0::tabulate_facet_dofs(unsigned int* dofs,
+                                        unsigned int facet) const
+{
+    switch ( facet )
+    {
+    case 0:
+      dofs[0] = 1;
+      dofs[1] = 2;
+      dofs[2] = 3;
+      dofs[3] = 7;
+      dofs[4] = 8;
+      dofs[5] = 9;
+      break;
+    case 1:
+      dofs[0] = 0;
+      dofs[1] = 2;
+      dofs[2] = 4;
+      dofs[3] = 6;
+      dofs[4] = 8;
+      dofs[5] = 10;
+      break;
+    case 2:
+      dofs[0] = 0;
+      dofs[1] = 1;
+      dofs[2] = 5;
+      dofs[3] = 6;
+      dofs[4] = 7;
+      dofs[5] = 11;
+      break;
+    }
+}
+
+/// Tabulate the local-to-local mapping of dofs on entity (d, i)
+void projection_0_dof_map_0::tabulate_entity_dofs(unsigned int* dofs,
+                                  unsigned int d, unsigned int i) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the coordinates of all dofs on a cell
+void projection_0_dof_map_0::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];
+    coordinates[3][0] = 0.5*x[1][0] + 0.5*x[2][0];
+    coordinates[3][1] = 0.5*x[1][1] + 0.5*x[2][1];
+    coordinates[4][0] = 0.5*x[0][0] + 0.5*x[2][0];
+    coordinates[4][1] = 0.5*x[0][1] + 0.5*x[2][1];
+    coordinates[5][0] = 0.5*x[0][0] + 0.5*x[1][0];
+    coordinates[5][1] = 0.5*x[0][1] + 0.5*x[1][1];
+    coordinates[6][0] = x[0][0];
+    coordinates[6][1] = x[0][1];
+    coordinates[7][0] = x[1][0];
+    coordinates[7][1] = x[1][1];
+    coordinates[8][0] = x[2][0];
+    coordinates[8][1] = x[2][1];
+    coordinates[9][0] = 0.5*x[1][0] + 0.5*x[2][0];
+    coordinates[9][1] = 0.5*x[1][1] + 0.5*x[2][1];
+    coordinates[10][0] = 0.5*x[0][0] + 0.5*x[2][0];
+    coordinates[10][1] = 0.5*x[0][1] + 0.5*x[2][1];
+    coordinates[11][0] = 0.5*x[0][0] + 0.5*x[1][0];
+    coordinates[11][1] = 0.5*x[0][1] + 0.5*x[1][1];
+}
+
+/// Return the number of sub dof maps (for a mixed element)
+unsigned int projection_0_dof_map_0::num_sub_dof_maps() const
+{
+    return 2;
+}
+
+/// Create a new dof_map for sub dof map i (for a mixed element)
+ufc::dof_map* projection_0_dof_map_0::create_sub_dof_map(unsigned int i) const
+{
+    switch ( i )
+    {
+    case 0:
+      return new projection_0_dof_map_0_0();
+      break;
+    case 1:
+      return new projection_0_dof_map_0_1();
+      break;
+    }
+    return 0;
+}
+
+
+/// Constructor
+projection_0_dof_map_1_0::projection_0_dof_map_1_0() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+projection_0_dof_map_1_0::~projection_0_dof_map_1_0()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* projection_0_dof_map_1_0::signature() const
+{
+    return "FFC dof map for FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool projection_0_dof_map_1_0::needs_mesh_entities(unsigned int d) const
+{
+    switch ( d )
+    {
+    case 0:
+      return true;
+      break;
+    case 1:
+      return true;
+      break;
+    case 2:
+      return false;
+      break;
+    }
+    return false;
+}
+
+/// Initialize dof map for mesh (return true iff init_cell() is needed)
+bool projection_0_dof_map_1_0::init_mesh(const ufc::mesh& m)
+{
+    __global_dimension = m.num_entities[0] + m.num_entities[1];
+    return false;
+}
+
+/// Initialize dof map for given cell
+void projection_0_dof_map_1_0::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void projection_0_dof_map_1_0::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int projection_0_dof_map_1_0::global_dimension() const
+{
+    return __global_dimension;
+}
+
+/// Return the dimension of the local finite element function space for a cell
+unsigned int projection_0_dof_map_1_0::local_dimension(const ufc::cell& c) const
+{
+    return 6;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int projection_0_dof_map_1_0::max_local_dimension() const
+{
+    return 6;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int projection_0_dof_map_1_0::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int projection_0_dof_map_1_0::num_facet_dofs() const
+{
+    return 3;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int projection_0_dof_map_1_0::num_entity_dofs(unsigned int d) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the local-to-global mapping of dofs on a cell
+void projection_0_dof_map_1_0::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];
+    unsigned int offset = m.num_entities[0];
+    dofs[3] = offset + c.entity_indices[1][0];
+    dofs[4] = offset + c.entity_indices[1][1];
+    dofs[5] = offset + c.entity_indices[1][2];
+}
+
+/// Tabulate the local-to-local mapping from facet dofs to cell dofs
+void projection_0_dof_map_1_0::tabulate_facet_dofs(unsigned int* dofs,
+                                        unsigned int facet) const
+{
+    switch ( facet )
+    {
+    case 0:
+      dofs[0] = 1;
+      dofs[1] = 2;
+      dofs[2] = 3;
+      break;
+    case 1:
+      dofs[0] = 0;
+      dofs[1] = 2;
+      dofs[2] = 4;
+      break;
+    case 2:
+      dofs[0] = 0;
+      dofs[1] = 1;
+      dofs[2] = 5;
+      break;
+    }
+}
+
+/// Tabulate the local-to-local mapping of dofs on entity (d, i)
+void projection_0_dof_map_1_0::tabulate_entity_dofs(unsigned int* dofs,
+                                  unsigned int d, unsigned int i) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the coordinates of all dofs on a cell
+void projection_0_dof_map_1_0::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];
+    coordinates[3][0] = 0.5*x[1][0] + 0.5*x[2][0];
+    coordinates[3][1] = 0.5*x[1][1] + 0.5*x[2][1];
+    coordinates[4][0] = 0.5*x[0][0] + 0.5*x[2][0];
+    coordinates[4][1] = 0.5*x[0][1] + 0.5*x[2][1];
+    coordinates[5][0] = 0.5*x[0][0] + 0.5*x[1][0];
+    coordinates[5][1] = 0.5*x[0][1] + 0.5*x[1][1];
+}
+
+/// Return the number of sub dof maps (for a mixed element)
+unsigned int projection_0_dof_map_1_0::num_sub_dof_maps() const
+{
+    return 1;
+}
+
+/// Create a new dof_map for sub dof map i (for a mixed element)
+ufc::dof_map* projection_0_dof_map_1_0::create_sub_dof_map(unsigned int i) const
+{
+    return new projection_0_dof_map_1_0();
+}
+
+
+/// Constructor
+projection_0_dof_map_1_1::projection_0_dof_map_1_1() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+projection_0_dof_map_1_1::~projection_0_dof_map_1_1()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* projection_0_dof_map_1_1::signature() const
+{
+    return "FFC dof map for FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool projection_0_dof_map_1_1::needs_mesh_entities(unsigned int d) const
+{
+    switch ( d )
+    {
+    case 0:
+      return true;
+      break;
+    case 1:
+      return true;
+      break;
+    case 2:
+      return false;
+      break;
+    }
+    return false;
+}
+
+/// Initialize dof map for mesh (return true iff init_cell() is needed)
+bool projection_0_dof_map_1_1::init_mesh(const ufc::mesh& m)
+{
+    __global_dimension = m.num_entities[0] + m.num_entities[1];
+    return false;
+}
+
+/// Initialize dof map for given cell
+void projection_0_dof_map_1_1::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void projection_0_dof_map_1_1::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int projection_0_dof_map_1_1::global_dimension() const
+{
+    return __global_dimension;
+}
+
+/// Return the dimension of the local finite element function space for a cell
+unsigned int projection_0_dof_map_1_1::local_dimension(const ufc::cell& c) const
+{
+    return 6;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int projection_0_dof_map_1_1::max_local_dimension() const
+{
+    return 6;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int projection_0_dof_map_1_1::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int projection_0_dof_map_1_1::num_facet_dofs() const
+{
+    return 3;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int projection_0_dof_map_1_1::num_entity_dofs(unsigned int d) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the local-to-global mapping of dofs on a cell
+void projection_0_dof_map_1_1::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];
+    unsigned int offset = m.num_entities[0];
+    dofs[3] = offset + c.entity_indices[1][0];
+    dofs[4] = offset + c.entity_indices[1][1];
+    dofs[5] = offset + c.entity_indices[1][2];
+}
+
+/// Tabulate the local-to-local mapping from facet dofs to cell dofs
+void projection_0_dof_map_1_1::tabulate_facet_dofs(unsigned int* dofs,
+                                        unsigned int facet) const
+{
+    switch ( facet )
+    {
+    case 0:
+      dofs[0] = 1;
+      dofs[1] = 2;
+      dofs[2] = 3;
+      break;
+    case 1:
+      dofs[0] = 0;
+      dofs[1] = 2;
+      dofs[2] = 4;
+      break;
+    case 2:
+      dofs[0] = 0;
+      dofs[1] = 1;
+      dofs[2] = 5;
+      break;
+    }
+}
+
+/// Tabulate the local-to-local mapping of dofs on entity (d, i)
+void projection_0_dof_map_1_1::tabulate_entity_dofs(unsigned int* dofs,
+                                  unsigned int d, unsigned int i) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the coordinates of all dofs on a cell
+void projection_0_dof_map_1_1::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];
+    coordinates[3][0] = 0.5*x[1][0] + 0.5*x[2][0];
+    coordinates[3][1] = 0.5*x[1][1] + 0.5*x[2][1];
+    coordinates[4][0] = 0.5*x[0][0] + 0.5*x[2][0];
+    coordinates[4][1] = 0.5*x[0][1] + 0.5*x[2][1];
+    coordinates[5][0] = 0.5*x[0][0] + 0.5*x[1][0];
+    coordinates[5][1] = 0.5*x[0][1] + 0.5*x[1][1];
+}
+
+/// Return the number of sub dof maps (for a mixed element)
+unsigned int projection_0_dof_map_1_1::num_sub_dof_maps() const
+{
+    return 1;
+}
+
+/// Create a new dof_map for sub dof map i (for a mixed element)
+ufc::dof_map* projection_0_dof_map_1_1::create_sub_dof_map(unsigned int i) const
+{
+    return new projection_0_dof_map_1_1();
+}
+
+
+/// Constructor
+projection_0_dof_map_1::projection_0_dof_map_1() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+projection_0_dof_map_1::~projection_0_dof_map_1()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* projection_0_dof_map_1::signature() const
+{
+    return "FFC dof map for VectorElement('Lagrange', Cell('triangle', 1, Space(2)), 2, 2)";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool projection_0_dof_map_1::needs_mesh_entities(unsigned int d) const
+{
+    switch ( d )
+    {
+    case 0:
+      return true;
+      break;
+    case 1:
+      return true;
+      break;
+    case 2:
+      return false;
+      break;
+    }
+    return false;
+}
+
+/// Initialize dof map for mesh (return true iff init_cell() is needed)
+bool projection_0_dof_map_1::init_mesh(const ufc::mesh& m)
+{
+    __global_dimension = 2*m.num_entities[0] + 2*m.num_entities[1];
+    return false;
+}
+
+/// Initialize dof map for given cell
+void projection_0_dof_map_1::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void projection_0_dof_map_1::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int projection_0_dof_map_1::global_dimension() const
+{
+    return __global_dimension;
+}
+
+/// Return the dimension of the local finite element function space for a cell
+unsigned int projection_0_dof_map_1::local_dimension(const ufc::cell& c) const
+{
+    return 12;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int projection_0_dof_map_1::max_local_dimension() const
+{
+    return 12;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int projection_0_dof_map_1::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int projection_0_dof_map_1::num_facet_dofs() const
+{
+    return 6;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int projection_0_dof_map_1::num_entity_dofs(unsigned int d) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the local-to-global mapping of dofs on a cell
+void projection_0_dof_map_1::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];
+    unsigned int offset = m.num_entities[0];
+    dofs[3] = offset + c.entity_indices[1][0];
+    dofs[4] = offset + c.entity_indices[1][1];
+    dofs[5] = offset + c.entity_indices[1][2];
+    offset = offset + m.num_entities[1];
+    dofs[6] = offset + c.entity_indices[0][0];
+    dofs[7] = offset + c.entity_indices[0][1];
+    dofs[8] = offset + c.entity_indices[0][2];
+    offset = offset + m.num_entities[0];
+    dofs[9] = offset + c.entity_indices[1][0];
+    dofs[10] = offset + c.entity_indices[1][1];
+    dofs[11] = offset + c.entity_indices[1][2];
+}
+
+/// Tabulate the local-to-local mapping from facet dofs to cell dofs
+void projection_0_dof_map_1::tabulate_facet_dofs(unsigned int* dofs,
+                                        unsigned int facet) const
+{
+    switch ( facet )
+    {
+    case 0:
+      dofs[0] = 1;
+      dofs[1] = 2;
+      dofs[2] = 3;
+      dofs[3] = 7;
+      dofs[4] = 8;
+      dofs[5] = 9;
+      break;
+    case 1:
+      dofs[0] = 0;
+      dofs[1] = 2;
+      dofs[2] = 4;
+      dofs[3] = 6;
+      dofs[4] = 8;
+      dofs[5] = 10;
+      break;
+    case 2:
+      dofs[0] = 0;
+      dofs[1] = 1;
+      dofs[2] = 5;
+      dofs[3] = 6;
+      dofs[4] = 7;
+      dofs[5] = 11;
+      break;
+    }
+}
+
+/// Tabulate the local-to-local mapping of dofs on entity (d, i)
+void projection_0_dof_map_1::tabulate_entity_dofs(unsigned int* dofs,
+                                  unsigned int d, unsigned int i) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the coordinates of all dofs on a cell
+void projection_0_dof_map_1::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];
+    coordinates[3][0] = 0.5*x[1][0] + 0.5*x[2][0];
+    coordinates[3][1] = 0.5*x[1][1] + 0.5*x[2][1];
+    coordinates[4][0] = 0.5*x[0][0] + 0.5*x[2][0];
+    coordinates[4][1] = 0.5*x[0][1] + 0.5*x[2][1];
+    coordinates[5][0] = 0.5*x[0][0] + 0.5*x[1][0];
+    coordinates[5][1] = 0.5*x[0][1] + 0.5*x[1][1];
+    coordinates[6][0] = x[0][0];
+    coordinates[6][1] = x[0][1];
+    coordinates[7][0] = x[1][0];
+    coordinates[7][1] = x[1][1];
+    coordinates[8][0] = x[2][0];
+    coordinates[8][1] = x[2][1];
+    coordinates[9][0] = 0.5*x[1][0] + 0.5*x[2][0];
+    coordinates[9][1] = 0.5*x[1][1] + 0.5*x[2][1];
+    coordinates[10][0] = 0.5*x[0][0] + 0.5*x[2][0];
+    coordinates[10][1] = 0.5*x[0][1] + 0.5*x[2][1];
+    coordinates[11][0] = 0.5*x[0][0] + 0.5*x[1][0];
+    coordinates[11][1] = 0.5*x[0][1] + 0.5*x[1][1];
+}
+
+/// Return the number of sub dof maps (for a mixed element)
+unsigned int projection_0_dof_map_1::num_sub_dof_maps() const
+{
+    return 2;
+}
+
+/// Create a new dof_map for sub dof map i (for a mixed element)
+ufc::dof_map* projection_0_dof_map_1::create_sub_dof_map(unsigned int i) const
+{
+    switch ( i )
+    {
+    case 0:
+      return new projection_0_dof_map_1_0();
+      break;
+    case 1:
+      return new projection_0_dof_map_1_1();
+      break;
+    }
+    return 0;
+}
+
+
+/// Constructor
+projection_0_cell_integral_0_quadrature::projection_0_cell_integral_0_quadrature() : ufc::cell_integral()
+{
+    // Do nothing
+}
+
+/// Destructor
+projection_0_cell_integral_0_quadrature::~projection_0_cell_integral_0_quadrature()
+{
+    // Do nothing
+}
+
+/// Tabulate the tensor for the contribution from a local cell
+void projection_0_cell_integral_0_quadrature::tabulate_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 W9[9] = {0.0558144204830443, 0.063678085099885, 0.0193963833059595, 0.0893030727728709, 0.101884936159816, 0.0310342132895351, 0.0558144204830443, 0.063678085099885, 0.0193963833059595};
+    // Quadrature points on the UFC reference element: (0.102717654809626, 0.088587959512704), (0.0665540678391645, 0.409466864440735), (0.0239311322870806, 0.787659461760847), (0.455706020243648, 0.088587959512704), (0.295266567779633, 0.409466864440735), (0.106170269119576, 0.787659461760847), (0.80869438567767, 0.088587959512704), (0.523979067720101, 0.409466864440735), (0.188409405952072, 0.787659461760847)
+    
+    // Value of basis functions at quadrature points.
+    static const double FE0_C0[9][6] = \
+    {{0.499278833175498, -0.0816158215904472, -0.072892306371455, 0.0363981897820602, 0.286562341986258, 0.332268763018087},
+    {0.0251290590975512, -0.0576951799472843, -0.0741406382908806, 0.109006741895515, 0.858208263567716, 0.139491753677383},
+    {-0.117413197449647, -0.022785734101997, 0.453155393641927, 0.0753983311062782, 0.593609805131561, 0.0180354016718773},
+    {-0.0403700664710397, -0.0403700664710397, -0.072892306371455, 0.161480265884159, 0.161480265884159, 0.830671907545216},
+    {-0.120901875682904, -0.120901875682904, -0.0741406382908806, 0.483607502731615, 0.483607502731615, 0.348729384193458},
+    {-0.0836260170297298, -0.0836260170297298, 0.453155393641927, 0.33450406811892, 0.33450406811892, 0.0450885041796933},
+    {-0.0816158215904471, 0.499278833175498, -0.072892306371455, 0.286562341986258, 0.0363981897820602, 0.332268763018087},
+    {-0.0576951799472841, 0.0251290590975512, -0.0741406382908806, 0.858208263567716, 0.109006741895515, 0.139491753677383},
+    {-0.022785734101997, -0.117413197449647, 0.453155393641927, 0.593609805131561, 0.0753983311062783, 0.0180354016718774}};
+    
+    // Array of non-zero columns
+    static const unsigned int nzc1[6] = {6, 7, 8, 9, 10, 11};
+    // Array of non-zero columns
+    static const unsigned int nzc0[6] = {0, 1, 2, 3, 4, 5};
+    
+    // Compute element tensor using UFL quadrature representation
+    // Optimisations: ('simplify expressions', True), ('ignore zero tables', True), ('non zero columns', True), ('remove zero terms', True), ('ignore ones', True)
+    // Total number of operations to compute element tensor: 1953
+    
+    // Loop quadrature points for integral
+    // Number of operations to compute element tensor for following IP loop = 1953
+    for (unsigned int ip = 0; ip < 9; ip++)
+    {
+      
+      // Number of operations to compute ip constants: 1
+      // Number of operations: 1
+      const double Gip0 = W9[ip]*det;
+      
+      
+      // Number of operations for primary indices: 216
+      for (unsigned int j = 0; j < 6; j++)
+      {
+        for (unsigned int k = 0; k < 6; k++)
+        {
+          // Number of operations to compute entry: 3
+          A[nzc0[j]*12 + nzc0[k]] += FE0_C0[ip][j]*FE0_C0[ip][k]*Gip0;
+          // Number of operations to compute entry: 3
+          A[nzc1[j]*12 + nzc1[k]] += FE0_C0[ip][j]*FE0_C0[ip][k]*Gip0;
+        }// end loop over 'k'
+      }// end loop over 'j'
+    }// end loop over 'ip'
+}
+
+/// Constructor
+projection_0_cell_integral_0::projection_0_cell_integral_0() : ufc::cell_integral()
+{
+    // Do nothing
+}
+
+/// Destructor
+projection_0_cell_integral_0::~projection_0_cell_integral_0()
+{
+    // Do nothing
+}
+
+/// Tabulate the tensor for the contribution from a local cell
+void projection_0_cell_integral_0::tabulate_tensor(double* A,
+                                    const double * const * w,
+                                    const ufc::cell& c) const
+{
+    // Reset values of the element tensor block
+    for (unsigned int j = 0; j < 144; j++)
+      A[j] = 0;
+    
+    // Add all contributions to element tensor
+    integral_0_quadrature.tabulate_tensor(A, w, c);
+}
+
+/// Constructor
+projection_form_0::projection_form_0() : ufc::form()
+{
+    // Do nothing
+}
+
+/// Destructor
+projection_form_0::~projection_form_0()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the form
+const char* projection_form_0::signature() const
+{
+    return "Form([Integral(IndexSum(Product(Indexed(BasisFunction(VectorElement('Lagrange', Cell('triangle', 1, Space(2)), 2, 2), 0), MultiIndex((Index(0),), {Index(0): 2})), Indexed(BasisFunction(VectorElement('Lagrange', Cell('triangle', 1, Space(2)), 2, 2), 1), MultiIndex((Index(0),), {Index(0): 2}))), MultiIndex((Index(0),), {Index(0): 2})), Measure('cell', 0, None))])";
+}
+
+/// Return the rank of the global tensor (r)
+unsigned int projection_form_0::rank() const
+{
+    return 2;
+}
+
+/// Return the number of coefficients (n)
+unsigned int projection_form_0::num_coefficients() const
+{
+    return 0;
+}
+
+/// Return the number of cell integrals
+unsigned int projection_form_0::num_cell_integrals() const
+{
+    return 1;
+}
+
+/// Return the number of exterior facet integrals
+unsigned int projection_form_0::num_exterior_facet_integrals() const
+{
+    return 0;
+}
+
+/// Return the number of interior facet integrals
+unsigned int projection_form_0::num_interior_facet_integrals() const
+{
+    return 0;
+}
+
+/// Create a new finite element for argument function i
+ufc::finite_element* projection_form_0::create_finite_element(unsigned int i) const
+{
+    switch ( i )
+    {
+    case 0:
+      return new projection_0_finite_element_0();
+      break;
+    case 1:
+      return new projection_0_finite_element_1();
+      break;
+    }
+    return 0;
+}
+
+/// Create a new dof map for argument function i
+ufc::dof_map* projection_form_0::create_dof_map(unsigned int i) const
+{
+    switch ( i )
+    {
+    case 0:
+      return new projection_0_dof_map_0();
+      break;
+    case 1:
+      return new projection_0_dof_map_1();
+      break;
+    }
+    return 0;
+}
+
+/// Create a new cell integral on sub domain i
+ufc::cell_integral* projection_form_0::create_cell_integral(unsigned int i) const
+{
+    return new projection_0_cell_integral_0();
+}
+
+/// Create a new exterior facet integral on sub domain i
+ufc::exterior_facet_integral* projection_form_0::create_exterior_facet_integral(unsigned int i) const
+{
+    return 0;
+}
+
+/// Create a new interior facet integral on sub domain i
+ufc::interior_facet_integral* projection_form_0::create_interior_facet_integral(unsigned int i) const
+{
+    return 0;
+}
+
+
+/// Constructor
+projection_1_finite_element_0_0::projection_1_finite_element_0_0() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+projection_1_finite_element_0_0::~projection_1_finite_element_0_0()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* projection_1_finite_element_0_0::signature() const
+{
+    return "FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
+}
+
+/// Return the cell shape
+ufc::shape projection_1_finite_element_0_0::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int projection_1_finite_element_0_0::space_dimension() const
+{
+    return 6;
+}
+
+/// Return the rank of the value space
+unsigned int projection_1_finite_element_0_0::value_rank() const
+{
+    return 0;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int projection_1_finite_element_0_0::value_dimension(unsigned int i) const
+{
+    return 1;
+}
+
+/// Evaluate basis function i at given point in cell
+void projection_1_finite_element_0_0::evaluate_basis(unsigned int i,
+                                   double* values,
+                                   const double* coordinates,
+                                   const ufc::cell& c) const
+{
+    // Extract vertex coordinates
+    const double * const * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Reset values
+    *values = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+    const double psitilde_bs_1_0 = 1;
+    const double psitilde_bs_1_1 = 2.5*y + 1.5;
+    const double psitilde_bs_2_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+    const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+    const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[6][6] = \
+    {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+    {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+    {0, 0, 0.2, 0, 0, 0.163299316185545},
+    {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+    {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+    {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+    // Extract relevant coefficients
+    const double coeff0_0 = coefficients0[dof][0];
+    const double coeff0_1 = coefficients0[dof][1];
+    const double coeff0_2 = coefficients0[dof][2];
+    const double coeff0_3 = coefficients0[dof][3];
+    const double coeff0_4 = coefficients0[dof][4];
+    const double coeff0_5 = coefficients0[dof][5];
+    
+    // Compute value(s)
+    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
+}
+
+/// Evaluate all basis functions at given point in cell
+void projection_1_finite_element_0_0::evaluate_basis_all(double* values,
+                                       const double* coordinates,
+                                       const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
+}
+
+/// Evaluate order n derivatives of basis function i at given point in cell
+void projection_1_finite_element_0_0::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 * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 2;
+    
+    
+    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
+    unsigned int **combinations = new unsigned int *[num_derivatives];
+    
+    for (unsigned int j = 0; j < num_derivatives; j++)
+    {
+      combinations[j] = new unsigned int [n];
+      for (unsigned int k = 0; k < n; k++)
+        combinations[j][k] = 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] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
+    
+    // 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
+    for (unsigned int j = 0; j < 1*num_derivatives; j++)
+      values[j] = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+    const double psitilde_bs_1_0 = 1;
+    const double psitilde_bs_1_1 = 2.5*y + 1.5;
+    const double psitilde_bs_2_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+    const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+    const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[6][6] = \
+    {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+    {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+    {0, 0, 0.2, 0, 0, 0.163299316185545},
+    {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+    {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+    {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+    // Interesting (new) part
+    // Tables of derivatives of the polynomial base (transpose)
+    static const double dmats0[6][6] = \
+    {{0, 0, 0, 0, 0, 0},
+    {4.89897948556636, 0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0},
+    {0, 9.48683298050514, 0, 0, 0, 0},
+    {4, 0, 7.07106781186548, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0}};
+    
+    static const double dmats1[6][6] = \
+    {{0, 0, 0, 0, 0, 0},
+    {2.44948974278318, 0, 0, 0, 0, 0},
+    {4.24264068711928, 0, 0, 0, 0, 0},
+    {2.58198889747161, 4.74341649025257, -0.912870929175277, 0, 0, 0},
+    {2, 6.12372435695795, 3.53553390593274, 0, 0, 0},
+    {-2.3094010767585, 0, 8.16496580927726, 0, 0, 0}};
+    
+    // Compute reference derivatives
+    // Declare pointer to array of derivatives on FIAT element
+    double *derivatives = new double [num_derivatives];
+    
+    // Declare coefficients
+    double coeff0_0 = 0;
+    double coeff0_1 = 0;
+    double coeff0_2 = 0;
+    double coeff0_3 = 0;
+    double coeff0_4 = 0;
+    double coeff0_5 = 0;
+    
+    // Declare new coefficients
+    double new_coeff0_0 = 0;
+    double new_coeff0_1 = 0;
+    double new_coeff0_2 = 0;
+    double new_coeff0_3 = 0;
+    double new_coeff0_4 = 0;
+    double new_coeff0_5 = 0;
+    
+    // Loop possible derivatives
+    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+    {
+      // Get values from coefficients array
+      new_coeff0_0 = coefficients0[dof][0];
+      new_coeff0_1 = coefficients0[dof][1];
+      new_coeff0_2 = coefficients0[dof][2];
+      new_coeff0_3 = coefficients0[dof][3];
+      new_coeff0_4 = coefficients0[dof][4];
+      new_coeff0_5 = coefficients0[dof][5];
+    
+      // Loop derivative order
+      for (unsigned int j = 0; j < n; j++)
+      {
+        // Update old coefficients
+        coeff0_0 = new_coeff0_0;
+        coeff0_1 = new_coeff0_1;
+        coeff0_2 = new_coeff0_2;
+        coeff0_3 = new_coeff0_3;
+        coeff0_4 = new_coeff0_4;
+        coeff0_5 = new_coeff0_5;
+    
+        if(combinations[deriv_num][j] == 0)
+        {
+          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
+          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
+          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
+          new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
+          new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
+          new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
+        }
+        if(combinations[deriv_num][j] == 1)
+        {
+          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
+          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
+          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
+          new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
+          new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
+          new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
+        }
+    
+      }
+      // Compute derivatives on reference element as dot product of coefficients and basisvalues
+      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
+    }
+    
+    // Transform derivatives back to physical element
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      for (unsigned int col = 0; col < num_derivatives; col++)
+      {
+        values[row] += transform[row][col]*derivatives[col];
+      }
+    }
+    // Delete pointer to array of derivatives on FIAT element
+    delete [] derivatives;
+    
+    // Delete pointer to array of combinations of derivatives and transform
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      delete [] combinations[row];
+      delete [] transform[row];
+    }
+    
+    delete [] combinations;
+    delete [] transform;
+}
+
+/// Evaluate order n derivatives of all basis functions at given point in cell
+void projection_1_finite_element_0_0::evaluate_basis_derivatives_all(unsigned int n,
+                                                   double* values,
+                                                   const double* coordinates,
+                                                   const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
+}
+
+/// Evaluate linear functional for dof i on the function f
+double projection_1_finite_element_0_0::evaluate_dof(unsigned int i,
+                                   const ufc::function& f,
+                                   const ufc::cell& c) const
+{
+    // The reference points, direction and weights:
+    static const double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}};
+    static const double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
+    static const double D[6][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}, {{1}}, {{1}}};
+    
+    const double * const * x = c.coordinates;
+    double result = 0.0;
+    // Iterate over the points:
+    // Evaluate basis functions for affine mapping
+    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    
+    // Compute affine mapping y = F(X)
+    double y[2];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
+    
+    // Evaluate function at physical points
+    double values[1];
+    f.evaluate(values, y, c);
+    
+    // Map function values using appropriate mapping
+    // Affine map: Do nothing
+    
+    // Note that we do not map the weights (yet).
+    
+    // Take directional components
+    for(int k = 0; k < 1; k++)
+      result += values[k]*D[i][0][k];
+    // Multiply by weights
+    result *= W[i][0];
+    
+    return result;
+}
+
+/// Evaluate linear functionals for all dofs on the function f
+void projection_1_finite_element_0_0::evaluate_dofs(double* values,
+                                  const ufc::function& f,
+                                  const ufc::cell& c) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Interpolate vertex values from dof values
+void projection_1_finite_element_0_0::interpolate_vertex_values(double* vertex_values,
+                                              const double* dof_values,
+                                              const ufc::cell& c) const
+{
+    // Evaluate at vertices and use affine mapping
+    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)
+unsigned int projection_1_finite_element_0_0::num_sub_elements() const
+{
+    return 1;
+}
+
+/// Create a new finite element for sub element i (for a mixed element)
+ufc::finite_element* projection_1_finite_element_0_0::create_sub_element(unsigned int i) const
+{
+    return new projection_1_finite_element_0_0();
+}
+
+
+/// Constructor
+projection_1_finite_element_0_1::projection_1_finite_element_0_1() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+projection_1_finite_element_0_1::~projection_1_finite_element_0_1()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* projection_1_finite_element_0_1::signature() const
+{
+    return "FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
+}
+
+/// Return the cell shape
+ufc::shape projection_1_finite_element_0_1::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int projection_1_finite_element_0_1::space_dimension() const
+{
+    return 6;
+}
+
+/// Return the rank of the value space
+unsigned int projection_1_finite_element_0_1::value_rank() const
+{
+    return 0;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int projection_1_finite_element_0_1::value_dimension(unsigned int i) const
+{
+    return 1;
+}
+
+/// Evaluate basis function i at given point in cell
+void projection_1_finite_element_0_1::evaluate_basis(unsigned int i,
+                                   double* values,
+                                   const double* coordinates,
+                                   const ufc::cell& c) const
+{
+    // Extract vertex coordinates
+    const double * const * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Reset values
+    *values = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+    const double psitilde_bs_1_0 = 1;
+    const double psitilde_bs_1_1 = 2.5*y + 1.5;
+    const double psitilde_bs_2_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+    const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+    const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[6][6] = \
+    {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+    {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+    {0, 0, 0.2, 0, 0, 0.163299316185545},
+    {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+    {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+    {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+    // Extract relevant coefficients
+    const double coeff0_0 = coefficients0[dof][0];
+    const double coeff0_1 = coefficients0[dof][1];
+    const double coeff0_2 = coefficients0[dof][2];
+    const double coeff0_3 = coefficients0[dof][3];
+    const double coeff0_4 = coefficients0[dof][4];
+    const double coeff0_5 = coefficients0[dof][5];
+    
+    // Compute value(s)
+    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
+}
+
+/// Evaluate all basis functions at given point in cell
+void projection_1_finite_element_0_1::evaluate_basis_all(double* values,
+                                       const double* coordinates,
+                                       const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
+}
+
+/// Evaluate order n derivatives of basis function i at given point in cell
+void projection_1_finite_element_0_1::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 * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 2;
+    
+    
+    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
+    unsigned int **combinations = new unsigned int *[num_derivatives];
+    
+    for (unsigned int j = 0; j < num_derivatives; j++)
+    {
+      combinations[j] = new unsigned int [n];
+      for (unsigned int k = 0; k < n; k++)
+        combinations[j][k] = 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] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
+    
+    // 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
+    for (unsigned int j = 0; j < 1*num_derivatives; j++)
+      values[j] = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+    const double psitilde_bs_1_0 = 1;
+    const double psitilde_bs_1_1 = 2.5*y + 1.5;
+    const double psitilde_bs_2_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+    const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+    const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[6][6] = \
+    {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+    {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+    {0, 0, 0.2, 0, 0, 0.163299316185545},
+    {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+    {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+    {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+    // Interesting (new) part
+    // Tables of derivatives of the polynomial base (transpose)
+    static const double dmats0[6][6] = \
+    {{0, 0, 0, 0, 0, 0},
+    {4.89897948556636, 0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0},
+    {0, 9.48683298050514, 0, 0, 0, 0},
+    {4, 0, 7.07106781186548, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0}};
+    
+    static const double dmats1[6][6] = \
+    {{0, 0, 0, 0, 0, 0},
+    {2.44948974278318, 0, 0, 0, 0, 0},
+    {4.24264068711928, 0, 0, 0, 0, 0},
+    {2.58198889747161, 4.74341649025257, -0.912870929175277, 0, 0, 0},
+    {2, 6.12372435695795, 3.53553390593274, 0, 0, 0},
+    {-2.3094010767585, 0, 8.16496580927726, 0, 0, 0}};
+    
+    // Compute reference derivatives
+    // Declare pointer to array of derivatives on FIAT element
+    double *derivatives = new double [num_derivatives];
+    
+    // Declare coefficients
+    double coeff0_0 = 0;
+    double coeff0_1 = 0;
+    double coeff0_2 = 0;
+    double coeff0_3 = 0;
+    double coeff0_4 = 0;
+    double coeff0_5 = 0;
+    
+    // Declare new coefficients
+    double new_coeff0_0 = 0;
+    double new_coeff0_1 = 0;
+    double new_coeff0_2 = 0;
+    double new_coeff0_3 = 0;
+    double new_coeff0_4 = 0;
+    double new_coeff0_5 = 0;
+    
+    // Loop possible derivatives
+    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+    {
+      // Get values from coefficients array
+      new_coeff0_0 = coefficients0[dof][0];
+      new_coeff0_1 = coefficients0[dof][1];
+      new_coeff0_2 = coefficients0[dof][2];
+      new_coeff0_3 = coefficients0[dof][3];
+      new_coeff0_4 = coefficients0[dof][4];
+      new_coeff0_5 = coefficients0[dof][5];
+    
+      // Loop derivative order
+      for (unsigned int j = 0; j < n; j++)
+      {
+        // Update old coefficients
+        coeff0_0 = new_coeff0_0;
+        coeff0_1 = new_coeff0_1;
+        coeff0_2 = new_coeff0_2;
+        coeff0_3 = new_coeff0_3;
+        coeff0_4 = new_coeff0_4;
+        coeff0_5 = new_coeff0_5;
+    
+        if(combinations[deriv_num][j] == 0)
+        {
+          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
+          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
+          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
+          new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
+          new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
+          new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
+        }
+        if(combinations[deriv_num][j] == 1)
+        {
+          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
+          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
+          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
+          new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
+          new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
+          new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
+        }
+    
+      }
+      // Compute derivatives on reference element as dot product of coefficients and basisvalues
+      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
+    }
+    
+    // Transform derivatives back to physical element
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      for (unsigned int col = 0; col < num_derivatives; col++)
+      {
+        values[row] += transform[row][col]*derivatives[col];
+      }
+    }
+    // Delete pointer to array of derivatives on FIAT element
+    delete [] derivatives;
+    
+    // Delete pointer to array of combinations of derivatives and transform
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      delete [] combinations[row];
+      delete [] transform[row];
+    }
+    
+    delete [] combinations;
+    delete [] transform;
+}
+
+/// Evaluate order n derivatives of all basis functions at given point in cell
+void projection_1_finite_element_0_1::evaluate_basis_derivatives_all(unsigned int n,
+                                                   double* values,
+                                                   const double* coordinates,
+                                                   const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
+}
+
+/// Evaluate linear functional for dof i on the function f
+double projection_1_finite_element_0_1::evaluate_dof(unsigned int i,
+                                   const ufc::function& f,
+                                   const ufc::cell& c) const
+{
+    // The reference points, direction and weights:
+    static const double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}};
+    static const double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
+    static const double D[6][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}, {{1}}, {{1}}};
+    
+    const double * const * x = c.coordinates;
+    double result = 0.0;
+    // Iterate over the points:
+    // Evaluate basis functions for affine mapping
+    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    
+    // Compute affine mapping y = F(X)
+    double y[2];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
+    
+    // Evaluate function at physical points
+    double values[1];
+    f.evaluate(values, y, c);
+    
+    // Map function values using appropriate mapping
+    // Affine map: Do nothing
+    
+    // Note that we do not map the weights (yet).
+    
+    // Take directional components
+    for(int k = 0; k < 1; k++)
+      result += values[k]*D[i][0][k];
+    // Multiply by weights
+    result *= W[i][0];
+    
+    return result;
+}
+
+/// Evaluate linear functionals for all dofs on the function f
+void projection_1_finite_element_0_1::evaluate_dofs(double* values,
+                                  const ufc::function& f,
+                                  const ufc::cell& c) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Interpolate vertex values from dof values
+void projection_1_finite_element_0_1::interpolate_vertex_values(double* vertex_values,
+                                              const double* dof_values,
+                                              const ufc::cell& c) const
+{
+    // Evaluate at vertices and use affine mapping
+    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)
+unsigned int projection_1_finite_element_0_1::num_sub_elements() const
+{
+    return 1;
+}
+
+/// Create a new finite element for sub element i (for a mixed element)
+ufc::finite_element* projection_1_finite_element_0_1::create_sub_element(unsigned int i) const
+{
+    return new projection_1_finite_element_0_1();
+}
+
+
+/// Constructor
+projection_1_finite_element_0::projection_1_finite_element_0() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+projection_1_finite_element_0::~projection_1_finite_element_0()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* projection_1_finite_element_0::signature() const
+{
+    return "VectorElement('Lagrange', Cell('triangle', 1, Space(2)), 2, 2)";
+}
+
+/// Return the cell shape
+ufc::shape projection_1_finite_element_0::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int projection_1_finite_element_0::space_dimension() const
+{
+    return 12;
+}
+
+/// Return the rank of the value space
+unsigned int projection_1_finite_element_0::value_rank() const
+{
+    return 1;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int projection_1_finite_element_0::value_dimension(unsigned int i) const
+{
+    return 2;
+}
+
+/// Evaluate basis function i at given point in cell
+void projection_1_finite_element_0::evaluate_basis(unsigned int i,
+                                   double* values,
+                                   const double* coordinates,
+                                   const ufc::cell& c) const
+{
+    // Extract vertex coordinates
+    const double * const * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Reset values
+    values[0] = 0;
+    values[1] = 0;
+    
+    if (0 <= i && i <= 5)
+    {
+      // Map degree of freedom to element degree of freedom
+      const unsigned int dof = i;
+    
+      // Generate scalings
+      const double scalings_y_0 = 1;
+      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+      const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+      // Compute psitilde_a
+      const double psitilde_a_0 = 1;
+      const double psitilde_a_1 = x;
+      const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+      // Compute psitilde_bs
+      const double psitilde_bs_0_0 = 1;
+      const double psitilde_bs_0_1 = 1.5*y + 0.5;
+      const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+      const double psitilde_bs_1_0 = 1;
+      const double psitilde_bs_1_1 = 2.5*y + 1.5;
+      const double psitilde_bs_2_0 = 1;
+    
+      // Compute basisvalues
+      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+      const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+      const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+      const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+      // Table(s) of coefficients
+      static const double coefficients0[6][6] =   \
+      {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+      {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+      {0, 0, 0.2, 0, 0, 0.163299316185545},
+      {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+      {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+      {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+      // Extract relevant coefficients
+      const double coeff0_0 =   coefficients0[dof][0];
+      const double coeff0_1 =   coefficients0[dof][1];
+      const double coeff0_2 =   coefficients0[dof][2];
+      const double coeff0_3 =   coefficients0[dof][3];
+      const double coeff0_4 =   coefficients0[dof][4];
+      const double coeff0_5 =   coefficients0[dof][5];
+    
+      // Compute value(s)
+      values[0] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
+    }
+    
+    if (6 <= i && i <= 11)
+    {
+      // Map degree of freedom to element degree of freedom
+      const unsigned int dof = i - 6;
+    
+      // Generate scalings
+      const double scalings_y_0 = 1;
+      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+      const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+      // Compute psitilde_a
+      const double psitilde_a_0 = 1;
+      const double psitilde_a_1 = x;
+      const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+      // Compute psitilde_bs
+      const double psitilde_bs_0_0 = 1;
+      const double psitilde_bs_0_1 = 1.5*y + 0.5;
+      const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+      const double psitilde_bs_1_0 = 1;
+      const double psitilde_bs_1_1 = 2.5*y + 1.5;
+      const double psitilde_bs_2_0 = 1;
+    
+      // Compute basisvalues
+      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+      const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+      const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+      const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+      // Table(s) of coefficients
+      static const double coefficients0[6][6] =   \
+      {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+      {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+      {0, 0, 0.2, 0, 0, 0.163299316185545},
+      {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+      {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+      {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+      // Extract relevant coefficients
+      const double coeff0_0 =   coefficients0[dof][0];
+      const double coeff0_1 =   coefficients0[dof][1];
+      const double coeff0_2 =   coefficients0[dof][2];
+      const double coeff0_3 =   coefficients0[dof][3];
+      const double coeff0_4 =   coefficients0[dof][4];
+      const double coeff0_5 =   coefficients0[dof][5];
+    
+      // Compute value(s)
+      values[1] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
+    }
+    
+}
+
+/// Evaluate all basis functions at given point in cell
+void projection_1_finite_element_0::evaluate_basis_all(double* values,
+                                       const double* coordinates,
+                                       const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
+}
+
+/// Evaluate order n derivatives of basis function i at given point in cell
+void projection_1_finite_element_0::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 * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 2;
+    
+    
+    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
+    unsigned int **combinations = new unsigned int *[num_derivatives];
+    
+    for (unsigned int j = 0; j < num_derivatives; j++)
+    {
+      combinations[j] = new unsigned int [n];
+      for (unsigned int k = 0; k < n; k++)
+        combinations[j][k] = 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] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
+    
+    // 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
+    for (unsigned int j = 0; j < 2*num_derivatives; j++)
+      values[j] = 0;
+    
+    if (0 <= i && i <= 5)
+    {
+      // Map degree of freedom to element degree of freedom
+      const unsigned int dof = i;
+    
+      // Generate scalings
+      const double scalings_y_0 = 1;
+      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+      const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+      // Compute psitilde_a
+      const double psitilde_a_0 = 1;
+      const double psitilde_a_1 = x;
+      const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+      // Compute psitilde_bs
+      const double psitilde_bs_0_0 = 1;
+      const double psitilde_bs_0_1 = 1.5*y + 0.5;
+      const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+      const double psitilde_bs_1_0 = 1;
+      const double psitilde_bs_1_1 = 2.5*y + 1.5;
+      const double psitilde_bs_2_0 = 1;
+    
+      // Compute basisvalues
+      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+      const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+      const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+      const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+      // Table(s) of coefficients
+      static const double coefficients0[6][6] =   \
+      {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+      {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+      {0, 0, 0.2, 0, 0, 0.163299316185545},
+      {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+      {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+      {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+      // Interesting (new) part
+      // Tables of derivatives of the polynomial base (transpose)
+      static const double dmats0[6][6] =   \
+      {{0, 0, 0, 0, 0, 0},
+      {4.89897948556636, 0, 0, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0},
+      {0, 9.48683298050514, 0, 0, 0, 0},
+      {4, 0, 7.07106781186548, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0}};
+    
+      static const double dmats1[6][6] =   \
+      {{0, 0, 0, 0, 0, 0},
+      {2.44948974278318, 0, 0, 0, 0, 0},
+      {4.24264068711928, 0, 0, 0, 0, 0},
+      {2.58198889747161, 4.74341649025257, -0.912870929175277, 0, 0, 0},
+      {2, 6.12372435695795, 3.53553390593274, 0, 0, 0},
+      {-2.3094010767585, 0, 8.16496580927726, 0, 0, 0}};
+    
+      // Compute reference derivatives
+      // Declare pointer to array of derivatives on FIAT element
+      double *derivatives = new double [num_derivatives];
+    
+      // Declare coefficients
+      double coeff0_0 = 0;
+      double coeff0_1 = 0;
+      double coeff0_2 = 0;
+      double coeff0_3 = 0;
+      double coeff0_4 = 0;
+      double coeff0_5 = 0;
+    
+      // Declare new coefficients
+      double new_coeff0_0 = 0;
+      double new_coeff0_1 = 0;
+      double new_coeff0_2 = 0;
+      double new_coeff0_3 = 0;
+      double new_coeff0_4 = 0;
+      double new_coeff0_5 = 0;
+    
+      // Loop possible derivatives
+      for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+      {
+        // Get values from coefficients array
+        new_coeff0_0 = coefficients0[dof][0];
+        new_coeff0_1 = coefficients0[dof][1];
+        new_coeff0_2 = coefficients0[dof][2];
+        new_coeff0_3 = coefficients0[dof][3];
+        new_coeff0_4 = coefficients0[dof][4];
+        new_coeff0_5 = coefficients0[dof][5];
+    
+        // Loop derivative order
+        for (unsigned int j = 0; j < n; j++)
+        {
+          // Update old coefficients
+          coeff0_0 = new_coeff0_0;
+          coeff0_1 = new_coeff0_1;
+          coeff0_2 = new_coeff0_2;
+          coeff0_3 = new_coeff0_3;
+          coeff0_4 = new_coeff0_4;
+          coeff0_5 = new_coeff0_5;
+    
+          if(combinations[deriv_num][j] == 0)
+          {
+            new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
+            new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
+            new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
+            new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
+            new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
+            new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
+          }
+          if(combinations[deriv_num][j] == 1)
+          {
+            new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
+            new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
+            new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
+            new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
+            new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
+            new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
+          }
+    
+        }
+        // Compute derivatives on reference element as dot product of coefficients and basisvalues
+        derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
+      }
+    
+      // Transform derivatives back to physical element
+      for (unsigned int row = 0; row < num_derivatives; row++)
+      {
+        for (unsigned int col = 0; col < num_derivatives; col++)
+        {
+          values[row] += transform[row][col]*derivatives[col];
+        }
+      }
+      // Delete pointer to array of derivatives on FIAT element
+      delete [] derivatives;
+    
+      // Delete pointer to array of combinations of derivatives and transform
+      for (unsigned int row = 0; row < num_derivatives; row++)
+      {
+        delete [] combinations[row];
+        delete [] transform[row];
+      }
+    
+      delete [] combinations;
+      delete [] transform;
+    }
+    
+    if (6 <= i && i <= 11)
+    {
+      // Map degree of freedom to element degree of freedom
+      const unsigned int dof = i - 6;
+    
+      // Generate scalings
+      const double scalings_y_0 = 1;
+      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+      const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+      // Compute psitilde_a
+      const double psitilde_a_0 = 1;
+      const double psitilde_a_1 = x;
+      const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+      // Compute psitilde_bs
+      const double psitilde_bs_0_0 = 1;
+      const double psitilde_bs_0_1 = 1.5*y + 0.5;
+      const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+      const double psitilde_bs_1_0 = 1;
+      const double psitilde_bs_1_1 = 2.5*y + 1.5;
+      const double psitilde_bs_2_0 = 1;
+    
+      // Compute basisvalues
+      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+      const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+      const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+      const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+      // Table(s) of coefficients
+      static const double coefficients0[6][6] =   \
+      {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+      {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+      {0, 0, 0.2, 0, 0, 0.163299316185545},
+      {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+      {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+      {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+      // Interesting (new) part
+      // Tables of derivatives of the polynomial base (transpose)
+      static const double dmats0[6][6] =   \
+      {{0, 0, 0, 0, 0, 0},
+      {4.89897948556636, 0, 0, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0},
+      {0, 9.48683298050514, 0, 0, 0, 0},
+      {4, 0, 7.07106781186548, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0}};
+    
+      static const double dmats1[6][6] =   \
+      {{0, 0, 0, 0, 0, 0},
+      {2.44948974278318, 0, 0, 0, 0, 0},
+      {4.24264068711928, 0, 0, 0, 0, 0},
+      {2.58198889747161, 4.74341649025257, -0.912870929175277, 0, 0, 0},
+      {2, 6.12372435695795, 3.53553390593274, 0, 0, 0},
+      {-2.3094010767585, 0, 8.16496580927726, 0, 0, 0}};
+    
+      // Compute reference derivatives
+      // Declare pointer to array of derivatives on FIAT element
+      double *derivatives = new double [num_derivatives];
+    
+      // Declare coefficients
+      double coeff0_0 = 0;
+      double coeff0_1 = 0;
+      double coeff0_2 = 0;
+      double coeff0_3 = 0;
+      double coeff0_4 = 0;
+      double coeff0_5 = 0;
+    
+      // Declare new coefficients
+      double new_coeff0_0 = 0;
+      double new_coeff0_1 = 0;
+      double new_coeff0_2 = 0;
+      double new_coeff0_3 = 0;
+      double new_coeff0_4 = 0;
+      double new_coeff0_5 = 0;
+    
+      // Loop possible derivatives
+      for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+      {
+        // Get values from coefficients array
+        new_coeff0_0 = coefficients0[dof][0];
+        new_coeff0_1 = coefficients0[dof][1];
+        new_coeff0_2 = coefficients0[dof][2];
+        new_coeff0_3 = coefficients0[dof][3];
+        new_coeff0_4 = coefficients0[dof][4];
+        new_coeff0_5 = coefficients0[dof][5];
+    
+        // Loop derivative order
+        for (unsigned int j = 0; j < n; j++)
+        {
+          // Update old coefficients
+          coeff0_0 = new_coeff0_0;
+          coeff0_1 = new_coeff0_1;
+          coeff0_2 = new_coeff0_2;
+          coeff0_3 = new_coeff0_3;
+          coeff0_4 = new_coeff0_4;
+          coeff0_5 = new_coeff0_5;
+    
+          if(combinations[deriv_num][j] == 0)
+          {
+            new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
+            new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
+            new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
+            new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
+            new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
+            new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
+          }
+          if(combinations[deriv_num][j] == 1)
+          {
+            new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
+            new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
+            new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
+            new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
+            new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
+            new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
+          }
+    
+        }
+        // Compute derivatives on reference element as dot product of coefficients and basisvalues
+        derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
+      }
+    
+      // Transform derivatives back to physical element
+      for (unsigned int row = 0; row < num_derivatives; row++)
+      {
+        for (unsigned int col = 0; col < num_derivatives; col++)
+        {
+          values[num_derivatives + row] += transform[row][col]*derivatives[col];
+        }
+      }
+      // Delete pointer to array of derivatives on FIAT element
+      delete [] derivatives;
+    
+      // Delete pointer to array of combinations of derivatives and transform
+      for (unsigned int row = 0; row < num_derivatives; row++)
+      {
+        delete [] combinations[row];
+        delete [] transform[row];
+      }
+    
+      delete [] combinations;
+      delete [] transform;
+    }
+    
+}
+
+/// Evaluate order n derivatives of all basis functions at given point in cell
+void projection_1_finite_element_0::evaluate_basis_derivatives_all(unsigned int n,
+                                                   double* values,
+                                                   const double* coordinates,
+                                                   const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
+}
+
+/// Evaluate linear functional for dof i on the function f
+double projection_1_finite_element_0::evaluate_dof(unsigned int i,
+                                   const ufc::function& f,
+                                   const ufc::cell& c) const
+{
+    // The reference points, direction and weights:
+    static const double X[12][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}, {{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}};
+    static const double W[12][1] = {{1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}};
+    static const double D[12][1][2] = {{{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{0, 1}}, {{0, 1}}, {{0, 1}}, {{0, 1}}, {{0, 1}}, {{0, 1}}};
+    
+    const double * const * x = c.coordinates;
+    double result = 0.0;
+    // Iterate over the points:
+    // Evaluate basis functions for affine mapping
+    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    
+    // Compute affine mapping y = F(X)
+    double y[2];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
+    
+    // Evaluate function at physical points
+    double values[2];
+    f.evaluate(values, y, c);
+    
+    // Map function values using appropriate mapping
+    // Affine map: Do nothing
+    
+    // Note that we do not map the weights (yet).
+    
+    // Take directional components
+    for(int k = 0; k < 2; k++)
+      result += values[k]*D[i][0][k];
+    // Multiply by weights
+    result *= W[i][0];
+    
+    return result;
+}
+
+/// Evaluate linear functionals for all dofs on the function f
+void projection_1_finite_element_0::evaluate_dofs(double* values,
+                                  const ufc::function& f,
+                                  const ufc::cell& c) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Interpolate vertex values from dof values
+void projection_1_finite_element_0::interpolate_vertex_values(double* vertex_values,
+                                              const double* dof_values,
+                                              const ufc::cell& c) const
+{
+    // Evaluate at vertices and use affine mapping
+    vertex_values[0] = dof_values[0];
+    vertex_values[2] = dof_values[1];
+    vertex_values[4] = dof_values[2];
+    // Evaluate at vertices and use affine mapping
+    vertex_values[1] = dof_values[6];
+    vertex_values[3] = dof_values[7];
+    vertex_values[5] = dof_values[8];
+}
+
+/// Return the number of sub elements (for a mixed element)
+unsigned int projection_1_finite_element_0::num_sub_elements() const
+{
+    return 2;
+}
+
+/// Create a new finite element for sub element i (for a mixed element)
+ufc::finite_element* projection_1_finite_element_0::create_sub_element(unsigned int i) const
+{
+    switch ( i )
+    {
+    case 0:
+      return new projection_1_finite_element_0_0();
+      break;
+    case 1:
+      return new projection_1_finite_element_0_1();
+      break;
+    }
+    return 0;
+}
+
+
+/// Constructor
+projection_1_finite_element_1_0::projection_1_finite_element_1_0() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+projection_1_finite_element_1_0::~projection_1_finite_element_1_0()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* projection_1_finite_element_1_0::signature() const
+{
+    return "FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
+}
+
+/// Return the cell shape
+ufc::shape projection_1_finite_element_1_0::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int projection_1_finite_element_1_0::space_dimension() const
+{
+    return 6;
+}
+
+/// Return the rank of the value space
+unsigned int projection_1_finite_element_1_0::value_rank() const
+{
+    return 0;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int projection_1_finite_element_1_0::value_dimension(unsigned int i) const
+{
+    return 1;
+}
+
+/// Evaluate basis function i at given point in cell
+void projection_1_finite_element_1_0::evaluate_basis(unsigned int i,
+                                   double* values,
+                                   const double* coordinates,
+                                   const ufc::cell& c) const
+{
+    // Extract vertex coordinates
+    const double * const * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Reset values
+    *values = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+    const double psitilde_bs_1_0 = 1;
+    const double psitilde_bs_1_1 = 2.5*y + 1.5;
+    const double psitilde_bs_2_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+    const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+    const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[6][6] = \
+    {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+    {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+    {0, 0, 0.2, 0, 0, 0.163299316185545},
+    {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+    {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+    {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+    // Extract relevant coefficients
+    const double coeff0_0 = coefficients0[dof][0];
+    const double coeff0_1 = coefficients0[dof][1];
+    const double coeff0_2 = coefficients0[dof][2];
+    const double coeff0_3 = coefficients0[dof][3];
+    const double coeff0_4 = coefficients0[dof][4];
+    const double coeff0_5 = coefficients0[dof][5];
+    
+    // Compute value(s)
+    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
+}
+
+/// Evaluate all basis functions at given point in cell
+void projection_1_finite_element_1_0::evaluate_basis_all(double* values,
+                                       const double* coordinates,
+                                       const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
+}
+
+/// Evaluate order n derivatives of basis function i at given point in cell
+void projection_1_finite_element_1_0::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 * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 2;
+    
+    
+    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
+    unsigned int **combinations = new unsigned int *[num_derivatives];
+    
+    for (unsigned int j = 0; j < num_derivatives; j++)
+    {
+      combinations[j] = new unsigned int [n];
+      for (unsigned int k = 0; k < n; k++)
+        combinations[j][k] = 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] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
+    
+    // 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
+    for (unsigned int j = 0; j < 1*num_derivatives; j++)
+      values[j] = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+    const double psitilde_bs_1_0 = 1;
+    const double psitilde_bs_1_1 = 2.5*y + 1.5;
+    const double psitilde_bs_2_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+    const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+    const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[6][6] = \
+    {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+    {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+    {0, 0, 0.2, 0, 0, 0.163299316185545},
+    {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+    {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+    {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+    // Interesting (new) part
+    // Tables of derivatives of the polynomial base (transpose)
+    static const double dmats0[6][6] = \
+    {{0, 0, 0, 0, 0, 0},
+    {4.89897948556636, 0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0},
+    {0, 9.48683298050514, 0, 0, 0, 0},
+    {4, 0, 7.07106781186548, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0}};
+    
+    static const double dmats1[6][6] = \
+    {{0, 0, 0, 0, 0, 0},
+    {2.44948974278318, 0, 0, 0, 0, 0},
+    {4.24264068711928, 0, 0, 0, 0, 0},
+    {2.58198889747161, 4.74341649025257, -0.912870929175277, 0, 0, 0},
+    {2, 6.12372435695795, 3.53553390593274, 0, 0, 0},
+    {-2.3094010767585, 0, 8.16496580927726, 0, 0, 0}};
+    
+    // Compute reference derivatives
+    // Declare pointer to array of derivatives on FIAT element
+    double *derivatives = new double [num_derivatives];
+    
+    // Declare coefficients
+    double coeff0_0 = 0;
+    double coeff0_1 = 0;
+    double coeff0_2 = 0;
+    double coeff0_3 = 0;
+    double coeff0_4 = 0;
+    double coeff0_5 = 0;
+    
+    // Declare new coefficients
+    double new_coeff0_0 = 0;
+    double new_coeff0_1 = 0;
+    double new_coeff0_2 = 0;
+    double new_coeff0_3 = 0;
+    double new_coeff0_4 = 0;
+    double new_coeff0_5 = 0;
+    
+    // Loop possible derivatives
+    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+    {
+      // Get values from coefficients array
+      new_coeff0_0 = coefficients0[dof][0];
+      new_coeff0_1 = coefficients0[dof][1];
+      new_coeff0_2 = coefficients0[dof][2];
+      new_coeff0_3 = coefficients0[dof][3];
+      new_coeff0_4 = coefficients0[dof][4];
+      new_coeff0_5 = coefficients0[dof][5];
+    
+      // Loop derivative order
+      for (unsigned int j = 0; j < n; j++)
+      {
+        // Update old coefficients
+        coeff0_0 = new_coeff0_0;
+        coeff0_1 = new_coeff0_1;
+        coeff0_2 = new_coeff0_2;
+        coeff0_3 = new_coeff0_3;
+        coeff0_4 = new_coeff0_4;
+        coeff0_5 = new_coeff0_5;
+    
+        if(combinations[deriv_num][j] == 0)
+        {
+          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
+          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
+          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
+          new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
+          new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
+          new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
+        }
+        if(combinations[deriv_num][j] == 1)
+        {
+          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
+          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
+          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
+          new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
+          new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
+          new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
+        }
+    
+      }
+      // Compute derivatives on reference element as dot product of coefficients and basisvalues
+      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
+    }
+    
+    // Transform derivatives back to physical element
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      for (unsigned int col = 0; col < num_derivatives; col++)
+      {
+        values[row] += transform[row][col]*derivatives[col];
+      }
+    }
+    // Delete pointer to array of derivatives on FIAT element
+    delete [] derivatives;
+    
+    // Delete pointer to array of combinations of derivatives and transform
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      delete [] combinations[row];
+      delete [] transform[row];
+    }
+    
+    delete [] combinations;
+    delete [] transform;
+}
+
+/// Evaluate order n derivatives of all basis functions at given point in cell
+void projection_1_finite_element_1_0::evaluate_basis_derivatives_all(unsigned int n,
+                                                   double* values,
+                                                   const double* coordinates,
+                                                   const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
+}
+
+/// Evaluate linear functional for dof i on the function f
+double projection_1_finite_element_1_0::evaluate_dof(unsigned int i,
+                                   const ufc::function& f,
+                                   const ufc::cell& c) const
+{
+    // The reference points, direction and weights:
+    static const double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}};
+    static const double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
+    static const double D[6][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}, {{1}}, {{1}}};
+    
+    const double * const * x = c.coordinates;
+    double result = 0.0;
+    // Iterate over the points:
+    // Evaluate basis functions for affine mapping
+    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    
+    // Compute affine mapping y = F(X)
+    double y[2];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
+    
+    // Evaluate function at physical points
+    double values[1];
+    f.evaluate(values, y, c);
+    
+    // Map function values using appropriate mapping
+    // Affine map: Do nothing
+    
+    // Note that we do not map the weights (yet).
+    
+    // Take directional components
+    for(int k = 0; k < 1; k++)
+      result += values[k]*D[i][0][k];
+    // Multiply by weights
+    result *= W[i][0];
+    
+    return result;
+}
+
+/// Evaluate linear functionals for all dofs on the function f
+void projection_1_finite_element_1_0::evaluate_dofs(double* values,
+                                  const ufc::function& f,
+                                  const ufc::cell& c) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Interpolate vertex values from dof values
+void projection_1_finite_element_1_0::interpolate_vertex_values(double* vertex_values,
+                                              const double* dof_values,
+                                              const ufc::cell& c) const
+{
+    // Evaluate at vertices and use affine mapping
+    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)
+unsigned int projection_1_finite_element_1_0::num_sub_elements() const
+{
+    return 1;
+}
+
+/// Create a new finite element for sub element i (for a mixed element)
+ufc::finite_element* projection_1_finite_element_1_0::create_sub_element(unsigned int i) const
+{
+    return new projection_1_finite_element_1_0();
+}
+
+
+/// Constructor
+projection_1_finite_element_1_1::projection_1_finite_element_1_1() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+projection_1_finite_element_1_1::~projection_1_finite_element_1_1()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* projection_1_finite_element_1_1::signature() const
+{
+    return "FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
+}
+
+/// Return the cell shape
+ufc::shape projection_1_finite_element_1_1::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int projection_1_finite_element_1_1::space_dimension() const
+{
+    return 6;
+}
+
+/// Return the rank of the value space
+unsigned int projection_1_finite_element_1_1::value_rank() const
+{
+    return 0;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int projection_1_finite_element_1_1::value_dimension(unsigned int i) const
+{
+    return 1;
+}
+
+/// Evaluate basis function i at given point in cell
+void projection_1_finite_element_1_1::evaluate_basis(unsigned int i,
+                                   double* values,
+                                   const double* coordinates,
+                                   const ufc::cell& c) const
+{
+    // Extract vertex coordinates
+    const double * const * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Reset values
+    *values = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+    const double psitilde_bs_1_0 = 1;
+    const double psitilde_bs_1_1 = 2.5*y + 1.5;
+    const double psitilde_bs_2_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+    const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+    const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[6][6] = \
+    {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+    {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+    {0, 0, 0.2, 0, 0, 0.163299316185545},
+    {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+    {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+    {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+    // Extract relevant coefficients
+    const double coeff0_0 = coefficients0[dof][0];
+    const double coeff0_1 = coefficients0[dof][1];
+    const double coeff0_2 = coefficients0[dof][2];
+    const double coeff0_3 = coefficients0[dof][3];
+    const double coeff0_4 = coefficients0[dof][4];
+    const double coeff0_5 = coefficients0[dof][5];
+    
+    // Compute value(s)
+    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
+}
+
+/// Evaluate all basis functions at given point in cell
+void projection_1_finite_element_1_1::evaluate_basis_all(double* values,
+                                       const double* coordinates,
+                                       const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
+}
+
+/// Evaluate order n derivatives of basis function i at given point in cell
+void projection_1_finite_element_1_1::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 * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 2;
+    
+    
+    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
+    unsigned int **combinations = new unsigned int *[num_derivatives];
+    
+    for (unsigned int j = 0; j < num_derivatives; j++)
+    {
+      combinations[j] = new unsigned int [n];
+      for (unsigned int k = 0; k < n; k++)
+        combinations[j][k] = 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] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
+    
+    // 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
+    for (unsigned int j = 0; j < 1*num_derivatives; j++)
+      values[j] = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+    const double psitilde_bs_1_0 = 1;
+    const double psitilde_bs_1_1 = 2.5*y + 1.5;
+    const double psitilde_bs_2_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+    const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+    const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[6][6] = \
+    {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+    {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+    {0, 0, 0.2, 0, 0, 0.163299316185545},
+    {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+    {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+    {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+    // Interesting (new) part
+    // Tables of derivatives of the polynomial base (transpose)
+    static const double dmats0[6][6] = \
+    {{0, 0, 0, 0, 0, 0},
+    {4.89897948556636, 0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0},
+    {0, 9.48683298050514, 0, 0, 0, 0},
+    {4, 0, 7.07106781186548, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0}};
+    
+    static const double dmats1[6][6] = \
+    {{0, 0, 0, 0, 0, 0},
+    {2.44948974278318, 0, 0, 0, 0, 0},
+    {4.24264068711928, 0, 0, 0, 0, 0},
+    {2.58198889747161, 4.74341649025257, -0.912870929175277, 0, 0, 0},
+    {2, 6.12372435695795, 3.53553390593274, 0, 0, 0},
+    {-2.3094010767585, 0, 8.16496580927726, 0, 0, 0}};
+    
+    // Compute reference derivatives
+    // Declare pointer to array of derivatives on FIAT element
+    double *derivatives = new double [num_derivatives];
+    
+    // Declare coefficients
+    double coeff0_0 = 0;
+    double coeff0_1 = 0;
+    double coeff0_2 = 0;
+    double coeff0_3 = 0;
+    double coeff0_4 = 0;
+    double coeff0_5 = 0;
+    
+    // Declare new coefficients
+    double new_coeff0_0 = 0;
+    double new_coeff0_1 = 0;
+    double new_coeff0_2 = 0;
+    double new_coeff0_3 = 0;
+    double new_coeff0_4 = 0;
+    double new_coeff0_5 = 0;
+    
+    // Loop possible derivatives
+    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+    {
+      // Get values from coefficients array
+      new_coeff0_0 = coefficients0[dof][0];
+      new_coeff0_1 = coefficients0[dof][1];
+      new_coeff0_2 = coefficients0[dof][2];
+      new_coeff0_3 = coefficients0[dof][3];
+      new_coeff0_4 = coefficients0[dof][4];
+      new_coeff0_5 = coefficients0[dof][5];
+    
+      // Loop derivative order
+      for (unsigned int j = 0; j < n; j++)
+      {
+        // Update old coefficients
+        coeff0_0 = new_coeff0_0;
+        coeff0_1 = new_coeff0_1;
+        coeff0_2 = new_coeff0_2;
+        coeff0_3 = new_coeff0_3;
+        coeff0_4 = new_coeff0_4;
+        coeff0_5 = new_coeff0_5;
+    
+        if(combinations[deriv_num][j] == 0)
+        {
+          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
+          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
+          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
+          new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
+          new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
+          new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
+        }
+        if(combinations[deriv_num][j] == 1)
+        {
+          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
+          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
+          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
+          new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
+          new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
+          new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
+        }
+    
+      }
+      // Compute derivatives on reference element as dot product of coefficients and basisvalues
+      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
+    }
+    
+    // Transform derivatives back to physical element
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      for (unsigned int col = 0; col < num_derivatives; col++)
+      {
+        values[row] += transform[row][col]*derivatives[col];
+      }
+    }
+    // Delete pointer to array of derivatives on FIAT element
+    delete [] derivatives;
+    
+    // Delete pointer to array of combinations of derivatives and transform
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      delete [] combinations[row];
+      delete [] transform[row];
+    }
+    
+    delete [] combinations;
+    delete [] transform;
+}
+
+/// Evaluate order n derivatives of all basis functions at given point in cell
+void projection_1_finite_element_1_1::evaluate_basis_derivatives_all(unsigned int n,
+                                                   double* values,
+                                                   const double* coordinates,
+                                                   const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
+}
+
+/// Evaluate linear functional for dof i on the function f
+double projection_1_finite_element_1_1::evaluate_dof(unsigned int i,
+                                   const ufc::function& f,
+                                   const ufc::cell& c) const
+{
+    // The reference points, direction and weights:
+    static const double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}};
+    static const double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
+    static const double D[6][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}, {{1}}, {{1}}};
+    
+    const double * const * x = c.coordinates;
+    double result = 0.0;
+    // Iterate over the points:
+    // Evaluate basis functions for affine mapping
+    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    
+    // Compute affine mapping y = F(X)
+    double y[2];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
+    
+    // Evaluate function at physical points
+    double values[1];
+    f.evaluate(values, y, c);
+    
+    // Map function values using appropriate mapping
+    // Affine map: Do nothing
+    
+    // Note that we do not map the weights (yet).
+    
+    // Take directional components
+    for(int k = 0; k < 1; k++)
+      result += values[k]*D[i][0][k];
+    // Multiply by weights
+    result *= W[i][0];
+    
+    return result;
+}
+
+/// Evaluate linear functionals for all dofs on the function f
+void projection_1_finite_element_1_1::evaluate_dofs(double* values,
+                                  const ufc::function& f,
+                                  const ufc::cell& c) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Interpolate vertex values from dof values
+void projection_1_finite_element_1_1::interpolate_vertex_values(double* vertex_values,
+                                              const double* dof_values,
+                                              const ufc::cell& c) const
+{
+    // Evaluate at vertices and use affine mapping
+    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)
+unsigned int projection_1_finite_element_1_1::num_sub_elements() const
+{
+    return 1;
+}
+
+/// Create a new finite element for sub element i (for a mixed element)
+ufc::finite_element* projection_1_finite_element_1_1::create_sub_element(unsigned int i) const
+{
+    return new projection_1_finite_element_1_1();
+}
+
+
+/// Constructor
+projection_1_finite_element_1::projection_1_finite_element_1() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+projection_1_finite_element_1::~projection_1_finite_element_1()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* projection_1_finite_element_1::signature() const
+{
+    return "VectorElement('Lagrange', Cell('triangle', 1, Space(2)), 2, 2)";
+}
+
+/// Return the cell shape
+ufc::shape projection_1_finite_element_1::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int projection_1_finite_element_1::space_dimension() const
+{
+    return 12;
+}
+
+/// Return the rank of the value space
+unsigned int projection_1_finite_element_1::value_rank() const
+{
+    return 1;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int projection_1_finite_element_1::value_dimension(unsigned int i) const
+{
+    return 2;
+}
+
+/// Evaluate basis function i at given point in cell
+void projection_1_finite_element_1::evaluate_basis(unsigned int i,
+                                   double* values,
+                                   const double* coordinates,
+                                   const ufc::cell& c) const
+{
+    // Extract vertex coordinates
+    const double * const * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Reset values
+    values[0] = 0;
+    values[1] = 0;
+    
+    if (0 <= i && i <= 5)
+    {
+      // Map degree of freedom to element degree of freedom
+      const unsigned int dof = i;
+    
+      // Generate scalings
+      const double scalings_y_0 = 1;
+      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+      const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+      // Compute psitilde_a
+      const double psitilde_a_0 = 1;
+      const double psitilde_a_1 = x;
+      const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+      // Compute psitilde_bs
+      const double psitilde_bs_0_0 = 1;
+      const double psitilde_bs_0_1 = 1.5*y + 0.5;
+      const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+      const double psitilde_bs_1_0 = 1;
+      const double psitilde_bs_1_1 = 2.5*y + 1.5;
+      const double psitilde_bs_2_0 = 1;
+    
+      // Compute basisvalues
+      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+      const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+      const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+      const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+      // Table(s) of coefficients
+      static const double coefficients0[6][6] =   \
+      {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+      {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+      {0, 0, 0.2, 0, 0, 0.163299316185545},
+      {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+      {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+      {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+      // Extract relevant coefficients
+      const double coeff0_0 =   coefficients0[dof][0];
+      const double coeff0_1 =   coefficients0[dof][1];
+      const double coeff0_2 =   coefficients0[dof][2];
+      const double coeff0_3 =   coefficients0[dof][3];
+      const double coeff0_4 =   coefficients0[dof][4];
+      const double coeff0_5 =   coefficients0[dof][5];
+    
+      // Compute value(s)
+      values[0] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
+    }
+    
+    if (6 <= i && i <= 11)
+    {
+      // Map degree of freedom to element degree of freedom
+      const unsigned int dof = i - 6;
+    
+      // Generate scalings
+      const double scalings_y_0 = 1;
+      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+      const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+      // Compute psitilde_a
+      const double psitilde_a_0 = 1;
+      const double psitilde_a_1 = x;
+      const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+      // Compute psitilde_bs
+      const double psitilde_bs_0_0 = 1;
+      const double psitilde_bs_0_1 = 1.5*y + 0.5;
+      const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+      const double psitilde_bs_1_0 = 1;
+      const double psitilde_bs_1_1 = 2.5*y + 1.5;
+      const double psitilde_bs_2_0 = 1;
+    
+      // Compute basisvalues
+      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+      const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+      const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+      const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+      // Table(s) of coefficients
+      static const double coefficients0[6][6] =   \
+      {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+      {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+      {0, 0, 0.2, 0, 0, 0.163299316185545},
+      {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+      {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+      {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+      // Extract relevant coefficients
+      const double coeff0_0 =   coefficients0[dof][0];
+      const double coeff0_1 =   coefficients0[dof][1];
+      const double coeff0_2 =   coefficients0[dof][2];
+      const double coeff0_3 =   coefficients0[dof][3];
+      const double coeff0_4 =   coefficients0[dof][4];
+      const double coeff0_5 =   coefficients0[dof][5];
+    
+      // Compute value(s)
+      values[1] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
+    }
+    
+}
+
+/// Evaluate all basis functions at given point in cell
+void projection_1_finite_element_1::evaluate_basis_all(double* values,
+                                       const double* coordinates,
+                                       const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
+}
+
+/// Evaluate order n derivatives of basis function i at given point in cell
+void projection_1_finite_element_1::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 * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 2;
+    
+    
+    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
+    unsigned int **combinations = new unsigned int *[num_derivatives];
+    
+    for (unsigned int j = 0; j < num_derivatives; j++)
+    {
+      combinations[j] = new unsigned int [n];
+      for (unsigned int k = 0; k < n; k++)
+        combinations[j][k] = 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] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
+    
+    // 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
+    for (unsigned int j = 0; j < 2*num_derivatives; j++)
+      values[j] = 0;
+    
+    if (0 <= i && i <= 5)
+    {
+      // Map degree of freedom to element degree of freedom
+      const unsigned int dof = i;
+    
+      // Generate scalings
+      const double scalings_y_0 = 1;
+      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+      const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+      // Compute psitilde_a
+      const double psitilde_a_0 = 1;
+      const double psitilde_a_1 = x;
+      const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+      // Compute psitilde_bs
+      const double psitilde_bs_0_0 = 1;
+      const double psitilde_bs_0_1 = 1.5*y + 0.5;
+      const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+      const double psitilde_bs_1_0 = 1;
+      const double psitilde_bs_1_1 = 2.5*y + 1.5;
+      const double psitilde_bs_2_0 = 1;
+    
+      // Compute basisvalues
+      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+      const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+      const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+      const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+      // Table(s) of coefficients
+      static const double coefficients0[6][6] =   \
+      {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+      {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+      {0, 0, 0.2, 0, 0, 0.163299316185545},
+      {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+      {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+      {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+      // Interesting (new) part
+      // Tables of derivatives of the polynomial base (transpose)
+      static const double dmats0[6][6] =   \
+      {{0, 0, 0, 0, 0, 0},
+      {4.89897948556636, 0, 0, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0},
+      {0, 9.48683298050514, 0, 0, 0, 0},
+      {4, 0, 7.07106781186548, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0}};
+    
+      static const double dmats1[6][6] =   \
+      {{0, 0, 0, 0, 0, 0},
+      {2.44948974278318, 0, 0, 0, 0, 0},
+      {4.24264068711928, 0, 0, 0, 0, 0},
+      {2.58198889747161, 4.74341649025257, -0.912870929175277, 0, 0, 0},
+      {2, 6.12372435695795, 3.53553390593274, 0, 0, 0},
+      {-2.3094010767585, 0, 8.16496580927726, 0, 0, 0}};
+    
+      // Compute reference derivatives
+      // Declare pointer to array of derivatives on FIAT element
+      double *derivatives = new double [num_derivatives];
+    
+      // Declare coefficients
+      double coeff0_0 = 0;
+      double coeff0_1 = 0;
+      double coeff0_2 = 0;
+      double coeff0_3 = 0;
+      double coeff0_4 = 0;
+      double coeff0_5 = 0;
+    
+      // Declare new coefficients
+      double new_coeff0_0 = 0;
+      double new_coeff0_1 = 0;
+      double new_coeff0_2 = 0;
+      double new_coeff0_3 = 0;
+      double new_coeff0_4 = 0;
+      double new_coeff0_5 = 0;
+    
+      // Loop possible derivatives
+      for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+      {
+        // Get values from coefficients array
+        new_coeff0_0 = coefficients0[dof][0];
+        new_coeff0_1 = coefficients0[dof][1];
+        new_coeff0_2 = coefficients0[dof][2];
+        new_coeff0_3 = coefficients0[dof][3];
+        new_coeff0_4 = coefficients0[dof][4];
+        new_coeff0_5 = coefficients0[dof][5];
+    
+        // Loop derivative order
+        for (unsigned int j = 0; j < n; j++)
+        {
+          // Update old coefficients
+          coeff0_0 = new_coeff0_0;
+          coeff0_1 = new_coeff0_1;
+          coeff0_2 = new_coeff0_2;
+          coeff0_3 = new_coeff0_3;
+          coeff0_4 = new_coeff0_4;
+          coeff0_5 = new_coeff0_5;
+    
+          if(combinations[deriv_num][j] == 0)
+          {
+            new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
+            new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
+            new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
+            new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
+            new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
+            new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
+          }
+          if(combinations[deriv_num][j] == 1)
+          {
+            new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
+            new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
+            new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
+            new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
+            new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
+            new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
+          }
+    
+        }
+        // Compute derivatives on reference element as dot product of coefficients and basisvalues
+        derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
+      }
+    
+      // Transform derivatives back to physical element
+      for (unsigned int row = 0; row < num_derivatives; row++)
+      {
+        for (unsigned int col = 0; col < num_derivatives; col++)
+        {
+          values[row] += transform[row][col]*derivatives[col];
+        }
+      }
+      // Delete pointer to array of derivatives on FIAT element
+      delete [] derivatives;
+    
+      // Delete pointer to array of combinations of derivatives and transform
+      for (unsigned int row = 0; row < num_derivatives; row++)
+      {
+        delete [] combinations[row];
+        delete [] transform[row];
+      }
+    
+      delete [] combinations;
+      delete [] transform;
+    }
+    
+    if (6 <= i && i <= 11)
+    {
+      // Map degree of freedom to element degree of freedom
+      const unsigned int dof = i - 6;
+    
+      // Generate scalings
+      const double scalings_y_0 = 1;
+      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+      const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+      // Compute psitilde_a
+      const double psitilde_a_0 = 1;
+      const double psitilde_a_1 = x;
+      const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+      // Compute psitilde_bs
+      const double psitilde_bs_0_0 = 1;
+      const double psitilde_bs_0_1 = 1.5*y + 0.5;
+      const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+      const double psitilde_bs_1_0 = 1;
+      const double psitilde_bs_1_1 = 2.5*y + 1.5;
+      const double psitilde_bs_2_0 = 1;
+    
+      // Compute basisvalues
+      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+      const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+      const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+      const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+      // Table(s) of coefficients
+      static const double coefficients0[6][6] =   \
+      {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+      {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+      {0, 0, 0.2, 0, 0, 0.163299316185545},
+      {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+      {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+      {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+      // Interesting (new) part
+      // Tables of derivatives of the polynomial base (transpose)
+      static const double dmats0[6][6] =   \
+      {{0, 0, 0, 0, 0, 0},
+      {4.89897948556636, 0, 0, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0},
+      {0, 9.48683298050514, 0, 0, 0, 0},
+      {4, 0, 7.07106781186548, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0}};
+    
+      static const double dmats1[6][6] =   \
+      {{0, 0, 0, 0, 0, 0},
+      {2.44948974278318, 0, 0, 0, 0, 0},
+      {4.24264068711928, 0, 0, 0, 0, 0},
+      {2.58198889747161, 4.74341649025257, -0.912870929175277, 0, 0, 0},
+      {2, 6.12372435695795, 3.53553390593274, 0, 0, 0},
+      {-2.3094010767585, 0, 8.16496580927726, 0, 0, 0}};
+    
+      // Compute reference derivatives
+      // Declare pointer to array of derivatives on FIAT element
+      double *derivatives = new double [num_derivatives];
+    
+      // Declare coefficients
+      double coeff0_0 = 0;
+      double coeff0_1 = 0;
+      double coeff0_2 = 0;
+      double coeff0_3 = 0;
+      double coeff0_4 = 0;
+      double coeff0_5 = 0;
+    
+      // Declare new coefficients
+      double new_coeff0_0 = 0;
+      double new_coeff0_1 = 0;
+      double new_coeff0_2 = 0;
+      double new_coeff0_3 = 0;
+      double new_coeff0_4 = 0;
+      double new_coeff0_5 = 0;
+    
+      // Loop possible derivatives
+      for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+      {
+        // Get values from coefficients array
+        new_coeff0_0 = coefficients0[dof][0];
+        new_coeff0_1 = coefficients0[dof][1];
+        new_coeff0_2 = coefficients0[dof][2];
+        new_coeff0_3 = coefficients0[dof][3];
+        new_coeff0_4 = coefficients0[dof][4];
+        new_coeff0_5 = coefficients0[dof][5];
+    
+        // Loop derivative order
+        for (unsigned int j = 0; j < n; j++)
+        {
+          // Update old coefficients
+          coeff0_0 = new_coeff0_0;
+          coeff0_1 = new_coeff0_1;
+          coeff0_2 = new_coeff0_2;
+          coeff0_3 = new_coeff0_3;
+          coeff0_4 = new_coeff0_4;
+          coeff0_5 = new_coeff0_5;
+    
+          if(combinations[deriv_num][j] == 0)
+          {
+            new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
+            new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
+            new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
+            new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
+            new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
+            new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
+          }
+          if(combinations[deriv_num][j] == 1)
+          {
+            new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
+            new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
+            new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
+            new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
+            new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
+            new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
+          }
+    
+        }
+        // Compute derivatives on reference element as dot product of coefficients and basisvalues
+        derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
+      }
+    
+      // Transform derivatives back to physical element
+      for (unsigned int row = 0; row < num_derivatives; row++)
+      {
+        for (unsigned int col = 0; col < num_derivatives; col++)
+        {
+          values[num_derivatives + row] += transform[row][col]*derivatives[col];
+        }
+      }
+      // Delete pointer to array of derivatives on FIAT element
+      delete [] derivatives;
+    
+      // Delete pointer to array of combinations of derivatives and transform
+      for (unsigned int row = 0; row < num_derivatives; row++)
+      {
+        delete [] combinations[row];
+        delete [] transform[row];
+      }
+    
+      delete [] combinations;
+      delete [] transform;
+    }
+    
+}
+
+/// Evaluate order n derivatives of all basis functions at given point in cell
+void projection_1_finite_element_1::evaluate_basis_derivatives_all(unsigned int n,
+                                                   double* values,
+                                                   const double* coordinates,
+                                                   const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
+}
+
+/// Evaluate linear functional for dof i on the function f
+double projection_1_finite_element_1::evaluate_dof(unsigned int i,
+                                   const ufc::function& f,
+                                   const ufc::cell& c) const
+{
+    // The reference points, direction and weights:
+    static const double X[12][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}, {{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}};
+    static const double W[12][1] = {{1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}};
+    static const double D[12][1][2] = {{{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{0, 1}}, {{0, 1}}, {{0, 1}}, {{0, 1}}, {{0, 1}}, {{0, 1}}};
+    
+    const double * const * x = c.coordinates;
+    double result = 0.0;
+    // Iterate over the points:
+    // Evaluate basis functions for affine mapping
+    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    
+    // Compute affine mapping y = F(X)
+    double y[2];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
+    
+    // Evaluate function at physical points
+    double values[2];
+    f.evaluate(values, y, c);
+    
+    // Map function values using appropriate mapping
+    // Affine map: Do nothing
+    
+    // Note that we do not map the weights (yet).
+    
+    // Take directional components
+    for(int k = 0; k < 2; k++)
+      result += values[k]*D[i][0][k];
+    // Multiply by weights
+    result *= W[i][0];
+    
+    return result;
+}
+
+/// Evaluate linear functionals for all dofs on the function f
+void projection_1_finite_element_1::evaluate_dofs(double* values,
+                                  const ufc::function& f,
+                                  const ufc::cell& c) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Interpolate vertex values from dof values
+void projection_1_finite_element_1::interpolate_vertex_values(double* vertex_values,
+                                              const double* dof_values,
+                                              const ufc::cell& c) const
+{
+    // Evaluate at vertices and use affine mapping
+    vertex_values[0] = dof_values[0];
+    vertex_values[2] = dof_values[1];
+    vertex_values[4] = dof_values[2];
+    // Evaluate at vertices and use affine mapping
+    vertex_values[1] = dof_values[6];
+    vertex_values[3] = dof_values[7];
+    vertex_values[5] = dof_values[8];
+}
+
+/// Return the number of sub elements (for a mixed element)
+unsigned int projection_1_finite_element_1::num_sub_elements() const
+{
+    return 2;
+}
+
+/// Create a new finite element for sub element i (for a mixed element)
+ufc::finite_element* projection_1_finite_element_1::create_sub_element(unsigned int i) const
+{
+    switch ( i )
+    {
+    case 0:
+      return new projection_1_finite_element_1_0();
+      break;
+    case 1:
+      return new projection_1_finite_element_1_1();
+      break;
+    }
+    return 0;
+}
+
+/// Constructor
+projection_1_dof_map_0_0::projection_1_dof_map_0_0() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+projection_1_dof_map_0_0::~projection_1_dof_map_0_0()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* projection_1_dof_map_0_0::signature() const
+{
+    return "FFC dof map for FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool projection_1_dof_map_0_0::needs_mesh_entities(unsigned int d) const
+{
+    switch ( d )
+    {
+    case 0:
+      return true;
+      break;
+    case 1:
+      return true;
+      break;
+    case 2:
+      return false;
+      break;
+    }
+    return false;
+}
+
+/// Initialize dof map for mesh (return true iff init_cell() is needed)
+bool projection_1_dof_map_0_0::init_mesh(const ufc::mesh& m)
+{
+    __global_dimension = m.num_entities[0] + m.num_entities[1];
+    return false;
+}
+
+/// Initialize dof map for given cell
+void projection_1_dof_map_0_0::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void projection_1_dof_map_0_0::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int projection_1_dof_map_0_0::global_dimension() const
+{
+    return __global_dimension;
+}
+
+/// Return the dimension of the local finite element function space for a cell
+unsigned int projection_1_dof_map_0_0::local_dimension(const ufc::cell& c) const
+{
+    return 6;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int projection_1_dof_map_0_0::max_local_dimension() const
+{
+    return 6;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int projection_1_dof_map_0_0::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int projection_1_dof_map_0_0::num_facet_dofs() const
+{
+    return 3;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int projection_1_dof_map_0_0::num_entity_dofs(unsigned int d) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the local-to-global mapping of dofs on a cell
+void projection_1_dof_map_0_0::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];
+    unsigned int offset = m.num_entities[0];
+    dofs[3] = offset + c.entity_indices[1][0];
+    dofs[4] = offset + c.entity_indices[1][1];
+    dofs[5] = offset + c.entity_indices[1][2];
+}
+
+/// Tabulate the local-to-local mapping from facet dofs to cell dofs
+void projection_1_dof_map_0_0::tabulate_facet_dofs(unsigned int* dofs,
+                                        unsigned int facet) const
+{
+    switch ( facet )
+    {
+    case 0:
+      dofs[0] = 1;
+      dofs[1] = 2;
+      dofs[2] = 3;
+      break;
+    case 1:
+      dofs[0] = 0;
+      dofs[1] = 2;
+      dofs[2] = 4;
+      break;
+    case 2:
+      dofs[0] = 0;
+      dofs[1] = 1;
+      dofs[2] = 5;
+      break;
+    }
+}
+
+/// Tabulate the local-to-local mapping of dofs on entity (d, i)
+void projection_1_dof_map_0_0::tabulate_entity_dofs(unsigned int* dofs,
+                                  unsigned int d, unsigned int i) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the coordinates of all dofs on a cell
+void projection_1_dof_map_0_0::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];
+    coordinates[3][0] = 0.5*x[1][0] + 0.5*x[2][0];
+    coordinates[3][1] = 0.5*x[1][1] + 0.5*x[2][1];
+    coordinates[4][0] = 0.5*x[0][0] + 0.5*x[2][0];
+    coordinates[4][1] = 0.5*x[0][1] + 0.5*x[2][1];
+    coordinates[5][0] = 0.5*x[0][0] + 0.5*x[1][0];
+    coordinates[5][1] = 0.5*x[0][1] + 0.5*x[1][1];
+}
+
+/// Return the number of sub dof maps (for a mixed element)
+unsigned int projection_1_dof_map_0_0::num_sub_dof_maps() const
+{
+    return 1;
+}
+
+/// Create a new dof_map for sub dof map i (for a mixed element)
+ufc::dof_map* projection_1_dof_map_0_0::create_sub_dof_map(unsigned int i) const
+{
+    return new projection_1_dof_map_0_0();
+}
+
+
+/// Constructor
+projection_1_dof_map_0_1::projection_1_dof_map_0_1() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+projection_1_dof_map_0_1::~projection_1_dof_map_0_1()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* projection_1_dof_map_0_1::signature() const
+{
+    return "FFC dof map for FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool projection_1_dof_map_0_1::needs_mesh_entities(unsigned int d) const
+{
+    switch ( d )
+    {
+    case 0:
+      return true;
+      break;
+    case 1:
+      return true;
+      break;
+    case 2:
+      return false;
+      break;
+    }
+    return false;
+}
+
+/// Initialize dof map for mesh (return true iff init_cell() is needed)
+bool projection_1_dof_map_0_1::init_mesh(const ufc::mesh& m)
+{
+    __global_dimension = m.num_entities[0] + m.num_entities[1];
+    return false;
+}
+
+/// Initialize dof map for given cell
+void projection_1_dof_map_0_1::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void projection_1_dof_map_0_1::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int projection_1_dof_map_0_1::global_dimension() const
+{
+    return __global_dimension;
+}
+
+/// Return the dimension of the local finite element function space for a cell
+unsigned int projection_1_dof_map_0_1::local_dimension(const ufc::cell& c) const
+{
+    return 6;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int projection_1_dof_map_0_1::max_local_dimension() const
+{
+    return 6;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int projection_1_dof_map_0_1::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int projection_1_dof_map_0_1::num_facet_dofs() const
+{
+    return 3;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int projection_1_dof_map_0_1::num_entity_dofs(unsigned int d) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the local-to-global mapping of dofs on a cell
+void projection_1_dof_map_0_1::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];
+    unsigned int offset = m.num_entities[0];
+    dofs[3] = offset + c.entity_indices[1][0];
+    dofs[4] = offset + c.entity_indices[1][1];
+    dofs[5] = offset + c.entity_indices[1][2];
+}
+
+/// Tabulate the local-to-local mapping from facet dofs to cell dofs
+void projection_1_dof_map_0_1::tabulate_facet_dofs(unsigned int* dofs,
+                                        unsigned int facet) const
+{
+    switch ( facet )
+    {
+    case 0:
+      dofs[0] = 1;
+      dofs[1] = 2;
+      dofs[2] = 3;
+      break;
+    case 1:
+      dofs[0] = 0;
+      dofs[1] = 2;
+      dofs[2] = 4;
+      break;
+    case 2:
+      dofs[0] = 0;
+      dofs[1] = 1;
+      dofs[2] = 5;
+      break;
+    }
+}
+
+/// Tabulate the local-to-local mapping of dofs on entity (d, i)
+void projection_1_dof_map_0_1::tabulate_entity_dofs(unsigned int* dofs,
+                                  unsigned int d, unsigned int i) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the coordinates of all dofs on a cell
+void projection_1_dof_map_0_1::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];
+    coordinates[3][0] = 0.5*x[1][0] + 0.5*x[2][0];
+    coordinates[3][1] = 0.5*x[1][1] + 0.5*x[2][1];
+    coordinates[4][0] = 0.5*x[0][0] + 0.5*x[2][0];
+    coordinates[4][1] = 0.5*x[0][1] + 0.5*x[2][1];
+    coordinates[5][0] = 0.5*x[0][0] + 0.5*x[1][0];
+    coordinates[5][1] = 0.5*x[0][1] + 0.5*x[1][1];
+}
+
+/// Return the number of sub dof maps (for a mixed element)
+unsigned int projection_1_dof_map_0_1::num_sub_dof_maps() const
+{
+    return 1;
+}
+
+/// Create a new dof_map for sub dof map i (for a mixed element)
+ufc::dof_map* projection_1_dof_map_0_1::create_sub_dof_map(unsigned int i) const
+{
+    return new projection_1_dof_map_0_1();
+}
+
+
+/// Constructor
+projection_1_dof_map_0::projection_1_dof_map_0() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+projection_1_dof_map_0::~projection_1_dof_map_0()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* projection_1_dof_map_0::signature() const
+{
+    return "FFC dof map for VectorElement('Lagrange', Cell('triangle', 1, Space(2)), 2, 2)";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool projection_1_dof_map_0::needs_mesh_entities(unsigned int d) const
+{
+    switch ( d )
+    {
+    case 0:
+      return true;
+      break;
+    case 1:
+      return true;
+      break;
+    case 2:
+      return false;
+      break;
+    }
+    return false;
+}
+
+/// Initialize dof map for mesh (return true iff init_cell() is needed)
+bool projection_1_dof_map_0::init_mesh(const ufc::mesh& m)
+{
+    __global_dimension = 2*m.num_entities[0] + 2*m.num_entities[1];
+    return false;
+}
+
+/// Initialize dof map for given cell
+void projection_1_dof_map_0::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void projection_1_dof_map_0::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int projection_1_dof_map_0::global_dimension() const
+{
+    return __global_dimension;
+}
+
+/// Return the dimension of the local finite element function space for a cell
+unsigned int projection_1_dof_map_0::local_dimension(const ufc::cell& c) const
+{
+    return 12;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int projection_1_dof_map_0::max_local_dimension() const
+{
+    return 12;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int projection_1_dof_map_0::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int projection_1_dof_map_0::num_facet_dofs() const
+{
+    return 6;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int projection_1_dof_map_0::num_entity_dofs(unsigned int d) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the local-to-global mapping of dofs on a cell
+void projection_1_dof_map_0::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];
+    unsigned int offset = m.num_entities[0];
+    dofs[3] = offset + c.entity_indices[1][0];
+    dofs[4] = offset + c.entity_indices[1][1];
+    dofs[5] = offset + c.entity_indices[1][2];
+    offset = offset + m.num_entities[1];
+    dofs[6] = offset + c.entity_indices[0][0];
+    dofs[7] = offset + c.entity_indices[0][1];
+    dofs[8] = offset + c.entity_indices[0][2];
+    offset = offset + m.num_entities[0];
+    dofs[9] = offset + c.entity_indices[1][0];
+    dofs[10] = offset + c.entity_indices[1][1];
+    dofs[11] = offset + c.entity_indices[1][2];
+}
+
+/// Tabulate the local-to-local mapping from facet dofs to cell dofs
+void projection_1_dof_map_0::tabulate_facet_dofs(unsigned int* dofs,
+                                        unsigned int facet) const
+{
+    switch ( facet )
+    {
+    case 0:
+      dofs[0] = 1;
+      dofs[1] = 2;
+      dofs[2] = 3;
+      dofs[3] = 7;
+      dofs[4] = 8;
+      dofs[5] = 9;
+      break;
+    case 1:
+      dofs[0] = 0;
+      dofs[1] = 2;
+      dofs[2] = 4;
+      dofs[3] = 6;
+      dofs[4] = 8;
+      dofs[5] = 10;
+      break;
+    case 2:
+      dofs[0] = 0;
+      dofs[1] = 1;
+      dofs[2] = 5;
+      dofs[3] = 6;
+      dofs[4] = 7;
+      dofs[5] = 11;
+      break;
+    }
+}
+
+/// Tabulate the local-to-local mapping of dofs on entity (d, i)
+void projection_1_dof_map_0::tabulate_entity_dofs(unsigned int* dofs,
+                                  unsigned int d, unsigned int i) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the coordinates of all dofs on a cell
+void projection_1_dof_map_0::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];
+    coordinates[3][0] = 0.5*x[1][0] + 0.5*x[2][0];
+    coordinates[3][1] = 0.5*x[1][1] + 0.5*x[2][1];
+    coordinates[4][0] = 0.5*x[0][0] + 0.5*x[2][0];
+    coordinates[4][1] = 0.5*x[0][1] + 0.5*x[2][1];
+    coordinates[5][0] = 0.5*x[0][0] + 0.5*x[1][0];
+    coordinates[5][1] = 0.5*x[0][1] + 0.5*x[1][1];
+    coordinates[6][0] = x[0][0];
+    coordinates[6][1] = x[0][1];
+    coordinates[7][0] = x[1][0];
+    coordinates[7][1] = x[1][1];
+    coordinates[8][0] = x[2][0];
+    coordinates[8][1] = x[2][1];
+    coordinates[9][0] = 0.5*x[1][0] + 0.5*x[2][0];
+    coordinates[9][1] = 0.5*x[1][1] + 0.5*x[2][1];
+    coordinates[10][0] = 0.5*x[0][0] + 0.5*x[2][0];
+    coordinates[10][1] = 0.5*x[0][1] + 0.5*x[2][1];
+    coordinates[11][0] = 0.5*x[0][0] + 0.5*x[1][0];
+    coordinates[11][1] = 0.5*x[0][1] + 0.5*x[1][1];
+}
+
+/// Return the number of sub dof maps (for a mixed element)
+unsigned int projection_1_dof_map_0::num_sub_dof_maps() const
+{
+    return 2;
+}
+
+/// Create a new dof_map for sub dof map i (for a mixed element)
+ufc::dof_map* projection_1_dof_map_0::create_sub_dof_map(unsigned int i) const
+{
+    switch ( i )
+    {
+    case 0:
+      return new projection_1_dof_map_0_0();
+      break;
+    case 1:
+      return new projection_1_dof_map_0_1();
+      break;
+    }
+    return 0;
+}
+
+
+/// Constructor
+projection_1_dof_map_1_0::projection_1_dof_map_1_0() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+projection_1_dof_map_1_0::~projection_1_dof_map_1_0()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* projection_1_dof_map_1_0::signature() const
+{
+    return "FFC dof map for FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool projection_1_dof_map_1_0::needs_mesh_entities(unsigned int d) const
+{
+    switch ( d )
+    {
+    case 0:
+      return true;
+      break;
+    case 1:
+      return true;
+      break;
+    case 2:
+      return false;
+      break;
+    }
+    return false;
+}
+
+/// Initialize dof map for mesh (return true iff init_cell() is needed)
+bool projection_1_dof_map_1_0::init_mesh(const ufc::mesh& m)
+{
+    __global_dimension = m.num_entities[0] + m.num_entities[1];
+    return false;
+}
+
+/// Initialize dof map for given cell
+void projection_1_dof_map_1_0::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void projection_1_dof_map_1_0::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int projection_1_dof_map_1_0::global_dimension() const
+{
+    return __global_dimension;
+}
+
+/// Return the dimension of the local finite element function space for a cell
+unsigned int projection_1_dof_map_1_0::local_dimension(const ufc::cell& c) const
+{
+    return 6;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int projection_1_dof_map_1_0::max_local_dimension() const
+{
+    return 6;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int projection_1_dof_map_1_0::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int projection_1_dof_map_1_0::num_facet_dofs() const
+{
+    return 3;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int projection_1_dof_map_1_0::num_entity_dofs(unsigned int d) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the local-to-global mapping of dofs on a cell
+void projection_1_dof_map_1_0::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];
+    unsigned int offset = m.num_entities[0];
+    dofs[3] = offset + c.entity_indices[1][0];
+    dofs[4] = offset + c.entity_indices[1][1];
+    dofs[5] = offset + c.entity_indices[1][2];
+}
+
+/// Tabulate the local-to-local mapping from facet dofs to cell dofs
+void projection_1_dof_map_1_0::tabulate_facet_dofs(unsigned int* dofs,
+                                        unsigned int facet) const
+{
+    switch ( facet )
+    {
+    case 0:
+      dofs[0] = 1;
+      dofs[1] = 2;
+      dofs[2] = 3;
+      break;
+    case 1:
+      dofs[0] = 0;
+      dofs[1] = 2;
+      dofs[2] = 4;
+      break;
+    case 2:
+      dofs[0] = 0;
+      dofs[1] = 1;
+      dofs[2] = 5;
+      break;
+    }
+}
+
+/// Tabulate the local-to-local mapping of dofs on entity (d, i)
+void projection_1_dof_map_1_0::tabulate_entity_dofs(unsigned int* dofs,
+                                  unsigned int d, unsigned int i) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the coordinates of all dofs on a cell
+void projection_1_dof_map_1_0::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];
+    coordinates[3][0] = 0.5*x[1][0] + 0.5*x[2][0];
+    coordinates[3][1] = 0.5*x[1][1] + 0.5*x[2][1];
+    coordinates[4][0] = 0.5*x[0][0] + 0.5*x[2][0];
+    coordinates[4][1] = 0.5*x[0][1] + 0.5*x[2][1];
+    coordinates[5][0] = 0.5*x[0][0] + 0.5*x[1][0];
+    coordinates[5][1] = 0.5*x[0][1] + 0.5*x[1][1];
+}
+
+/// Return the number of sub dof maps (for a mixed element)
+unsigned int projection_1_dof_map_1_0::num_sub_dof_maps() const
+{
+    return 1;
+}
+
+/// Create a new dof_map for sub dof map i (for a mixed element)
+ufc::dof_map* projection_1_dof_map_1_0::create_sub_dof_map(unsigned int i) const
+{
+    return new projection_1_dof_map_1_0();
+}
+
+
+/// Constructor
+projection_1_dof_map_1_1::projection_1_dof_map_1_1() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+projection_1_dof_map_1_1::~projection_1_dof_map_1_1()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* projection_1_dof_map_1_1::signature() const
+{
+    return "FFC dof map for FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool projection_1_dof_map_1_1::needs_mesh_entities(unsigned int d) const
+{
+    switch ( d )
+    {
+    case 0:
+      return true;
+      break;
+    case 1:
+      return true;
+      break;
+    case 2:
+      return false;
+      break;
+    }
+    return false;
+}
+
+/// Initialize dof map for mesh (return true iff init_cell() is needed)
+bool projection_1_dof_map_1_1::init_mesh(const ufc::mesh& m)
+{
+    __global_dimension = m.num_entities[0] + m.num_entities[1];
+    return false;
+}
+
+/// Initialize dof map for given cell
+void projection_1_dof_map_1_1::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void projection_1_dof_map_1_1::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int projection_1_dof_map_1_1::global_dimension() const
+{
+    return __global_dimension;
+}
+
+/// Return the dimension of the local finite element function space for a cell
+unsigned int projection_1_dof_map_1_1::local_dimension(const ufc::cell& c) const
+{
+    return 6;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int projection_1_dof_map_1_1::max_local_dimension() const
+{
+    return 6;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int projection_1_dof_map_1_1::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int projection_1_dof_map_1_1::num_facet_dofs() const
+{
+    return 3;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int projection_1_dof_map_1_1::num_entity_dofs(unsigned int d) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the local-to-global mapping of dofs on a cell
+void projection_1_dof_map_1_1::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];
+    unsigned int offset = m.num_entities[0];
+    dofs[3] = offset + c.entity_indices[1][0];
+    dofs[4] = offset + c.entity_indices[1][1];
+    dofs[5] = offset + c.entity_indices[1][2];
+}
+
+/// Tabulate the local-to-local mapping from facet dofs to cell dofs
+void projection_1_dof_map_1_1::tabulate_facet_dofs(unsigned int* dofs,
+                                        unsigned int facet) const
+{
+    switch ( facet )
+    {
+    case 0:
+      dofs[0] = 1;
+      dofs[1] = 2;
+      dofs[2] = 3;
+      break;
+    case 1:
+      dofs[0] = 0;
+      dofs[1] = 2;
+      dofs[2] = 4;
+      break;
+    case 2:
+      dofs[0] = 0;
+      dofs[1] = 1;
+      dofs[2] = 5;
+      break;
+    }
+}
+
+/// Tabulate the local-to-local mapping of dofs on entity (d, i)
+void projection_1_dof_map_1_1::tabulate_entity_dofs(unsigned int* dofs,
+                                  unsigned int d, unsigned int i) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the coordinates of all dofs on a cell
+void projection_1_dof_map_1_1::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];
+    coordinates[3][0] = 0.5*x[1][0] + 0.5*x[2][0];
+    coordinates[3][1] = 0.5*x[1][1] + 0.5*x[2][1];
+    coordinates[4][0] = 0.5*x[0][0] + 0.5*x[2][0];
+    coordinates[4][1] = 0.5*x[0][1] + 0.5*x[2][1];
+    coordinates[5][0] = 0.5*x[0][0] + 0.5*x[1][0];
+    coordinates[5][1] = 0.5*x[0][1] + 0.5*x[1][1];
+}
+
+/// Return the number of sub dof maps (for a mixed element)
+unsigned int projection_1_dof_map_1_1::num_sub_dof_maps() const
+{
+    return 1;
+}
+
+/// Create a new dof_map for sub dof map i (for a mixed element)
+ufc::dof_map* projection_1_dof_map_1_1::create_sub_dof_map(unsigned int i) const
+{
+    return new projection_1_dof_map_1_1();
+}
+
+
+/// Constructor
+projection_1_dof_map_1::projection_1_dof_map_1() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+projection_1_dof_map_1::~projection_1_dof_map_1()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* projection_1_dof_map_1::signature() const
+{
+    return "FFC dof map for VectorElement('Lagrange', Cell('triangle', 1, Space(2)), 2, 2)";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool projection_1_dof_map_1::needs_mesh_entities(unsigned int d) const
+{
+    switch ( d )
+    {
+    case 0:
+      return true;
+      break;
+    case 1:
+      return true;
+      break;
+    case 2:
+      return false;
+      break;
+    }
+    return false;
+}
+
+/// Initialize dof map for mesh (return true iff init_cell() is needed)
+bool projection_1_dof_map_1::init_mesh(const ufc::mesh& m)
+{
+    __global_dimension = 2*m.num_entities[0] + 2*m.num_entities[1];
+    return false;
+}
+
+/// Initialize dof map for given cell
+void projection_1_dof_map_1::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void projection_1_dof_map_1::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int projection_1_dof_map_1::global_dimension() const
+{
+    return __global_dimension;
+}
+
+/// Return the dimension of the local finite element function space for a cell
+unsigned int projection_1_dof_map_1::local_dimension(const ufc::cell& c) const
+{
+    return 12;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int projection_1_dof_map_1::max_local_dimension() const
+{
+    return 12;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int projection_1_dof_map_1::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int projection_1_dof_map_1::num_facet_dofs() const
+{
+    return 6;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int projection_1_dof_map_1::num_entity_dofs(unsigned int d) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the local-to-global mapping of dofs on a cell
+void projection_1_dof_map_1::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];
+    unsigned int offset = m.num_entities[0];
+    dofs[3] = offset + c.entity_indices[1][0];
+    dofs[4] = offset + c.entity_indices[1][1];
+    dofs[5] = offset + c.entity_indices[1][2];
+    offset = offset + m.num_entities[1];
+    dofs[6] = offset + c.entity_indices[0][0];
+    dofs[7] = offset + c.entity_indices[0][1];
+    dofs[8] = offset + c.entity_indices[0][2];
+    offset = offset + m.num_entities[0];
+    dofs[9] = offset + c.entity_indices[1][0];
+    dofs[10] = offset + c.entity_indices[1][1];
+    dofs[11] = offset + c.entity_indices[1][2];
+}
+
+/// Tabulate the local-to-local mapping from facet dofs to cell dofs
+void projection_1_dof_map_1::tabulate_facet_dofs(unsigned int* dofs,
+                                        unsigned int facet) const
+{
+    switch ( facet )
+    {
+    case 0:
+      dofs[0] = 1;
+      dofs[1] = 2;
+      dofs[2] = 3;
+      dofs[3] = 7;
+      dofs[4] = 8;
+      dofs[5] = 9;
+      break;
+    case 1:
+      dofs[0] = 0;
+      dofs[1] = 2;
+      dofs[2] = 4;
+      dofs[3] = 6;
+      dofs[4] = 8;
+      dofs[5] = 10;
+      break;
+    case 2:
+      dofs[0] = 0;
+      dofs[1] = 1;
+      dofs[2] = 5;
+      dofs[3] = 6;
+      dofs[4] = 7;
+      dofs[5] = 11;
+      break;
+    }
+}
+
+/// Tabulate the local-to-local mapping of dofs on entity (d, i)
+void projection_1_dof_map_1::tabulate_entity_dofs(unsigned int* dofs,
+                                  unsigned int d, unsigned int i) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the coordinates of all dofs on a cell
+void projection_1_dof_map_1::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];
+    coordinates[3][0] = 0.5*x[1][0] + 0.5*x[2][0];
+    coordinates[3][1] = 0.5*x[1][1] + 0.5*x[2][1];
+    coordinates[4][0] = 0.5*x[0][0] + 0.5*x[2][0];
+    coordinates[4][1] = 0.5*x[0][1] + 0.5*x[2][1];
+    coordinates[5][0] = 0.5*x[0][0] + 0.5*x[1][0];
+    coordinates[5][1] = 0.5*x[0][1] + 0.5*x[1][1];
+    coordinates[6][0] = x[0][0];
+    coordinates[6][1] = x[0][1];
+    coordinates[7][0] = x[1][0];
+    coordinates[7][1] = x[1][1];
+    coordinates[8][0] = x[2][0];
+    coordinates[8][1] = x[2][1];
+    coordinates[9][0] = 0.5*x[1][0] + 0.5*x[2][0];
+    coordinates[9][1] = 0.5*x[1][1] + 0.5*x[2][1];
+    coordinates[10][0] = 0.5*x[0][0] + 0.5*x[2][0];
+    coordinates[10][1] = 0.5*x[0][1] + 0.5*x[2][1];
+    coordinates[11][0] = 0.5*x[0][0] + 0.5*x[1][0];
+    coordinates[11][1] = 0.5*x[0][1] + 0.5*x[1][1];
+}
+
+/// Return the number of sub dof maps (for a mixed element)
+unsigned int projection_1_dof_map_1::num_sub_dof_maps() const
+{
+    return 2;
+}
+
+/// Create a new dof_map for sub dof map i (for a mixed element)
+ufc::dof_map* projection_1_dof_map_1::create_sub_dof_map(unsigned int i) const
+{
+    switch ( i )
+    {
+    case 0:
+      return new projection_1_dof_map_1_0();
+      break;
+    case 1:
+      return new projection_1_dof_map_1_1();
+      break;
+    }
+    return 0;
+}
+
+
+/// Constructor
+projection_1_cell_integral_0_quadrature::projection_1_cell_integral_0_quadrature() : ufc::cell_integral()
+{
+    // Do nothing
+}
+
+/// Destructor
+projection_1_cell_integral_0_quadrature::~projection_1_cell_integral_0_quadrature()
+{
+    // Do nothing
+}
+
+/// Tabulate the tensor for the contribution from a local cell
+void projection_1_cell_integral_0_quadrature::tabulate_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 W9[9] = {0.0558144204830443, 0.063678085099885, 0.0193963833059595, 0.0893030727728709, 0.101884936159816, 0.0310342132895351, 0.0558144204830443, 0.063678085099885, 0.0193963833059595};
+    // Quadrature points on the UFC reference element: (0.102717654809626, 0.088587959512704), (0.0665540678391645, 0.409466864440735), (0.0239311322870806, 0.787659461760847), (0.455706020243648, 0.088587959512704), (0.295266567779633, 0.409466864440735), (0.106170269119576, 0.787659461760847), (0.80869438567767, 0.088587959512704), (0.523979067720101, 0.409466864440735), (0.188409405952072, 0.787659461760847)
+    
+    // Value of basis functions at quadrature points.
+    static const double FE0_C0[9][6] = \
+    {{0.499278833175498, -0.0816158215904472, -0.072892306371455, 0.0363981897820602, 0.286562341986258, 0.332268763018087},
+    {0.0251290590975511, -0.0576951799472843, -0.0741406382908807, 0.109006741895515, 0.858208263567716, 0.139491753677383},
+    {-0.117413197449647, -0.0227857341019971, 0.453155393641927, 0.0753983311062782, 0.593609805131561, 0.0180354016718773},
+    {-0.0403700664710398, -0.0403700664710398, -0.072892306371455, 0.161480265884159, 0.161480265884159, 0.830671907545216},
+    {-0.120901875682904, -0.120901875682904, -0.0741406382908807, 0.483607502731615, 0.483607502731615, 0.348729384193458},
+    {-0.0836260170297299, -0.0836260170297299, 0.453155393641927, 0.33450406811892, 0.33450406811892, 0.0450885041796933},
+    {-0.0816158215904472, 0.499278833175498, -0.072892306371455, 0.286562341986258, 0.0363981897820602, 0.332268763018087},
+    {-0.0576951799472842, 0.0251290590975512, -0.0741406382908807, 0.858208263567716, 0.109006741895515, 0.139491753677383},
+    {-0.0227857341019971, -0.117413197449647, 0.453155393641927, 0.593609805131561, 0.0753983311062783, 0.0180354016718774}};
+    
+    // Array of non-zero columns
+    static const unsigned int nzc1[6] = {6, 7, 8, 9, 10, 11};
+    // Array of non-zero columns
+    static const unsigned int nzc0[6] = {0, 1, 2, 3, 4, 5};
+    
+    // Compute element tensor using UFL quadrature representation
+    // Optimisations: ('simplify expressions', True), ('ignore zero tables', True), ('non zero columns', True), ('remove zero terms', True), ('ignore ones', True)
+    // Total number of operations to compute element tensor: 468
+    
+    // Loop quadrature points for integral
+    // Number of operations to compute element tensor for following IP loop = 468
+    for (unsigned int ip = 0; ip < 9; ip++)
+    {
+      
+      // Function declarations
+      double F0 = 0;
+      double F1 = 0;
+      
+      // Total number of operations to compute function values = 24
+      for (unsigned int r = 0; r < 6; r++)
+      {
+        F0 += FE0_C0[ip][r]*w[0][nzc0[r]];
+        F1 += FE0_C0[ip][r]*w[0][nzc1[r]];
+      }// end loop over 'r'
+      
+      // Number of operations to compute ip constants: 4
+      // Number of operations: 2
+      const double Gip0 = F0*W9[ip]*det;
+      
+      // Number of operations: 2
+      const double Gip1 = F1*W9[ip]*det;
+      
+      
+      // Number of operations for primary indices: 24
+      for (unsigned int j = 0; j < 6; j++)
+      {
+        // Number of operations to compute entry: 2
+        A[nzc0[j]] += FE0_C0[ip][j]*Gip0;
+        // Number of operations to compute entry: 2
+        A[nzc1[j]] += FE0_C0[ip][j]*Gip1;
+      }// end loop over 'j'
+    }// end loop over 'ip'
+}
+
+/// Constructor
+projection_1_cell_integral_0::projection_1_cell_integral_0() : ufc::cell_integral()
+{
+    // Do nothing
+}
+
+/// Destructor
+projection_1_cell_integral_0::~projection_1_cell_integral_0()
+{
+    // Do nothing
+}
+
+/// Tabulate the tensor for the contribution from a local cell
+void projection_1_cell_integral_0::tabulate_tensor(double* A,
+                                    const double * const * w,
+                                    const ufc::cell& c) const
+{
+    // Reset values of the element tensor block
+    for (unsigned int j = 0; j < 12; j++)
+      A[j] = 0;
+    
+    // Add all contributions to element tensor
+    integral_0_quadrature.tabulate_tensor(A, w, c);
+}
+
+/// Constructor
+projection_form_1::projection_form_1() : ufc::form()
+{
+    // Do nothing
+}
+
+/// Destructor
+projection_form_1::~projection_form_1()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the form
+const char* projection_form_1::signature() const
+{
+    return "Form([Integral(IndexSum(Product(Indexed(BasisFunction(VectorElement('Lagrange', Cell('triangle', 1, Space(2)), 2, 2), 0), MultiIndex((Index(0),), {Index(0): 2})), Indexed(Function(VectorElement('Lagrange', Cell('triangle', 1, Space(2)), 2, 2), 0), MultiIndex((Index(0),), {Index(0): 2}))), MultiIndex((Index(0),), {Index(0): 2})), Measure('cell', 0, None))])";
+}
+
+/// Return the rank of the global tensor (r)
+unsigned int projection_form_1::rank() const
+{
+    return 1;
+}
+
+/// Return the number of coefficients (n)
+unsigned int projection_form_1::num_coefficients() const
+{
+    return 1;
+}
+
+/// Return the number of cell integrals
+unsigned int projection_form_1::num_cell_integrals() const
+{
+    return 1;
+}
+
+/// Return the number of exterior facet integrals
+unsigned int projection_form_1::num_exterior_facet_integrals() const
+{
+    return 0;
+}
+
+/// Return the number of interior facet integrals
+unsigned int projection_form_1::num_interior_facet_integrals() const
+{
+    return 0;
+}
+
+/// Create a new finite element for argument function i
+ufc::finite_element* projection_form_1::create_finite_element(unsigned int i) const
+{
+    switch ( i )
+    {
+    case 0:
+      return new projection_1_finite_element_0();
+      break;
+    case 1:
+      return new projection_1_finite_element_1();
+      break;
+    }
+    return 0;
+}
+
+/// Create a new dof map for argument function i
+ufc::dof_map* projection_form_1::create_dof_map(unsigned int i) const
+{
+    switch ( i )
+    {
+    case 0:
+      return new projection_1_dof_map_0();
+      break;
+    case 1:
+      return new projection_1_dof_map_1();
+      break;
+    }
+    return 0;
+}
+
+/// Create a new cell integral on sub domain i
+ufc::cell_integral* projection_form_1::create_cell_integral(unsigned int i) const
+{
+    return new projection_1_cell_integral_0();
+}
+
+/// Create a new exterior facet integral on sub domain i
+ufc::exterior_facet_integral* projection_form_1::create_exterior_facet_integral(unsigned int i) const
+{
+    return 0;
+}
+
+/// Create a new interior facet integral on sub domain i
+ufc::interior_facet_integral* projection_form_1::create_interior_facet_integral(unsigned int i) const
+{
+    return 0;
+}
+
diff -r 18d756141ac1 -r 137baa77335a MADDs-5/MADDs-5a/cpp/Projection.ufl
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MADDs-5/MADDs-5a/cpp/Projection.ufl	Tue Dec 08 23:31:34 2009 -0500
@@ -0,0 +1,1 @@
+forms/Projection_P2.ufl
\ No newline at end of file
diff -r 18d756141ac1 -r 137baa77335a MADDs-5/MADDs-5a/cpp/SemiLagrangianRHS.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MADDs-5/MADDs-5a/cpp/SemiLagrangianRHS.cpp	Tue Dec 08 23:31:34 2009 -0500
@@ -0,0 +1,1148 @@
+#include "SemiLagrangianRHS.h"
+
+/// Constructor
+semilagrangianrhs_0_finite_element_0::semilagrangianrhs_0_finite_element_0() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+semilagrangianrhs_0_finite_element_0::~semilagrangianrhs_0_finite_element_0()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* semilagrangianrhs_0_finite_element_0::signature() const
+{
+    return "FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
+}
+
+/// Return the cell shape
+ufc::shape semilagrangianrhs_0_finite_element_0::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int semilagrangianrhs_0_finite_element_0::space_dimension() const
+{
+    return 6;
+}
+
+/// Return the rank of the value space
+unsigned int semilagrangianrhs_0_finite_element_0::value_rank() const
+{
+    return 0;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int semilagrangianrhs_0_finite_element_0::value_dimension(unsigned int i) const
+{
+    return 1;
+}
+
+/// Evaluate basis function i at given point in cell
+void semilagrangianrhs_0_finite_element_0::evaluate_basis(unsigned int i,
+                                   double* values,
+                                   const double* coordinates,
+                                   const ufc::cell& c) const
+{
+    // Extract vertex coordinates
+    const double * const * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Reset values
+    *values = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+    const double psitilde_bs_1_0 = 1;
+    const double psitilde_bs_1_1 = 2.5*y + 1.5;
+    const double psitilde_bs_2_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+    const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+    const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[6][6] = \
+    {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+    {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+    {0, 0, 0.2, 0, 0, 0.163299316185545},
+    {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+    {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+    {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+    // Extract relevant coefficients
+    const double coeff0_0 = coefficients0[dof][0];
+    const double coeff0_1 = coefficients0[dof][1];
+    const double coeff0_2 = coefficients0[dof][2];
+    const double coeff0_3 = coefficients0[dof][3];
+    const double coeff0_4 = coefficients0[dof][4];
+    const double coeff0_5 = coefficients0[dof][5];
+    
+    // Compute value(s)
+    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
+}
+
+/// Evaluate all basis functions at given point in cell
+void semilagrangianrhs_0_finite_element_0::evaluate_basis_all(double* values,
+                                       const double* coordinates,
+                                       const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
+}
+
+/// Evaluate order n derivatives of basis function i at given point in cell
+void semilagrangianrhs_0_finite_element_0::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 * element_coordinates = c.coordinates;
+    
+    // Compute Jacobian of affine map from reference cell
+    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
+    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
+    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
+    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
+    
+    // Compute determinant of Jacobian
+    const double detJ = J_00*J_11 - J_01*J_10;
+    
+    // Compute inverse of Jacobian
+    
+    // Get coordinates and map to the reference (UFC) element
+    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
+                element_coordinates[0][0]*element_coordinates[2][1] +\
+                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
+    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
+                element_coordinates[1][0]*element_coordinates[0][1] -\
+                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
+    
+    // Map coordinates to the reference square
+    if (std::abs(y - 1.0) < 1e-14)
+      x = -1.0;
+    else
+      x = 2.0 *x/(1.0 - y) - 1.0;
+    y = 2.0*y - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 2;
+    
+    
+    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
+    unsigned int **combinations = new unsigned int *[num_derivatives];
+    
+    for (unsigned int j = 0; j < num_derivatives; j++)
+    {
+      combinations[j] = new unsigned int [n];
+      for (unsigned int k = 0; k < n; k++)
+        combinations[j][k] = 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] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
+    
+    // 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
+    for (unsigned int j = 0; j < 1*num_derivatives; j++)
+      values[j] = 0;
+    
+    // Map degree of freedom to element degree of freedom
+    const unsigned int dof = i;
+    
+    // Generate scalings
+    const double scalings_y_0 = 1;
+    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
+    const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    const double psitilde_a_1 = x;
+    const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    const double psitilde_bs_0_1 = 1.5*y + 0.5;
+    const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
+    const double psitilde_bs_1_0 = 1;
+    const double psitilde_bs_1_1 = 2.5*y + 1.5;
+    const double psitilde_bs_2_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
+    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
+    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
+    const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
+    const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
+    const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[6][6] = \
+    {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
+    {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
+    {0, 0, 0.2, 0, 0, 0.163299316185545},
+    {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
+    {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
+    {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
+    
+    // Interesting (new) part
+    // Tables of derivatives of the polynomial base (transpose)
+    static const double dmats0[6][6] = \
+    {{0, 0, 0, 0, 0, 0},
+    {4.89897948556636, 0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0},
+    {0, 9.48683298050514, 0, 0, 0, 0},
+    {4, 0, 7.07106781186548, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0}};
+    
+    static const double dmats1[6][6] = \
+    {{0, 0, 0, 0, 0, 0},
+    {2.44948974278318, 0, 0, 0, 0, 0},
+    {4.24264068711928, 0, 0, 0, 0, 0},
+    {2.58198889747161, 4.74341649025257, -0.912870929175277, 0, 0, 0},
+    {2, 6.12372435695795, 3.53553390593274, 0, 0, 0},
+    {-2.3094010767585, 0, 8.16496580927726, 0, 0, 0}};
+    
+    // Compute reference derivatives
+    // Declare pointer to array of derivatives on FIAT element
+    double *derivatives = new double [num_derivatives];
+    
+    // Declare coefficients
+    double coeff0_0 = 0;
+    double coeff0_1 = 0;
+    double coeff0_2 = 0;
+    double coeff0_3 = 0;
+    double coeff0_4 = 0;
+    double coeff0_5 = 0;
+    
+    // Declare new coefficients
+    double new_coeff0_0 = 0;
+    double new_coeff0_1 = 0;
+    double new_coeff0_2 = 0;
+    double new_coeff0_3 = 0;
+    double new_coeff0_4 = 0;
+    double new_coeff0_5 = 0;
+    
+    // Loop possible derivatives
+    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
+    {
+      // Get values from coefficients array
+      new_coeff0_0 = coefficients0[dof][0];
+      new_coeff0_1 = coefficients0[dof][1];
+      new_coeff0_2 = coefficients0[dof][2];
+      new_coeff0_3 = coefficients0[dof][3];
+      new_coeff0_4 = coefficients0[dof][4];
+      new_coeff0_5 = coefficients0[dof][5];
+    
+      // Loop derivative order
+      for (unsigned int j = 0; j < n; j++)
+      {
+        // Update old coefficients
+        coeff0_0 = new_coeff0_0;
+        coeff0_1 = new_coeff0_1;
+        coeff0_2 = new_coeff0_2;
+        coeff0_3 = new_coeff0_3;
+        coeff0_4 = new_coeff0_4;
+        coeff0_5 = new_coeff0_5;
+    
+        if(combinations[deriv_num][j] == 0)
+        {
+          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
+          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
+          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
+          new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
+          new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
+          new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
+        }
+        if(combinations[deriv_num][j] == 1)
+        {
+          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
+          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
+          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
+          new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
+          new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
+          new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
+        }
+    
+      }
+      // Compute derivatives on reference element as dot product of coefficients and basisvalues
+      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
+    }
+    
+    // Transform derivatives back to physical element
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      for (unsigned int col = 0; col < num_derivatives; col++)
+      {
+        values[row] += transform[row][col]*derivatives[col];
+      }
+    }
+    // Delete pointer to array of derivatives on FIAT element
+    delete [] derivatives;
+    
+    // Delete pointer to array of combinations of derivatives and transform
+    for (unsigned int row = 0; row < num_derivatives; row++)
+    {
+      delete [] combinations[row];
+      delete [] transform[row];
+    }
+    
+    delete [] combinations;
+    delete [] transform;
+}
+
+/// Evaluate order n derivatives of all basis functions at given point in cell
+void semilagrangianrhs_0_finite_element_0::evaluate_basis_derivatives_all(unsigned int n,
+                                                   double* values,
+                                                   const double* coordinates,
+                                                   const ufc::cell& c) const
+{
+    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
+}
+
+/// Evaluate linear functional for dof i on the function f
+double semilagrangianrhs_0_finite_element_0::evaluate_dof(unsigned int i,
+                                   const ufc::function& f,
+                                   const ufc::cell& c) const
+{
+    // The reference points, direction and weights:
+    static const double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}};
+    static const double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
+    static const double D[6][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}, {{1}}, {{1}}};
+    
+    const double * const * x = c.coordinates;
+    double result = 0.0;
+    // Iterate over the points:
+    // Evaluate basis functions for affine mapping
+    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    
+    // Compute affine mapping y = F(X)
+    double y[2];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
+    
+    // Evaluate function at physical points
+    double values[1];
+    f.evaluate(values, y, c);
+    
+    // Map function values using appropriate mapping
+    // Affine map: Do nothing
+    
+    // Note that we do not map the weights (yet).
+    
+    // Take directional components
+    for(int k = 0; k < 1; k++)
+      result += values[k]*D[i][0][k];
+    // Multiply by weights
+    result *= W[i][0];
+    
+    return result;
+}
+
+/// Evaluate linear functionals for all dofs on the function f
+void semilagrangianrhs_0_finite_element_0::evaluate_dofs(double* values,
+                                  const ufc::function& f,
+                                  const ufc::cell& c) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Interpolate vertex values from dof values
+void semilagrangianrhs_0_finite_element_0::interpolate_vertex_values(double* vertex_values,
+                                              const double* dof_values,
+                                              const ufc::cell& c) const
+{
+    // Evaluate at vertices and use affine mapping
+    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)
+unsigned int semilagrangianrhs_0_finite_element_0::num_sub_elements() const
+{
+    return 1;
+}
+
+/// Create a new finite element for sub element i (for a mixed element)
+ufc::finite_element* semilagrangianrhs_0_finite_element_0::create_sub_element(unsigned int i) const
+{
+    return new semilagrangianrhs_0_finite_element_0();
+}
+
+
+/// Constructor
+semilagrangianrhs_0_finite_element_1::semilagrangianrhs_0_finite_element_1() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+semilagrangianrhs_0_finite_element_1::~semilagrangianrhs_0_finite_element_1()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* semilagrangianrhs_0_finite_element_1::signature() const
+{
+    return "FiniteElement('Quadrature', Cell('triangle', 1, Space(2)), 4)";
+}
+
+/// Return the cell shape
+ufc::shape semilagrangianrhs_0_finite_element_1::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int semilagrangianrhs_0_finite_element_1::space_dimension() const
+{
+    return 9;
+}
+
+/// Return the rank of the value space
+unsigned int semilagrangianrhs_0_finite_element_1::value_rank() const
+{
+    return 0;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int semilagrangianrhs_0_finite_element_1::value_dimension(unsigned int i) const
+{
+    return 1;
+}
+
+/// Evaluate basis function i at given point in cell
+void semilagrangianrhs_0_finite_element_1::evaluate_basis(unsigned int i,
+                                   double* values,
+                                   const double* coordinates,
+                                   const ufc::cell& c) const
+{
+    throw std::runtime_error("evaluate_basis() is not supported for QuadratureElement");
+}
+
+/// Evaluate all basis functions at given point in cell
+void semilagrangianrhs_0_finite_element_1::evaluate_basis_all(double* values,
+                                       const double* coordinates,
+                                       const ufc::cell& c) const
+{
+    throw std::runtime_error("evaluate_basis_all() is not supported for QuadratureElement.");
+}
+
+/// Evaluate order n derivatives of basis function i at given point in cell
+void semilagrangianrhs_0_finite_element_1::evaluate_basis_derivatives(unsigned int i,
+                                               unsigned int n,
+                                               double* values,
+                                               const double* coordinates,
+                                               const ufc::cell& c) const
+{
+    throw std::runtime_error("evaluate_basis_derivatives() is not supported for QuadratureElement");
+}
+
+/// Evaluate order n derivatives of all basis functions at given point in cell
+void semilagrangianrhs_0_finite_element_1::evaluate_basis_derivatives_all(unsigned int n,
+                                                   double* values,
+                                                   const double* coordinates,
+                                                   const ufc::cell& c) const
+{
+    throw std::runtime_error("evaluate_basis_derivatives_all() is not supported for QuadratureElement.");
+}
+
+/// Evaluate linear functional for dof i on the function f
+double semilagrangianrhs_0_finite_element_1::evaluate_dof(unsigned int i,
+                                   const ufc::function& f,
+                                   const ufc::cell& c) const
+{
+    // The reference points, direction and weights:
+    static const double X[9][1][2] = {{{0.102717654809626, 0.088587959512704}}, {{0.0665540678391645, 0.409466864440735}}, {{0.0239311322870806, 0.787659461760847}}, {{0.455706020243648, 0.088587959512704}}, {{0.295266567779633, 0.409466864440735}}, {{0.106170269119576, 0.787659461760847}}, {{0.80869438567767, 0.088587959512704}}, {{0.523979067720101, 0.409466864440735}}, {{0.188409405952072, 0.787659461760847}}};
+    static const double W[9][1] = {{1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}};
+    static const double D[9][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}, {{1}}, {{1}}, {{1}}, {{1}}, {{1}}};
+    
+    const double * const * x = c.coordinates;
+    double result = 0.0;
+    // Iterate over the points:
+    // Evaluate basis functions for affine mapping
+    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    
+    // Compute affine mapping y = F(X)
+    double y[2];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
+    
+    // Evaluate function at physical points
+    double values[1];
+    f.evaluate(values, y, c);
+    
+    // Map function values using appropriate mapping
+    // Affine map: Do nothing
+    
+    // Note that we do not map the weights (yet).
+    
+    // Take directional components
+    for(int k = 0; k < 1; k++)
+      result += values[k]*D[i][0][k];
+    // Multiply by weights
+    result *= W[i][0];
+    
+    return result;
+}
+
+/// Evaluate linear functionals for all dofs on the function f
+void semilagrangianrhs_0_finite_element_1::evaluate_dofs(double* values,
+                                  const ufc::function& f,
+                                  const ufc::cell& c) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Interpolate vertex values from dof values
+void semilagrangianrhs_0_finite_element_1::interpolate_vertex_values(double* vertex_values,
+                                              const double* dof_values,
+                                              const ufc::cell& c) const
+{
+    throw std::runtime_error("interpolate_vertex_values() is not supported for QuadratureElement");
+}
+
+/// Return the number of sub elements (for a mixed element)
+unsigned int semilagrangianrhs_0_finite_element_1::num_sub_elements() const
+{
+    return 1;
+}
+
+/// Create a new finite element for sub element i (for a mixed element)
+ufc::finite_element* semilagrangianrhs_0_finite_element_1::create_sub_element(unsigned int i) const
+{
+    return new semilagrangianrhs_0_finite_element_1();
+}
+
+/// Constructor
+semilagrangianrhs_0_dof_map_0::semilagrangianrhs_0_dof_map_0() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+semilagrangianrhs_0_dof_map_0::~semilagrangianrhs_0_dof_map_0()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* semilagrangianrhs_0_dof_map_0::signature() const
+{
+    return "FFC dof map for FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool semilagrangianrhs_0_dof_map_0::needs_mesh_entities(unsigned int d) const
+{
+    switch ( d )
+    {
+    case 0:
+      return true;
+      break;
+    case 1:
+      return true;
+      break;
+    case 2:
+      return false;
+      break;
+    }
+    return false;
+}
+
+/// Initialize dof map for mesh (return true iff init_cell() is needed)
+bool semilagrangianrhs_0_dof_map_0::init_mesh(const ufc::mesh& m)
+{
+    __global_dimension = m.num_entities[0] + m.num_entities[1];
+    return false;
+}
+
+/// Initialize dof map for given cell
+void semilagrangianrhs_0_dof_map_0::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void semilagrangianrhs_0_dof_map_0::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int semilagrangianrhs_0_dof_map_0::global_dimension() const
+{
+    return __global_dimension;
+}
+
+/// Return the dimension of the local finite element function space for a cell
+unsigned int semilagrangianrhs_0_dof_map_0::local_dimension(const ufc::cell& c) const
+{
+    return 6;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int semilagrangianrhs_0_dof_map_0::max_local_dimension() const
+{
+    return 6;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int semilagrangianrhs_0_dof_map_0::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int semilagrangianrhs_0_dof_map_0::num_facet_dofs() const
+{
+    return 3;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int semilagrangianrhs_0_dof_map_0::num_entity_dofs(unsigned int d) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the local-to-global mapping of dofs on a cell
+void semilagrangianrhs_0_dof_map_0::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];
+    unsigned int offset = m.num_entities[0];
+    dofs[3] = offset + c.entity_indices[1][0];
+    dofs[4] = offset + c.entity_indices[1][1];
+    dofs[5] = offset + c.entity_indices[1][2];
+}
+
+/// Tabulate the local-to-local mapping from facet dofs to cell dofs
+void semilagrangianrhs_0_dof_map_0::tabulate_facet_dofs(unsigned int* dofs,
+                                        unsigned int facet) const
+{
+    switch ( facet )
+    {
+    case 0:
+      dofs[0] = 1;
+      dofs[1] = 2;
+      dofs[2] = 3;
+      break;
+    case 1:
+      dofs[0] = 0;
+      dofs[1] = 2;
+      dofs[2] = 4;
+      break;
+    case 2:
+      dofs[0] = 0;
+      dofs[1] = 1;
+      dofs[2] = 5;
+      break;
+    }
+}
+
+/// Tabulate the local-to-local mapping of dofs on entity (d, i)
+void semilagrangianrhs_0_dof_map_0::tabulate_entity_dofs(unsigned int* dofs,
+                                  unsigned int d, unsigned int i) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the coordinates of all dofs on a cell
+void semilagrangianrhs_0_dof_map_0::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];
+    coordinates[3][0] = 0.5*x[1][0] + 0.5*x[2][0];
+    coordinates[3][1] = 0.5*x[1][1] + 0.5*x[2][1];
+    coordinates[4][0] = 0.5*x[0][0] + 0.5*x[2][0];
+    coordinates[4][1] = 0.5*x[0][1] + 0.5*x[2][1];
+    coordinates[5][0] = 0.5*x[0][0] + 0.5*x[1][0];
+    coordinates[5][1] = 0.5*x[0][1] + 0.5*x[1][1];
+}
+
+/// Return the number of sub dof maps (for a mixed element)
+unsigned int semilagrangianrhs_0_dof_map_0::num_sub_dof_maps() const
+{
+    return 1;
+}
+
+/// Create a new dof_map for sub dof map i (for a mixed element)
+ufc::dof_map* semilagrangianrhs_0_dof_map_0::create_sub_dof_map(unsigned int i) const
+{
+    return new semilagrangianrhs_0_dof_map_0();
+}
+
+
+/// Constructor
+semilagrangianrhs_0_dof_map_1::semilagrangianrhs_0_dof_map_1() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+semilagrangianrhs_0_dof_map_1::~semilagrangianrhs_0_dof_map_1()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* semilagrangianrhs_0_dof_map_1::signature() const
+{
+    return "FFC dof map for FiniteElement('Quadrature', Cell('triangle', 1, Space(2)), 4)";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool semilagrangianrhs_0_dof_map_1::needs_mesh_entities(unsigned int d) const
+{
+    switch ( d )
+    {
+    case 0:
+      return false;
+      break;
+    case 1:
+      return false;
+      break;
+    case 2:
+      return true;
+      break;
+    }
+    return false;
+}
+
+/// Initialize dof map for mesh (return true iff init_cell() is needed)
+bool semilagrangianrhs_0_dof_map_1::init_mesh(const ufc::mesh& m)
+{
+    __global_dimension = 9*m.num_entities[2];
+    return false;
+}
+
+/// Initialize dof map for given cell
+void semilagrangianrhs_0_dof_map_1::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void semilagrangianrhs_0_dof_map_1::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int semilagrangianrhs_0_dof_map_1::global_dimension() const
+{
+    return __global_dimension;
+}
+
+/// Return the dimension of the local finite element function space for a cell
+unsigned int semilagrangianrhs_0_dof_map_1::local_dimension(const ufc::cell& c) const
+{
+    return 9;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int semilagrangianrhs_0_dof_map_1::max_local_dimension() const
+{
+    return 9;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int semilagrangianrhs_0_dof_map_1::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int semilagrangianrhs_0_dof_map_1::num_facet_dofs() const
+{
+    return 0;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int semilagrangianrhs_0_dof_map_1::num_entity_dofs(unsigned int d) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the local-to-global mapping of dofs on a cell
+void semilagrangianrhs_0_dof_map_1::tabulate_dofs(unsigned int* dofs,
+                                  const ufc::mesh& m,
+                                  const ufc::cell& c) const
+{
+    dofs[0] = 9*c.entity_indices[2][0];
+    dofs[1] = 9*c.entity_indices[2][0] + 1;
+    dofs[2] = 9*c.entity_indices[2][0] + 2;
+    dofs[3] = 9*c.entity_indices[2][0] + 3;
+    dofs[4] = 9*c.entity_indices[2][0] + 4;
+    dofs[5] = 9*c.entity_indices[2][0] + 5;
+    dofs[6] = 9*c.entity_indices[2][0] + 6;
+    dofs[7] = 9*c.entity_indices[2][0] + 7;
+    dofs[8] = 9*c.entity_indices[2][0] + 8;
+}
+
+/// Tabulate the local-to-local mapping from facet dofs to cell dofs
+void semilagrangianrhs_0_dof_map_1::tabulate_facet_dofs(unsigned int* dofs,
+                                        unsigned int facet) const
+{
+    switch ( facet )
+    {
+    case 0:
+      
+      break;
+    case 1:
+      
+      break;
+    case 2:
+      
+      break;
+    }
+}
+
+/// Tabulate the local-to-local mapping of dofs on entity (d, i)
+void semilagrangianrhs_0_dof_map_1::tabulate_entity_dofs(unsigned int* dofs,
+                                  unsigned int d, unsigned int i) const
+{
+    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
+}
+
+/// Tabulate the coordinates of all dofs on a cell
+void semilagrangianrhs_0_dof_map_1::tabulate_coordinates(double** coordinates,
+                                         const ufc::cell& c) const
+{
+    const double * const * x = c.coordinates;
+    coordinates[0][0] = 0.80869438567767*x[0][0] + 0.102717654809626*x[1][0] + 0.088587959512704*x[2][0];
+    coordinates[0][1] = 0.80869438567767*x[0][1] + 0.102717654809626*x[1][1] + 0.088587959512704*x[2][1];
+    coordinates[1][0] = 0.523979067720101*x[0][0] + 0.0665540678391645*x[1][0] + 0.409466864440735*x[2][0];
+    coordinates[1][1] = 0.523979067720101*x[0][1] + 0.0665540678391645*x[1][1] + 0.409466864440735*x[2][1];
+    coordinates[2][0] = 0.188409405952072*x[0][0] + 0.0239311322870807*x[1][0] + 0.787659461760847*x[2][0];
+    coordinates[2][1] = 0.188409405952072*x[0][1] + 0.0239311322870807*x[1][1] + 0.787659461760847*x[2][1];
+    coordinates[3][0] = 0.455706020243648*x[0][0] + 0.455706020243648*x[1][0] + 0.088587959512704*x[2][0];
+    coordinates[3][1] = 0.455706020243648*x[0][1] + 0.455706020243648*x[1][1] + 0.088587959512704*x[2][1];
+    coordinates[4][0] = 0.295266567779633*x[0][0] + 0.295266567779633*x[1][0] + 0.409466864440735*x[2][0];
+    coordinates[4][1] = 0.295266567779633*x[0][1] + 0.295266567779633*x[1][1] + 0.409466864440735*x[2][1];
+    coordinates[5][0] = 0.106170269119577*x[0][0] + 0.106170269119577*x[1][0] + 0.787659461760847*x[2][0];
+    coordinates[5][1] = 0.106170269119577*x[0][1] + 0.106170269119577*x[1][1] + 0.787659461760847*x[2][1];
+    coordinates[6][0] = 0.102717654809626*x[0][0] + 0.80869438567767*x[1][0] + 0.088587959512704*x[2][0];
+    coordinates[6][1] = 0.102717654809626*x[0][1] + 0.80869438567767*x[1][1] + 0.088587959512704*x[2][1];
+    coordinates[7][0] = 0.0665540678391645*x[0][0] + 0.523979067720101*x[1][0] + 0.409466864440735*x[2][0];
+    coordinates[7][1] = 0.0665540678391645*x[0][1] + 0.523979067720101*x[1][1] + 0.409466864440735*x[2][1];
+    coordinates[8][0] = 0.0239311322870807*x[0][0] + 0.188409405952072*x[1][0] + 0.787659461760847*x[2][0];
+    coordinates[8][1] = 0.0239311322870807*x[0][1] + 0.188409405952072*x[1][1] + 0.787659461760847*x[2][1];
+}
+
+/// Return the number of sub dof maps (for a mixed element)
+unsigned int semilagrangianrhs_0_dof_map_1::num_sub_dof_maps() const
+{
+    return 1;
+}
+
+/// Create a new dof_map for sub dof map i (for a mixed element)
+ufc::dof_map* semilagrangianrhs_0_dof_map_1::create_sub_dof_map(unsigned int i) const
+{
+    return new semilagrangianrhs_0_dof_map_1();
+}
+
+
+/// Constructor
+semilagrangianrhs_0_cell_integral_0_quadrature::semilagrangianrhs_0_cell_integral_0_quadrature() : ufc::cell_integral()
+{
+    // Do nothing
+}
+
+/// Destructor
+semilagrangianrhs_0_cell_integral_0_quadrature::~semilagrangianrhs_0_cell_integral_0_quadrature()
+{
+    // Do nothing
+}
+
+/// Tabulate the tensor for the contribution from a local cell
+void semilagrangianrhs_0_cell_integral_0_quadrature::tabulate_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 W9[9] = {0.0558144204830443, 0.063678085099885, 0.0193963833059595, 0.0893030727728709, 0.101884936159816, 0.0310342132895351, 0.0558144204830443, 0.063678085099885, 0.0193963833059595};
+    // Quadrature points on the UFC reference element: (0.102717654809626, 0.088587959512704), (0.0665540678391645, 0.409466864440735), (0.0239311322870806, 0.787659461760847), (0.455706020243648, 0.088587959512704), (0.295266567779633, 0.409466864440735), (0.106170269119576, 0.787659461760847), (0.80869438567767, 0.088587959512704), (0.523979067720101, 0.409466864440735), (0.188409405952072, 0.787659461760847)
+    
+    // Value of basis functions at quadrature points.
+    static const double FE0[9][6] = \
+    {{0.499278833175498, -0.0816158215904472, -0.072892306371455, 0.0363981897820602, 0.286562341986258, 0.332268763018087},
+    {0.0251290590975512, -0.0576951799472843, -0.0741406382908806, 0.109006741895515, 0.858208263567716, 0.139491753677383},
+    {-0.117413197449647, -0.022785734101997, 0.453155393641927, 0.0753983311062782, 0.593609805131561, 0.0180354016718773},
+    {-0.0403700664710397, -0.0403700664710397, -0.072892306371455, 0.161480265884159, 0.161480265884159, 0.830671907545216},
+    {-0.120901875682904, -0.120901875682904, -0.0741406382908806, 0.483607502731615, 0.483607502731615, 0.348729384193458},
+    {-0.0836260170297298, -0.0836260170297298, 0.453155393641927, 0.33450406811892, 0.33450406811892, 0.0450885041796933},
+    {-0.0816158215904471, 0.499278833175498, -0.072892306371455, 0.286562341986258, 0.0363981897820602, 0.332268763018087},
+    {-0.0576951799472841, 0.0251290590975512, -0.0741406382908806, 0.858208263567716, 0.109006741895515, 0.139491753677383},
+    {-0.022785734101997, -0.117413197449647, 0.453155393641927, 0.593609805131561, 0.0753983311062783, 0.0180354016718774}};
+    
+    
+    // Compute element tensor using UFL quadrature representation
+    // Optimisations: ('simplify expressions', True), ('ignore zero tables', True), ('non zero columns', True), ('remove zero terms', True), ('ignore ones', True)
+    // Total number of operations to compute element tensor: 126
+    
+    // Loop quadrature points for integral
+    // Number of operations to compute element tensor for following IP loop = 126
+    for (unsigned int ip = 0; ip < 9; ip++)
+    {
+      
+      // Number of operations to compute ip constants: 2
+      // Number of operations: 2
+      const double Gip0 = -W9[ip]*det*w[0][ip];
+      
+      
+      // Number of operations for primary indices: 12
+      for (unsigned int j = 0; j < 6; j++)
+      {
+        // Number of operations to compute entry: 2
+        A[j] += FE0[ip][j]*Gip0;
+      }// end loop over 'j'
+    }// end loop over 'ip'
+}
+
+/// Constructor
+semilagrangianrhs_0_cell_integral_0::semilagrangianrhs_0_cell_integral_0() : ufc::cell_integral()
+{
+    // Do nothing
+}
+
+/// Destructor
+semilagrangianrhs_0_cell_integral_0::~semilagrangianrhs_0_cell_integral_0()
+{
+    // Do nothing
+}
+
+/// Tabulate the tensor for the contribution from a local cell
+void semilagrangianrhs_0_cell_integral_0::tabulate_tensor(double* A,
+                                    const double * const * w,
+                                    const ufc::cell& c) const
+{
+    // Reset values of the element tensor block
+    for (unsigned int j = 0; j < 6; j++)
+      A[j] = 0;
+    
+    // Add all contributions to element tensor
+    integral_0_quadrature.tabulate_tensor(A, w, c);
+}
+
+/// Constructor
+semilagrangianrhs_form_0::semilagrangianrhs_form_0() : ufc::form()
+{
+    // Do nothing
+}
+
+/// Destructor
+semilagrangianrhs_form_0::~semilagrangianrhs_form_0()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the form
+const char* semilagrangianrhs_form_0::signature() const
+{
+    return "Form([Integral(Product(Function(FiniteElement('Quadrature', Cell('triangle', 1, Space(2)), 4), 0), Product(IntValue(-1, (), (), {}), BasisFunction(FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2), 0))), Measure('cell', 0, None))])";
+}
+
+/// Return the rank of the global tensor (r)
+unsigned int semilagrangianrhs_form_0::rank() const
+{
+    return 1;
+}
+
+/// Return the number of coefficients (n)
+unsigned int semilagrangianrhs_form_0::num_coefficients() const
+{
+    return 1;
+}
+
+/// Return the number of cell integrals
+unsigned int semilagrangianrhs_form_0::num_cell_integrals() const
+{
+    return 1;
+}
+
+/// Return the number of exterior facet integrals
+unsigned int semilagrangianrhs_form_0::num_exterior_facet_integrals() const
+{
+    return 0;
+}
+
+/// Return the number of interior facet integrals
+unsigned int semilagrangianrhs_form_0::num_interior_facet_integrals() const
+{
+    return 0;
+}
+
+/// Create a new finite element for argument function i
+ufc::finite_element* semilagrangianrhs_form_0::create_finite_element(unsigned int i) const
+{
+    switch ( i )
+    {
+    case 0:
+      return new semilagrangianrhs_0_finite_element_0();
+      break;
+    case 1:
+      return new semilagrangianrhs_0_finite_element_1();
+      break;
+    }
+    return 0;
+}
+
+/// Create a new dof map for argument function i
+ufc::dof_map* semilagrangianrhs_form_0::create_dof_map(unsigned int i) const
+{
+    switch ( i )
+    {
+    case 0:
+      return new semilagrangianrhs_0_dof_map_0();
+      break;
+    case 1:
+      return new semilagrangianrhs_0_dof_map_1();
+      break;
+    }
+    return 0;
+}
+
+/// Create a new cell integral on sub domain i
+ufc::cell_integral* semilagrangianrhs_form_0::create_cell_integral(unsigned int i) const
+{
+    return new semilagrangianrhs_0_cell_integral_0();
+}
+
+/// Create a new exterior facet integral on sub domain i
+ufc::exterior_facet_integral* semilagrangianrhs_form_0::create_exterior_facet_integral(unsigned int i) const
+{
+    return 0;
+}
+
+/// Create a new interior facet integral on sub domain i
+ufc::interior_facet_integral* semilagrangianrhs_form_0::create_interior_facet_integral(unsigned int i) const
+{
+    return 0;
+}
+
diff -r 18d756141ac1 -r 137baa77335a MADDs-5/MADDs-5a/cpp/SemiLagrangianRHS.ufl
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MADDs-5/MADDs-5a/cpp/SemiLagrangianRHS.ufl	Tue Dec 08 23:31:34 2009 -0500
@@ -0,0 +1,1 @@
+forms/SemiLagrangianRHS_P2.ufl
\ No newline at end of file
diff -r 18d756141ac1 -r 137baa77335a MADDs-5/MADDs-5a/cpp/forms/SemiLagrangianRHS_P2.ufl
--- a/MADDs-5/MADDs-5a/cpp/forms/SemiLagrangianRHS_P2.ufl	Mon Dec 07 00:03:09 2009 -0500
+++ b/MADDs-5/MADDs-5a/cpp/forms/SemiLagrangianRHS_P2.ufl	Tue Dec 08 23:31:34 2009 -0500
@@ -9,7 +9,7 @@ QE = FiniteElement("Quadrature", triangl
 QE = FiniteElement("Quadrature", triangle,4) # quadrature element for Semi-Lagrangian source term
 
 u  = TestFunction(P2)
-gStar    = Function(P2)      # source term calculated from last time step by semi-Lagrangian update
+gStar    = Function(QE)      # source term calculated from last time step by semi-Lagrangian update
 
 
 L =  -u*gStar*dx 
diff -r 18d756141ac1 -r 137baa77335a MADDs-5/MADDs-5a/cpp/main.cpp
--- a/MADDs-5/MADDs-5a/cpp/main.cpp	Mon Dec 07 00:03:09 2009 -0500
+++ b/MADDs-5/MADDs-5a/cpp/main.cpp	Tue Dec 08 23:31:34 2009 -0500
@@ -2,7 +2,7 @@
 // Licensed under the GNU LGPL Version 2.1.
 //
 // First added:   9 Mar 2009 17:39:22
-// Last changed:   9 Mar 2009 17:39:28
+// Last changed:    7 Dec 2009 00:05:28
 //
 // This program illustrates the use of hybrid DOLFIN/PETSc nonlinear solver for solving 
 // the time-dependent non-linear porosity magma equations for a Mid-Ocean ridge  problem (Benchmark MADDs-5a)
@@ -10,7 +10,7 @@
 // Latest version implements Semi-Lagrangian update for solid state velocity advection
 //
 //  modified  from Garth Wells Cahn-Hilliard Example in Dolfin/demo/nls/CahnHilliard
-//  Additionally modified from Spiegelman MADDs-4 and ArcFlow code for compatibility with Dolfin 0.9.1/FFC 0.6.1
+//  Additionally modified from Spiegelman MADDs-4 and ArcFlow code for compatibility with Dolfin 0.9.5/FFC 0.7.1
 //
 
 
@@ -106,15 +106,13 @@ class SemiLagrangianFunction : public Fu
       intersection_detector.reset(new IntersectionDetector(V.mesh()));
 
     // create new ufc_cell
-    ufc_cell_star = new UFCCell(u.function_space().mesh());
-    
-    // initialize vector x_star
+    ufc_cell_star = new UFCCell(V.mesh());
+
+    //create initialize x_star
     x_star.reserve(2);
-
   }
   
   // Destructor 
-
   ~SemiLagrangianFunction()
   {
 	delete ufc_cell_star;
@@ -137,7 +135,9 @@ class SemiLagrangianFunction : public Fu
 	ufc_cell_star->update(cell_star);
 	
 	u.eval(values0, x_star, cell_star, *ufc_cell_star); 
-	double pStar = values0[0], fStar = values0[1];
+	double pStar,fStar;
+	pStar = values0[0];
+	fStar = values0[1];
 
 	// get viscosity and gamma at x* (this assumes all discrete functions  share the same mesh as u, fragile!)
 	double iEtaStar, GammaStar;
@@ -151,7 +151,6 @@ class SemiLagrangianFunction : public Fu
     }
   
 private:
-
   
   // Model parameters
   Function& u;
@@ -174,7 +173,7 @@ private:
 // modified midpoint method
   bool findpoint(const Data& data) const
   {
-    dolfin::uint const dim = data.x.size();
+    dolfin::uint const dim = 2;//data.x.size();
     double V[dim];
     unsigned int i, k, kMax = 2;
     bool outside = false;
@@ -305,6 +304,8 @@ int main(int argc, char* argv[])
 int main(int argc, char* argv[])
 {
   dolfin_init(argc, argv);
+  logging(false); //turn off dolfin messages
+  set_log_level(1);
 
   //load mesh
   std::string  filename;
@@ -314,7 +315,7 @@ int main(int argc, char* argv[])
   mesh.init();
   mesh.order();
 
-  //Set function spaces for Stokes solutions
+  //Set function spaces for Stokes solutions (this may be broken)
   Stokes_P2P1::FunctionSpace W(mesh);
   SubSpace W0(W, 0); //velocity
   SubSpace W01(W0,1); //vertical velocity
@@ -380,7 +381,7 @@ int main(int argc, char* argv[])
    
   //set the melting rate Gamma = W*dFdz
   Function Velocity_W = Velocity[1];
-  Function Gamma(W01);
+  Function Gamma(Velocity_W.function_space());
   ProductionRate dFdz(phi0, Fmax, z_lambda, z_solidus);
   Gamma.interpolate(dFdz);
   Gamma.vector() *= Velocity_W.vector();
@@ -398,7 +399,7 @@ int main(int argc, char* argv[])
   
   //Boundary Conditions
   DirichletBoundary boundaries;
-  Constant uZero(2,0.0);
+  Constant uZero(0.0,0.0);
   DirichletBC bc(V, uZero, boundaries);
   // Collect boundary conditions
   std::vector<DirichletBC*> bcs(1);
@@ -406,9 +407,10 @@ int main(int argc, char* argv[])
   
   
   //set SemiLagrangian source function
-  SemiLagrangianRHS::FunctionSpace VStar(mesh);
+  SemiLagrangianRHS::FunctionSpace VStar(V.mesh());
   SemiLagrangianFunction gStar(VStar, u0, Velocity, Gamma, iEta, delta_t, h2);
-  SemiLagrangianRHS::LinearForm LStar(VStar, gStar);
+  SemiLagrangianRHS::LinearForm LStar(VStar);
+  LStar.gStar = gStar;
   Vector bStar;
   
   
@@ -442,7 +444,7 @@ int main(int argc, char* argv[])
   PETScVector x(xSize), r(xSize);
   // pre-allocate  memory for sparse Jacobian matrix
   PETScMatrix J;  
-  Assembler::assemble(J,ctx.a,true); //Assemble matrix once to set sparsity pattern
+  assemble(J,ctx.a,true); //Assemble matrix once to set sparsity pattern
 
   //create SNES and attach call-back functions
   SNESCreate(PETSC_COMM_WORLD, &snes);
@@ -542,8 +544,8 @@ int main(int argc, char* argv[])
       //calculate melt flux
       p = u[0];
       f = u[1];
-      Lm.p = u[0];
-      Lm.f = u[1];
+      Lm.p = p;
+      Lm.f = f;
       qmelt.solve(melt_flux);
       FindMaxMeltVelocity(max_mag_v, melt_flux, f, U0onw0, epsilon); 
       dt_check = std::min(delta_t0, cfl*dh/max_mag_v);
@@ -551,11 +553,11 @@ int main(int argc, char* argv[])
       //crude adaptive time stepping
       if (t == 0 || dt_check < delta_t) { // if initial or shrinking time-step
 	delta_t = dt_check;
-	cout << "decreasing delta_t=" << delta_t << endl;
+	printf("decreasing delta_t=%g\n",delta_t);
       }
       else if (dt_check > alpha*delta_t) { //grow the time step by a factor alpha
 	delta_t = alpha*delta_t;
-	cout << "increasing delta_t=" << delta_t << endl;
+	printf("increasing delta_t=%g\n",delta_t);
       }
       dt = delta_t;
     }



More information about the CIG-COMMITS mailing list