[cig-commits] commit: update SolitaryWave ufl splits

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


changeset:   100:4d3585d24e75
user:        Marc Spiegelman <mspieg at ldeo.columbia.edu>
date:        Sun Dec 06 00:12:54 2009 -0500
files:       MADDs-4/cpp/SolitaryWave2D.cpp MADDs-4/cpp/SolitaryWave3D.cpp
description:
update SolitaryWave ufl splits


diff -r 945ab07a21be -r 4d3585d24e75 MADDs-4/cpp/SolitaryWave2D.cpp
--- a/MADDs-4/cpp/SolitaryWave2D.cpp	Sat Dec 05 22:52:18 2009 -0500
+++ b/MADDs-4/cpp/SolitaryWave2D.cpp	Sun Dec 06 00:12:54 2009 -0500
@@ -7529,6 +7529,5962 @@ solitarywave2d_0_cell_integral_0_quadrat
 
 /// Tabulate the tensor for the contribution from a local cell
 void solitarywave2d_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 W25[25] = {0.0114650803515925, 0.0198040831320473, 0.0173415064313656, 0.0087554991821638, 0.00186555216687783, 0.0231612219294983, 0.0400072873861603, 0.0350325045033716, 0.0176874521104834, 0.0037687016953276, 0.0275289856644697, 0.0475518970579538, 0.0416389652151948, 0.021022967487322, 0.00447940679728133, 0.0231612219294983, 0.0400072873861603, 0.0350325045033716, 0.0176874521104834, 0.0037687016953276, 0.0114650803515925, 0.0198040831320473, 0.0173415064313656, 0.0087554991821638, 0.00186555216687783};
+    // Quadrature points on the UFC reference element: (0.0450425935698037, 0.0398098570514687), (0.0376212523451112, 0.198013417873608), (0.0263646449444709, 0.437974810247386), (0.0142857943955714, 0.695464273353636), (0.00462228846504642, 0.901464914201174), (0.221578609552379, 0.0398098570514687), (0.185070710267389, 0.198013417873608), (0.129695936782254, 0.437974810247386), (0.0702762920082817, 0.695464273353636), (0.022738483063764, 0.901464914201174), (0.480095071474266, 0.0398098570514687), (0.400993291063196, 0.198013417873608), (0.281012594876307, 0.437974810247386), (0.152267863323182, 0.695464273353636), (0.0492675428994132, 0.901464914201174), (0.738611533396152, 0.0398098570514687), (0.616915871859002, 0.198013417873608), (0.43232925297036, 0.437974810247386), (0.234259434638082, 0.695464273353636), (0.0757966027350624, 0.901464914201174), (0.915147549378728, 0.0398098570514687), (0.764365329781281, 0.198013417873608), (0.535660544808143, 0.437974810247386), (0.290249932250792, 0.695464273353636), (0.09391279733378, 0.901464914201174)
+    
+    // Value of basis functions at quadrature points.
+    static const double FE1_C0[25][6] = \
+    {{0.759842524889054, -0.0409849230988147, -0.036640207614552, 0.00717255684496518, 0.145727572487076, 0.164882476492272},
+    {0.404143384962011, -0.0347905350890821, -0.119594790557632, 0.0297980510461638, 0.605418365816316, 0.115025523822223},
+    {0.0382038937201701, -0.0249744559383749, -0.0543309414249183, 0.0461882014671774, 0.938423301877431, 0.0564900002985142},
+    {-0.121759885907613, -0.0138776265525463, 0.271876837668966, 0.0397410384743819, 0.807433832894958, 0.0165858034218535},
+    {-0.0762735703276686, -0.00457955736373816, 0.723813068870285, 0.0166673234982246, 0.338636367163553, 0.00173636815934486},
+    {0.352482461135478, -0.123384449130048, -0.036640207614552, 0.0352840510877737, 0.117616078244268, 0.65464206627708},
+    {0.144254514044104, -0.116568374669637, -0.119594790557632, 0.146585935553368, 0.488630481309112, 0.456692234320685},
+    {-0.0585120870225411, -0.0960538647466012, -0.0543309414249183, 0.227214213208259, 0.75739729013635, 0.224285389849452},
+    {-0.124504469204174, -0.0603987775714151, 0.271876837668966, 0.19549860142211, 0.65167626994723, 0.0658515377372835},
+    {-0.0643063527627086, -0.0217044058396818, 0.723813068870285, 0.0819917787365634, 0.273311911925214, 0.00689399907032842},
+    {-0.0191125161665051, -0.0191125161665052, -0.036640207614552, 0.0764500646660208, 0.0764500646660207, 0.921965110615521},
+    {-0.0794020521078099, -0.07940205210781, -0.119594790557632, 0.31760820843124, 0.31760820843124, 0.643182477910772},
+    {-0.123076437918076, -0.123076437918076, -0.0543309414249183, 0.492305751672304, 0.492305751672304, 0.315872313916462},
+    {-0.105896858921167, -0.105896858921167, 0.271876837668966, 0.42358743568467, 0.42358743568467, 0.092742008804029},
+    {-0.0444129613327221, -0.0444129613327221, 0.723813068870285, 0.177651845330889, 0.177651845330889, 0.00970916313338224},
+    {-0.123384449130048, 0.352482461135478, -0.036640207614552, 0.117616078244268, 0.0352840510877737, 0.65464206627708},
+    {-0.116568374669637, 0.144254514044104, -0.119594790557632, 0.488630481309112, 0.146585935553368, 0.456692234320686},
+    {-0.096053864746601, -0.0585120870225411, -0.0543309414249183, 0.75739729013635, 0.227214213208259, 0.224285389849452},
+    {-0.0603987775714151, -0.124504469204174, 0.271876837668966, 0.651676269947229, 0.19549860142211, 0.0658515377372836},
+    {-0.0217044058396818, -0.0643063527627086, 0.723813068870285, 0.273311911925214, 0.0819917787365633, 0.00689399907032842},
+    {-0.0409849230988147, 0.759842524889054, -0.036640207614552, 0.145727572487076, 0.00717255684496521, 0.164882476492272},
+    {-0.034790535089082, 0.404143384962011, -0.119594790557632, 0.605418365816316, 0.0297980510461639, 0.115025523822223},
+    {-0.0249744559383748, 0.03820389372017, -0.0543309414249183, 0.938423301877431, 0.0461882014671775, 0.0564900002985145},
+    {-0.0138776265525463, -0.121759885907613, 0.271876837668966, 0.807433832894958, 0.0397410384743822, 0.0165858034218536},
+    {-0.00457955736373811, -0.0762735703276687, 0.723813068870285, 0.338636367163553, 0.0166673234982245, 0.00173636815934486}};
+    
+    // Array of non-zero columns
+    static const unsigned int nzc0[6] = {0, 1, 2, 3, 4, 5};
+    // Array of non-zero columns
+    static const unsigned int nzc3[6] = {6, 7, 8, 9, 10, 11};
+    static const double FE1_C0_D01[25][5] = \
+    {{-2.66059019751491, -0.840760571794125, 0.180170374279215, 3.50135076930903, -0.180170374279215},
+    {-2.05746131912512, -0.207946328505567, 0.150485009380445, 2.26540764763069, -0.150485009380445},
+    {-1.14264217923257, 0.751899240989545, 0.105458579777884, 0.390742938243026, -0.105458579777884},
+    {-0.16099972900317, 1.78185709341454, 0.0571431775822861, -1.62085736441137, -0.0571431775822854},
+    {0.624348810664881, 2.60585965680469, 0.0184891538601872, -3.23020846746957, -0.0184891538601858},
+    {-1.95444613358461, -0.840760571794126, 0.886314438209517, 2.79520670537873, -0.886314438209516},
+    {-1.46766348743601, -0.207946328505567, 0.740282841069557, 1.67560981594158, -0.740282841069557},
+    {-0.729317011881439, 0.751899240989545, 0.518783747129016, -0.0225822291081061, -0.518783747129016},
+    {0.0629622614476711, 1.78185709341454, 0.281105168033127, -1.84481935486222, -0.281105168033127},
+    {0.696813589059751, 2.60585965680469, 0.0909539322550576, -3.30267324586444, -0.0909539322550562},
+    {-0.920380285897062, -0.840760571794126, 1.92038028589706, 1.76114085769119, -1.92038028589706},
+    {-0.603973164252783, -0.207946328505567, 1.60397316425278, 0.811919492758351, -1.60397316425278},
+    {-0.124050379505228, 0.751899240989545, 1.12405037950523, -0.627848861484317, -1.12405037950523},
+    {0.390928546707272, 1.78185709341454, 0.609071453292728, -2.17278564012182, -0.609071453292728},
+    {0.802929828402348, 2.60585965680469, 0.197070171597654, -3.40878948520704, -0.197070171597653},
+    {0.113685561790484, -0.840760571794125, 2.95444613358461, 0.727075010003642, -2.95444613358461},
+    {0.259717158930443, -0.207946328505567, 2.46766348743601, -0.0517708304248748, -2.46766348743601},
+    {0.481216252870984, 0.751899240989544, 1.72931701188144, -1.23311549386053, -1.72931701188144},
+    {0.718894831966874, 1.78185709341454, 0.937037738552329, -2.50075192538142, -0.937037738552328},
+    {0.909046067744945, 2.60585965680469, 0.303186410940251, -3.51490572454964, -0.30318641094025},
+    {0.819829625720786, -0.840760571794125, 3.66059019751491, 0.0209309460733398, -3.66059019751491},
+    {0.849514990619556, -0.207946328505567, 3.05746131912512, -0.641568662113988, -3.05746131912512},
+    {0.894541420222117, 0.751899240989544, 2.14264217923257, -1.64644066121166, -2.14264217923257},
+    {0.942856822417715, 1.78185709341454, 1.16099972900317, -2.72471391583226, -1.16099972900317},
+    {0.981510846139815, 2.60585965680469, 0.375651189335121, -3.58737050294451, -0.37565118933512}};
+    
+    // Array of non-zero columns
+    static const unsigned int nzc1[5] = {0, 2, 3, 4, 5};
+    static const double FE1_C0_D10[25][5] = \
+    {{-2.66059019751491, -0.819829625720785, 0.159239428205874, -0.159239428205874, 3.4804198232357},
+    {-2.05746131912512, -0.849514990619555, 0.792053671494433, -0.792053671494433, 2.90697630974468},
+    {-1.14264217923257, -0.894541420222116, 1.75189924098954, -1.75189924098954, 2.03718359945469},
+    {-0.16099972900317, -0.942856822417714, 2.78185709341454, -2.78185709341454, 1.10385655142088},
+    {0.624348810664881, -0.981510846139815, 3.60585965680469, -3.60585965680469, 0.357162035474934},
+    {-1.95444613358461, -0.113685561790483, 0.159239428205875, -0.159239428205875, 2.06813169537509},
+    {-1.46766348743601, -0.259717158930442, 0.792053671494433, -0.792053671494433, 1.72738064636645},
+    {-0.729317011881439, -0.481216252870983, 1.75189924098954, -1.75189924098954, 1.21053326475242},
+    {0.0629622614476713, -0.718894831966873, 2.78185709341454, -2.78185709341454, 0.655932570519202},
+    {0.696813589059752, -0.909046067744944, 3.60585965680469, -3.60585965680469, 0.212232478685193},
+    {-0.920380285897062, 0.920380285897063, 0.159239428205875, -0.159239428205875, 0},
+    {-0.603973164252783, 0.603973164252784, 0.792053671494433, -0.792053671494433, 0},
+    {-0.124050379505228, 0.124050379505228, 1.75189924098954, -1.75189924098954, 0},
+    {0.390928546707273, -0.390928546707272, 2.78185709341454, -2.78185709341454, 0},
+    {0.802929828402348, -0.802929828402348, 3.60585965680469, -3.60585965680469, 0},
+    {0.113685561790483, 1.95444613358461, 0.159239428205875, -0.159239428205875, -2.06813169537509},
+    {0.259717158930442, 1.46766348743601, 0.792053671494433, -0.792053671494433, -1.72738064636645},
+    {0.481216252870984, 0.729317011881439, 1.75189924098954, -1.75189924098954, -1.21053326475242},
+    {0.718894831966873, -0.0629622614476713, 2.78185709341454, -2.78185709341454, -0.655932570519202},
+    {0.909046067744945, -0.696813589059751, 3.60585965680469, -3.60585965680469, -0.212232478685194},
+    {0.819829625720786, 2.66059019751491, 0.159239428205876, -0.159239428205876, -3.4804198232357},
+    {0.849514990619555, 2.05746131912512, 0.792053671494433, -0.792053671494433, -2.90697630974468},
+    {0.894541420222116, 1.14264217923257, 1.75189924098954, -1.75189924098954, -2.03718359945469},
+    {0.942856822417715, 0.16099972900317, 2.78185709341454, -2.78185709341454, -1.10385655142088},
+    {0.981510846139815, -0.624348810664881, 3.60585965680469, -3.60585965680469, -0.357162035474935}};
+    
+    // Array of non-zero columns
+    static const unsigned int nzc2[5] = {0, 1, 3, 4, 5};
+    
+    // Number of operations to compute geometry constants: 35
+    const double G0 = 3*det*(Jinv_00*Jinv_00 + Jinv_01*Jinv_01);
+    const double G1 = -3*Jinv_01*det;
+    const double G2 = 3*det*(Jinv_00*Jinv_10 + Jinv_01*Jinv_11);
+    const double G3 = -0.5*det*w[1][0]*w[2][0];
+    const double G4 = det*(Jinv_00*Jinv_00 + Jinv_01*Jinv_01);
+    const double G5 = det*(Jinv_10*Jinv_10 + Jinv_11*Jinv_11);
+    const double G6 = det*(Jinv_00*Jinv_10 + Jinv_01*Jinv_11);
+    const double G7 = det*w[2][0];
+    const double G8 = -3*Jinv_11*det;
+    const double G9 = 3*det*(Jinv_10*Jinv_10 + Jinv_11*Jinv_11);
+    
+    // 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: 21660
+    
+    // Loop quadrature points for integral
+    // Number of operations to compute element tensor for following IP loop = 21625
+    for (unsigned int ip = 0; ip < 25; ip++)
+    {
+      
+      // Function declarations
+      double F0 = 0;
+      double F1 = 0;
+      double F2 = 0;
+      
+      // Total number of operations to compute function values = 20
+      for (unsigned int r = 0; r < 5; r++)
+      {
+        F1 += FE1_C0_D10[ip][r]*w[0][nzc2[r]];
+        F2 += FE1_C0_D01[ip][r]*w[0][nzc1[r]];
+      }// end loop over 'r'
+      
+      // Total number of operations to compute function values = 12
+      for (unsigned int r = 0; r < 6; r++)
+      {
+        F0 += FE1_C0[ip][r]*w[0][nzc3[r]];
+      }// end loop over 'r'
+      
+      // Number of operations to compute ip constants: 29
+      // Number of operations: 7
+      const double Gip0 = F0*F0*W25[ip]*(G1 + F1*G0 + F2*G2);
+      
+      // Number of operations: 1
+      const double Gip1 = G3*W25[ip];
+      
+      // Number of operations: 4
+      const double Gip2 = F0*F0*F0*G4*W25[ip];
+      
+      // Number of operations: 4
+      const double Gip3 = F0*F0*F0*G5*W25[ip];
+      
+      // Number of operations: 1
+      const double Gip4 = W25[ip]*det;
+      
+      // Number of operations: 4
+      const double Gip5 = F0*F0*F0*G6*W25[ip];
+      
+      // Number of operations: 1
+      const double Gip6 = G7*W25[ip];
+      
+      // Number of operations: 7
+      const double Gip7 = F0*F0*W25[ip]*(G8 + F1*G2 + F2*G9);
+      
+      
+      // Number of operations for primary indices: 324
+      for (unsigned int j = 0; j < 6; j++)
+      {
+        for (unsigned int k = 0; k < 6; k++)
+        {
+          // Number of operations to compute entry: 3
+          A[nzc3[j]*12 + nzc0[k]] += FE1_C0[ip][j]*FE1_C0[ip][k]*Gip1;
+          // Number of operations to compute entry: 3
+          A[nzc3[j]*12 + nzc3[k]] += FE1_C0[ip][j]*FE1_C0[ip][k]*Gip4;
+          // Number of operations to compute entry: 3
+          A[nzc0[j]*12 + nzc0[k]] += FE1_C0[ip][j]*FE1_C0[ip][k]*Gip6;
+        }// 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[nzc2[j]*12 + nzc3[k]] += FE1_C0[ip][k]*FE1_C0_D10[ip][j]*Gip0;
+          // Number of operations to compute entry: 3
+          A[nzc1[j]*12 + nzc3[k]] += FE1_C0[ip][k]*FE1_C0_D01[ip][j]*Gip7;
+        }// 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[nzc2[j]*12 + nzc2[k]] += FE1_C0_D10[ip][j]*FE1_C0_D10[ip][k]*Gip2;
+          // Number of operations to compute entry: 3
+          A[nzc1[j]*12 + nzc1[k]] += FE1_C0_D01[ip][j]*FE1_C0_D01[ip][k]*Gip3;
+          // Number of operations to compute entry: 3
+          A[nzc2[j]*12 + nzc1[k]] += FE1_C0_D01[ip][k]*FE1_C0_D10[ip][j]*Gip5;
+          // Number of operations to compute entry: 3
+          A[nzc1[j]*12 + nzc2[k]] += FE1_C0_D01[ip][j]*FE1_C0_D10[ip][k]*Gip5;
+        }// end loop over 'k'
+      }// end loop over 'j'
+    }// end loop over 'ip'
+}
+
+/// Constructor
+solitarywave2d_0_cell_integral_0::solitarywave2d_0_cell_integral_0() : ufc::cell_integral()
+{
+    // Do nothing
+}
+
+/// Destructor
+solitarywave2d_0_cell_integral_0::~solitarywave2d_0_cell_integral_0()
+{
+    // Do nothing
+}
+
+/// Tabulate the tensor for the contribution from a local cell
+void solitarywave2d_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
+solitarywave2d_0_exterior_facet_integral_0_quadrature::solitarywave2d_0_exterior_facet_integral_0_quadrature() : ufc::exterior_facet_integral()
+{
+    // Do nothing
+}
+
+/// Destructor
+solitarywave2d_0_exterior_facet_integral_0_quadrature::~solitarywave2d_0_exterior_facet_integral_0_quadrature()
+{
+    // Do nothing
+}
+
+/// Tabulate the tensor for the contribution from a local exterior facet
+void solitarywave2d_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
+    
+    // Compute determinant of Jacobian
+    
+    // Compute inverse of Jacobian
+    
+    // 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 n1 = direction ? -dx0 / det : dx0 / det;
+    
+    
+    // Array of quadrature weights
+    static const double W5[5] = {0.118463442528094, 0.239314335249683, 0.284444444444444, 0.239314335249683, 0.118463442528094};
+    // Quadrature points on the UFC reference element: (0.046910077030668), (0.230765344947158), (0.5), (0.769234655052841), (0.953089922969332)
+    
+    // Value of basis functions at quadrature points.
+    static const double FE0_f0_C0[5][3] = \
+    {{0.863670879562042, -0.0425089663766216, 0.178838086814579},
+    {0.414209254015687, -0.124260056089996, 0.71005080207431},
+    {0, 0, 1},
+    {-0.124260056089996, 0.414209254015687, 0.71005080207431},
+    {-0.0425089663766215, 0.863670879562042, 0.178838086814579}};
+    
+    // Array of non-zero columns
+    static const unsigned int nzc1[3] = {7, 8, 9};
+    // Array of non-zero columns
+    static const unsigned int nzc0[3] = {1, 2, 3};
+    // Array of non-zero columns
+    static const unsigned int nzc5[3] = {6, 7, 11};
+    // Array of non-zero columns
+    static const unsigned int nzc4[3] = {0, 1, 5};
+    // Array of non-zero columns
+    static const unsigned int nzc2[3] = {0, 2, 4};
+    // Array of non-zero columns
+    static const unsigned int nzc3[3] = {6, 8, 10};
+    
+    // Number of operations to compute geometry constants: 2
+    // Should be added to total operation count.
+    const double G0 = 3*det*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): 180
+      
+      // Loop quadrature points for integral
+      // Number of operations to compute element tensor for following IP loop = 180
+      for (unsigned int ip = 0; ip < 5; ip++)
+      {
+        
+        // Function declarations
+        double F0 = 0;
+        
+        // Total number of operations to compute function values = 6
+        for (unsigned int r = 0; r < 3; r++)
+        {
+          F0 += FE0_f0_C0[ip][r]*w[0][nzc1[r]];
+        }// end loop over 'r'
+        
+        // Number of operations to compute ip constants: 3
+        // Number of operations: 3
+        const double Gip0 = F0*F0*G0*W5[ip];
+        
+        
+        // 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[nzc0[j]*12 + nzc1[k]] += FE0_f0_C0[ip][j]*FE0_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): 180
+      
+      // Loop quadrature points for integral
+      // Number of operations to compute element tensor for following IP loop = 180
+      for (unsigned int ip = 0; ip < 5; ip++)
+      {
+        
+        // Function declarations
+        double F0 = 0;
+        
+        // Total number of operations to compute function values = 6
+        for (unsigned int r = 0; r < 3; r++)
+        {
+          F0 += FE0_f0_C0[ip][r]*w[0][nzc3[r]];
+        }// end loop over 'r'
+        
+        // Number of operations to compute ip constants: 3
+        // Number of operations: 3
+        const double Gip0 = F0*F0*G0*W5[ip];
+        
+        
+        // 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[nzc2[j]*12 + nzc3[k]] += FE0_f0_C0[ip][j]*FE0_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): 180
+      
+      // Loop quadrature points for integral
+      // Number of operations to compute element tensor for following IP loop = 180
+      for (unsigned int ip = 0; ip < 5; ip++)
+      {
+        
+        // Function declarations
+        double F0 = 0;
+        
+        // Total number of operations to compute function values = 6
+        for (unsigned int r = 0; r < 3; r++)
+        {
+          F0 += FE0_f0_C0[ip][r]*w[0][nzc5[r]];
+        }// end loop over 'r'
+        
+        // Number of operations to compute ip constants: 3
+        // Number of operations: 3
+        const double Gip0 = F0*F0*G0*W5[ip];
+        
+        
+        // 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[nzc4[j]*12 + nzc5[k]] += FE0_f0_C0[ip][j]*FE0_f0_C0[ip][k]*Gip0;
+          }// end loop over 'k'
+        }// end loop over 'j'
+      }// end loop over 'ip'
+      }
+      break;
+    }
+}
+
+/// Constructor
+solitarywave2d_0_exterior_facet_integral_0::solitarywave2d_0_exterior_facet_integral_0() : ufc::exterior_facet_integral()
+{
+    // Do nothing
+}
+
+/// Destructor
+solitarywave2d_0_exterior_facet_integral_0::~solitarywave2d_0_exterior_facet_integral_0()
+{
+    // Do nothing
+}
+
+/// Tabulate the tensor for the contribution from a local exterior facet
+void solitarywave2d_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
+solitarywave2d_form_0::solitarywave2d_form_0() : ufc::form()
+{
+    // Do nothing
+}
+
+/// Destructor
+solitarywave2d_form_0::~solitarywave2d_form_0()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the form
+const char* solitarywave2d_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(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(Constant(Cell('triangle', 1, Space(2)), 2), Product(FloatValue(0.5, (), (), {}), Constant(Cell('triangle', 1, Space(2)), 1))))))), 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})), 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(1),), {FixedIndex(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, (), (), {}))), 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(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(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(Constant(Cell('triangle', 1, Space(2)), 2), 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})))), 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(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(2),), {Index(2): 2})), MultiIndex((FixedIndex(0),), {})), 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})), 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, (), (), {})))), 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(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(2),), {Index(2): 2})), MultiIndex((FixedIndex(0),), {})), MultiIndex((Index(2),), {Index(2): 2})), MultiIndex((Index(1),), {Index(1): 2}))), MultiIndex((Index(1),), {Index(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(1),), {FixedIndex(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, (), (), {}))), 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(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}))))))))))), Measure('cell', 0, None)), Integral(Product(Indexed(FacetNormal(Cell('triangle', 1, Space(2))), MultiIndex((FixedIndex(1),), {FixedIndex(1): 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})), 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(1),), {FixedIndex(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, (), (), {}))), 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(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})))))))), Measure('exterior_facet', 0, None))])";
+}
+
+/// Return the rank of the global tensor (r)
+unsigned int solitarywave2d_form_0::rank() const
+{
+    return 2;
+}
+
+/// Return the number of coefficients (n)
+unsigned int solitarywave2d_form_0::num_coefficients() const
+{
+    return 3;
+}
+
+/// Return the number of cell integrals
+unsigned int solitarywave2d_form_0::num_cell_integrals() const
+{
+    return 1;
+}
+
+/// Return the number of exterior facet integrals
+unsigned int solitarywave2d_form_0::num_exterior_facet_integrals() const
+{
+    return 1;
+}
+
+/// Return the number of interior facet integrals
+unsigned int solitarywave2d_form_0::num_interior_facet_integrals() const
+{
+    return 0;
+}
+
+/// Create a new finite element for argument function i
+ufc::finite_element* solitarywave2d_form_0::create_finite_element(unsigned int i) const
+{
+    switch ( i )
+    {
+    case 0:
+      return new solitarywave2d_0_finite_element_0();
+      break;
+    case 1:
+      return new solitarywave2d_0_finite_element_1();
+      break;
+    case 2:
+      return new solitarywave2d_0_finite_element_2();
+      break;
+    case 3:
+      return new solitarywave2d_0_finite_element_3();
+      break;
+    case 4:
+      return new solitarywave2d_0_finite_element_4();
+      break;
+    }
+    return 0;
+}
+
+/// Create a new dof map for argument function i
+ufc::dof_map* solitarywave2d_form_0::create_dof_map(unsigned int i) const
+{
+    switch ( i )
+    {
+    case 0:
+      return new solitarywave2d_0_dof_map_0();
+      break;
+    case 1:
+      return new solitarywave2d_0_dof_map_1();
+      break;
+    case 2:
+      return new solitarywave2d_0_dof_map_2();
+      break;
+    case 3:
+      return new solitarywave2d_0_dof_map_3();
+      break;
+    case 4:
+      return new solitarywave2d_0_dof_map_4();
+      break;
+    }
+    return 0;
+}
+
+/// Create a new cell integral on sub domain i
+ufc::cell_integral* solitarywave2d_form_0::create_cell_integral(unsigned int i) const
+{
+    return new solitarywave2d_0_cell_integral_0();
+}
+
+/// Create a new exterior facet integral on sub domain i
+ufc::exterior_facet_integral* solitarywave2d_form_0::create_exterior_facet_integral(unsigned int i) const
+{
+    return new solitarywave2d_0_exterior_facet_integral_0();
+}
+
+/// Create a new interior facet integral on sub domain i
+ufc::interior_facet_integral* solitarywave2d_form_0::create_interior_facet_integral(unsigned int i) const
+{
+    return 0;
+}
+
+
+/// Constructor
+solitarywave2d_1_finite_element_0_0::solitarywave2d_1_finite_element_0_0() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+solitarywave2d_1_finite_element_0_0::~solitarywave2d_1_finite_element_0_0()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* solitarywave2d_1_finite_element_0_0::signature() const
+{
+    return "FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
+}
+
+/// Return the cell shape
+ufc::shape solitarywave2d_1_finite_element_0_0::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int solitarywave2d_1_finite_element_0_0::space_dimension() const
+{
+    return 6;
+}
+
+/// Return the rank of the value space
+unsigned int solitarywave2d_1_finite_element_0_0::value_rank() const
+{
+    return 0;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int solitarywave2d_1_finite_element_0_0::value_dimension(unsigned int i) const
+{
+    return 1;
+}
+
+/// Evaluate basis function i at given point in cell
+void solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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* solitarywave2d_1_finite_element_0_0::create_sub_element(unsigned int i) const
+{
+    return new solitarywave2d_1_finite_element_0_0();
+}
+
+
+/// Constructor
+solitarywave2d_1_finite_element_0_1::solitarywave2d_1_finite_element_0_1() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+solitarywave2d_1_finite_element_0_1::~solitarywave2d_1_finite_element_0_1()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* solitarywave2d_1_finite_element_0_1::signature() const
+{
+    return "FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
+}
+
+/// Return the cell shape
+ufc::shape solitarywave2d_1_finite_element_0_1::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int solitarywave2d_1_finite_element_0_1::space_dimension() const
+{
+    return 6;
+}
+
+/// Return the rank of the value space
+unsigned int solitarywave2d_1_finite_element_0_1::value_rank() const
+{
+    return 0;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int solitarywave2d_1_finite_element_0_1::value_dimension(unsigned int i) const
+{
+    return 1;
+}
+
+/// Evaluate basis function i at given point in cell
+void solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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* solitarywave2d_1_finite_element_0_1::create_sub_element(unsigned int i) const
+{
+    return new solitarywave2d_1_finite_element_0_1();
+}
+
+
+/// Constructor
+solitarywave2d_1_finite_element_0::solitarywave2d_1_finite_element_0() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+solitarywave2d_1_finite_element_0::~solitarywave2d_1_finite_element_0()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* solitarywave2d_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 solitarywave2d_1_finite_element_0::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int solitarywave2d_1_finite_element_0::space_dimension() const
+{
+    return 12;
+}
+
+/// Return the rank of the value space
+unsigned int solitarywave2d_1_finite_element_0::value_rank() const
+{
+    return 1;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int solitarywave2d_1_finite_element_0::value_dimension(unsigned int i) const
+{
+    return 2;
+}
+
+/// Evaluate basis function i at given point in cell
+void solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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* solitarywave2d_1_finite_element_0::create_sub_element(unsigned int i) const
+{
+    switch ( i )
+    {
+    case 0:
+      return new solitarywave2d_1_finite_element_0_0();
+      break;
+    case 1:
+      return new solitarywave2d_1_finite_element_0_1();
+      break;
+    }
+    return 0;
+}
+
+
+/// Constructor
+solitarywave2d_1_finite_element_1_0::solitarywave2d_1_finite_element_1_0() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+solitarywave2d_1_finite_element_1_0::~solitarywave2d_1_finite_element_1_0()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* solitarywave2d_1_finite_element_1_0::signature() const
+{
+    return "FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
+}
+
+/// Return the cell shape
+ufc::shape solitarywave2d_1_finite_element_1_0::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int solitarywave2d_1_finite_element_1_0::space_dimension() const
+{
+    return 6;
+}
+
+/// Return the rank of the value space
+unsigned int solitarywave2d_1_finite_element_1_0::value_rank() const
+{
+    return 0;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int solitarywave2d_1_finite_element_1_0::value_dimension(unsigned int i) const
+{
+    return 1;
+}
+
+/// Evaluate basis function i at given point in cell
+void solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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* solitarywave2d_1_finite_element_1_0::create_sub_element(unsigned int i) const
+{
+    return new solitarywave2d_1_finite_element_1_0();
+}
+
+
+/// Constructor
+solitarywave2d_1_finite_element_1_1::solitarywave2d_1_finite_element_1_1() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+solitarywave2d_1_finite_element_1_1::~solitarywave2d_1_finite_element_1_1()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* solitarywave2d_1_finite_element_1_1::signature() const
+{
+    return "FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
+}
+
+/// Return the cell shape
+ufc::shape solitarywave2d_1_finite_element_1_1::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int solitarywave2d_1_finite_element_1_1::space_dimension() const
+{
+    return 6;
+}
+
+/// Return the rank of the value space
+unsigned int solitarywave2d_1_finite_element_1_1::value_rank() const
+{
+    return 0;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int solitarywave2d_1_finite_element_1_1::value_dimension(unsigned int i) const
+{
+    return 1;
+}
+
+/// Evaluate basis function i at given point in cell
+void solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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* solitarywave2d_1_finite_element_1_1::create_sub_element(unsigned int i) const
+{
+    return new solitarywave2d_1_finite_element_1_1();
+}
+
+
+/// Constructor
+solitarywave2d_1_finite_element_1::solitarywave2d_1_finite_element_1() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+solitarywave2d_1_finite_element_1::~solitarywave2d_1_finite_element_1()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* solitarywave2d_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 solitarywave2d_1_finite_element_1::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int solitarywave2d_1_finite_element_1::space_dimension() const
+{
+    return 12;
+}
+
+/// Return the rank of the value space
+unsigned int solitarywave2d_1_finite_element_1::value_rank() const
+{
+    return 1;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int solitarywave2d_1_finite_element_1::value_dimension(unsigned int i) const
+{
+    return 2;
+}
+
+/// Evaluate basis function i at given point in cell
+void solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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* solitarywave2d_1_finite_element_1::create_sub_element(unsigned int i) const
+{
+    switch ( i )
+    {
+    case 0:
+      return new solitarywave2d_1_finite_element_1_0();
+      break;
+    case 1:
+      return new solitarywave2d_1_finite_element_1_1();
+      break;
+    }
+    return 0;
+}
+
+
+/// Constructor
+solitarywave2d_1_finite_element_2::solitarywave2d_1_finite_element_2() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+solitarywave2d_1_finite_element_2::~solitarywave2d_1_finite_element_2()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* solitarywave2d_1_finite_element_2::signature() const
+{
+    return "FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 0)";
+}
+
+/// Return the cell shape
+ufc::shape solitarywave2d_1_finite_element_2::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int solitarywave2d_1_finite_element_2::space_dimension() const
+{
+    return 1;
+}
+
+/// Return the rank of the value space
+unsigned int solitarywave2d_1_finite_element_2::value_rank() const
+{
+    return 0;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int solitarywave2d_1_finite_element_2::value_dimension(unsigned int i) const
+{
+    return 1;
+}
+
+/// Evaluate basis function i at given point in cell
+void solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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* solitarywave2d_1_finite_element_2::create_sub_element(unsigned int i) const
+{
+    return new solitarywave2d_1_finite_element_2();
+}
+
+
+/// Constructor
+solitarywave2d_1_finite_element_3::solitarywave2d_1_finite_element_3() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+solitarywave2d_1_finite_element_3::~solitarywave2d_1_finite_element_3()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* solitarywave2d_1_finite_element_3::signature() const
+{
+    return "FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 0)";
+}
+
+/// Return the cell shape
+ufc::shape solitarywave2d_1_finite_element_3::cell_shape() const
+{
+    return ufc::triangle;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int solitarywave2d_1_finite_element_3::space_dimension() const
+{
+    return 1;
+}
+
+/// Return the rank of the value space
+unsigned int solitarywave2d_1_finite_element_3::value_rank() const
+{
+    return 0;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int solitarywave2d_1_finite_element_3::value_dimension(unsigned int i) const
+{
+    return 1;
+}
+
+/// Evaluate basis function i at given point in cell
+void solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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* solitarywave2d_1_finite_element_3::create_sub_element(unsigned int i) const
+{
+    return new solitarywave2d_1_finite_element_3();
+}
+
+/// Constructor
+solitarywave2d_1_dof_map_0_0::solitarywave2d_1_dof_map_0_0() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+solitarywave2d_1_dof_map_0_0::~solitarywave2d_1_dof_map_0_0()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_1_dof_map_0_0::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int solitarywave2d_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 solitarywave2d_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 solitarywave2d_1_dof_map_0_0::max_local_dimension() const
+{
+    return 6;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int solitarywave2d_1_dof_map_0_0::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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* solitarywave2d_1_dof_map_0_0::create_sub_dof_map(unsigned int i) const
+{
+    return new solitarywave2d_1_dof_map_0_0();
+}
+
+
+/// Constructor
+solitarywave2d_1_dof_map_0_1::solitarywave2d_1_dof_map_0_1() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+solitarywave2d_1_dof_map_0_1::~solitarywave2d_1_dof_map_0_1()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_1_dof_map_0_1::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int solitarywave2d_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 solitarywave2d_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 solitarywave2d_1_dof_map_0_1::max_local_dimension() const
+{
+    return 6;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int solitarywave2d_1_dof_map_0_1::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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* solitarywave2d_1_dof_map_0_1::create_sub_dof_map(unsigned int i) const
+{
+    return new solitarywave2d_1_dof_map_0_1();
+}
+
+
+/// Constructor
+solitarywave2d_1_dof_map_0::solitarywave2d_1_dof_map_0() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+solitarywave2d_1_dof_map_0::~solitarywave2d_1_dof_map_0()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_1_dof_map_0::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void solitarywave2d_1_dof_map_0::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int solitarywave2d_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 solitarywave2d_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 solitarywave2d_1_dof_map_0::max_local_dimension() const
+{
+    return 12;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int solitarywave2d_1_dof_map_0::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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* solitarywave2d_1_dof_map_0::create_sub_dof_map(unsigned int i) const
+{
+    switch ( i )
+    {
+    case 0:
+      return new solitarywave2d_1_dof_map_0_0();
+      break;
+    case 1:
+      return new solitarywave2d_1_dof_map_0_1();
+      break;
+    }
+    return 0;
+}
+
+
+/// Constructor
+solitarywave2d_1_dof_map_1_0::solitarywave2d_1_dof_map_1_0() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+solitarywave2d_1_dof_map_1_0::~solitarywave2d_1_dof_map_1_0()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_1_dof_map_1_0::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int solitarywave2d_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 solitarywave2d_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 solitarywave2d_1_dof_map_1_0::max_local_dimension() const
+{
+    return 6;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int solitarywave2d_1_dof_map_1_0::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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* solitarywave2d_1_dof_map_1_0::create_sub_dof_map(unsigned int i) const
+{
+    return new solitarywave2d_1_dof_map_1_0();
+}
+
+
+/// Constructor
+solitarywave2d_1_dof_map_1_1::solitarywave2d_1_dof_map_1_1() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+solitarywave2d_1_dof_map_1_1::~solitarywave2d_1_dof_map_1_1()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_1_dof_map_1_1::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int solitarywave2d_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 solitarywave2d_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 solitarywave2d_1_dof_map_1_1::max_local_dimension() const
+{
+    return 6;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int solitarywave2d_1_dof_map_1_1::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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* solitarywave2d_1_dof_map_1_1::create_sub_dof_map(unsigned int i) const
+{
+    return new solitarywave2d_1_dof_map_1_1();
+}
+
+
+/// Constructor
+solitarywave2d_1_dof_map_1::solitarywave2d_1_dof_map_1() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+solitarywave2d_1_dof_map_1::~solitarywave2d_1_dof_map_1()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_1_dof_map_1::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void solitarywave2d_1_dof_map_1::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int solitarywave2d_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 solitarywave2d_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 solitarywave2d_1_dof_map_1::max_local_dimension() const
+{
+    return 12;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int solitarywave2d_1_dof_map_1::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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* solitarywave2d_1_dof_map_1::create_sub_dof_map(unsigned int i) const
+{
+    switch ( i )
+    {
+    case 0:
+      return new solitarywave2d_1_dof_map_1_0();
+      break;
+    case 1:
+      return new solitarywave2d_1_dof_map_1_1();
+      break;
+    }
+    return 0;
+}
+
+
+/// Constructor
+solitarywave2d_1_dof_map_2::solitarywave2d_1_dof_map_2() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+solitarywave2d_1_dof_map_2::~solitarywave2d_1_dof_map_2()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_1_dof_map_2::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void solitarywave2d_1_dof_map_2::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int solitarywave2d_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 solitarywave2d_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 solitarywave2d_1_dof_map_2::max_local_dimension() const
+{
+    return 1;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int solitarywave2d_1_dof_map_2::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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* solitarywave2d_1_dof_map_2::create_sub_dof_map(unsigned int i) const
+{
+    return new solitarywave2d_1_dof_map_2();
+}
+
+
+/// Constructor
+solitarywave2d_1_dof_map_3::solitarywave2d_1_dof_map_3() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+solitarywave2d_1_dof_map_3::~solitarywave2d_1_dof_map_3()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_1_dof_map_3::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void solitarywave2d_1_dof_map_3::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int solitarywave2d_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 solitarywave2d_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 solitarywave2d_1_dof_map_3::max_local_dimension() const
+{
+    return 1;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int solitarywave2d_1_dof_map_3::geometric_dimension() const
+{
+    return 2;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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* solitarywave2d_1_dof_map_3::create_sub_dof_map(unsigned int i) const
+{
+    return new solitarywave2d_1_dof_map_3();
+}
+
+
+/// Constructor
+solitarywave2d_1_cell_integral_0_quadrature::solitarywave2d_1_cell_integral_0_quadrature() : ufc::cell_integral()
+{
+    // Do nothing
+}
+
+/// Destructor
+solitarywave2d_1_cell_integral_0_quadrature::~solitarywave2d_1_cell_integral_0_quadrature()
+{
+    // Do nothing
+}
+
+/// Tabulate the tensor for the contribution from a local cell
+void solitarywave2d_1_cell_integral_0_quadrature::tabulate_tensor(double* A,
                                     const double * const * w,
                                     const ufc::cell& c) const
 {
@@ -7649,5962 +13605,6 @@ void solitarywave2d_0_cell_integral_0_qu
     // Array of non-zero columns
     static const unsigned int nzc2[5] = {0, 1, 3, 4, 5};
     
-    // Number of operations to compute geometry constants: 35
-    const double G0 = 3*det*(Jinv_00*Jinv_00 + Jinv_01*Jinv_01);
-    const double G1 = -3*Jinv_01*det;
-    const double G2 = 3*det*(Jinv_00*Jinv_10 + Jinv_01*Jinv_11);
-    const double G3 = -0.5*det*w[1][0]*w[2][0];
-    const double G4 = det*(Jinv_00*Jinv_00 + Jinv_01*Jinv_01);
-    const double G5 = det*(Jinv_10*Jinv_10 + Jinv_11*Jinv_11);
-    const double G6 = det*(Jinv_00*Jinv_10 + Jinv_01*Jinv_11);
-    const double G7 = det*w[2][0];
-    const double G8 = -3*Jinv_11*det;
-    const double G9 = 3*det*(Jinv_10*Jinv_10 + Jinv_11*Jinv_11);
-    
-    // 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: 21660
-    
-    // Loop quadrature points for integral
-    // Number of operations to compute element tensor for following IP loop = 21625
-    for (unsigned int ip = 0; ip < 25; ip++)
-    {
-      
-      // Function declarations
-      double F0 = 0;
-      double F1 = 0;
-      double F2 = 0;
-      
-      // Total number of operations to compute function values = 20
-      for (unsigned int r = 0; r < 5; r++)
-      {
-        F1 += FE1_C0_D10[ip][r]*w[0][nzc2[r]];
-        F2 += FE1_C0_D01[ip][r]*w[0][nzc1[r]];
-      }// end loop over 'r'
-      
-      // Total number of operations to compute function values = 12
-      for (unsigned int r = 0; r < 6; r++)
-      {
-        F0 += FE1_C0[ip][r]*w[0][nzc3[r]];
-      }// end loop over 'r'
-      
-      // Number of operations to compute ip constants: 29
-      // Number of operations: 7
-      const double Gip0 = F0*F0*W25[ip]*(G1 + F1*G0 + F2*G2);
-      
-      // Number of operations: 1
-      const double Gip1 = G3*W25[ip];
-      
-      // Number of operations: 4
-      const double Gip2 = F0*F0*F0*G4*W25[ip];
-      
-      // Number of operations: 4
-      const double Gip3 = F0*F0*F0*G5*W25[ip];
-      
-      // Number of operations: 1
-      const double Gip4 = W25[ip]*det;
-      
-      // Number of operations: 4
-      const double Gip5 = F0*F0*F0*G6*W25[ip];
-      
-      // Number of operations: 1
-      const double Gip6 = G7*W25[ip];
-      
-      // Number of operations: 7
-      const double Gip7 = F0*F0*W25[ip]*(G8 + F1*G2 + F2*G9);
-      
-      
-      // Number of operations for primary indices: 324
-      for (unsigned int j = 0; j < 6; j++)
-      {
-        for (unsigned int k = 0; k < 6; k++)
-        {
-          // Number of operations to compute entry: 3
-          A[nzc3[j]*12 + nzc0[k]] += FE1_C0[ip][j]*FE1_C0[ip][k]*Gip1;
-          // Number of operations to compute entry: 3
-          A[nzc3[j]*12 + nzc3[k]] += FE1_C0[ip][j]*FE1_C0[ip][k]*Gip4;
-          // Number of operations to compute entry: 3
-          A[nzc0[j]*12 + nzc0[k]] += FE1_C0[ip][j]*FE1_C0[ip][k]*Gip6;
-        }// 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[nzc2[j]*12 + nzc3[k]] += FE1_C0[ip][k]*FE1_C0_D10[ip][j]*Gip0;
-          // Number of operations to compute entry: 3
-          A[nzc1[j]*12 + nzc3[k]] += FE1_C0[ip][k]*FE1_C0_D01[ip][j]*Gip7;
-        }// 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[nzc2[j]*12 + nzc2[k]] += FE1_C0_D10[ip][j]*FE1_C0_D10[ip][k]*Gip2;
-          // Number of operations to compute entry: 3
-          A[nzc1[j]*12 + nzc1[k]] += FE1_C0_D01[ip][j]*FE1_C0_D01[ip][k]*Gip3;
-          // Number of operations to compute entry: 3
-          A[nzc2[j]*12 + nzc1[k]] += FE1_C0_D01[ip][k]*FE1_C0_D10[ip][j]*Gip5;
-          // Number of operations to compute entry: 3
-          A[nzc1[j]*12 + nzc2[k]] += FE1_C0_D01[ip][j]*FE1_C0_D10[ip][k]*Gip5;
-        }// end loop over 'k'
-      }// end loop over 'j'
-    }// end loop over 'ip'
-}
-
-/// Constructor
-solitarywave2d_0_cell_integral_0::solitarywave2d_0_cell_integral_0() : ufc::cell_integral()
-{
-    // Do nothing
-}
-
-/// Destructor
-solitarywave2d_0_cell_integral_0::~solitarywave2d_0_cell_integral_0()
-{
-    // Do nothing
-}
-
-/// Tabulate the tensor for the contribution from a local cell
-void solitarywave2d_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
-solitarywave2d_0_exterior_facet_integral_0_quadrature::solitarywave2d_0_exterior_facet_integral_0_quadrature() : ufc::exterior_facet_integral()
-{
-    // Do nothing
-}
-
-/// Destructor
-solitarywave2d_0_exterior_facet_integral_0_quadrature::~solitarywave2d_0_exterior_facet_integral_0_quadrature()
-{
-    // Do nothing
-}
-
-/// Tabulate the tensor for the contribution from a local exterior facet
-void solitarywave2d_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
-    
-    // Compute determinant of Jacobian
-    
-    // Compute inverse of Jacobian
-    
-    // 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 n1 = direction ? -dx0 / det : dx0 / det;
-    
-    
-    // Array of quadrature weights
-    static const double W5[5] = {0.118463442528094, 0.239314335249683, 0.284444444444444, 0.239314335249683, 0.118463442528094};
-    // Quadrature points on the UFC reference element: (0.046910077030668), (0.230765344947158), (0.5), (0.769234655052841), (0.953089922969332)
-    
-    // Value of basis functions at quadrature points.
-    static const double FE0_f0_C0[5][3] = \
-    {{0.863670879562042, -0.0425089663766216, 0.178838086814579},
-    {0.414209254015687, -0.124260056089996, 0.71005080207431},
-    {0, 0, 1},
-    {-0.124260056089996, 0.414209254015687, 0.71005080207431},
-    {-0.0425089663766216, 0.863670879562042, 0.178838086814579}};
-    
-    // Array of non-zero columns
-    static const unsigned int nzc1[3] = {7, 8, 9};
-    // Array of non-zero columns
-    static const unsigned int nzc0[3] = {1, 2, 3};
-    // Array of non-zero columns
-    static const unsigned int nzc5[3] = {6, 7, 11};
-    // Array of non-zero columns
-    static const unsigned int nzc4[3] = {0, 1, 5};
-    // Array of non-zero columns
-    static const unsigned int nzc2[3] = {0, 2, 4};
-    // Array of non-zero columns
-    static const unsigned int nzc3[3] = {6, 8, 10};
-    
-    // Number of operations to compute geometry constants: 2
-    // Should be added to total operation count.
-    const double G0 = 3*det*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): 180
-      
-      // Loop quadrature points for integral
-      // Number of operations to compute element tensor for following IP loop = 180
-      for (unsigned int ip = 0; ip < 5; ip++)
-      {
-        
-        // Function declarations
-        double F0 = 0;
-        
-        // Total number of operations to compute function values = 6
-        for (unsigned int r = 0; r < 3; r++)
-        {
-          F0 += FE0_f0_C0[ip][r]*w[0][nzc1[r]];
-        }// end loop over 'r'
-        
-        // Number of operations to compute ip constants: 3
-        // Number of operations: 3
-        const double Gip0 = F0*F0*G0*W5[ip];
-        
-        
-        // 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[nzc0[j]*12 + nzc1[k]] += FE0_f0_C0[ip][j]*FE0_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): 180
-      
-      // Loop quadrature points for integral
-      // Number of operations to compute element tensor for following IP loop = 180
-      for (unsigned int ip = 0; ip < 5; ip++)
-      {
-        
-        // Function declarations
-        double F0 = 0;
-        
-        // Total number of operations to compute function values = 6
-        for (unsigned int r = 0; r < 3; r++)
-        {
-          F0 += FE0_f0_C0[ip][r]*w[0][nzc3[r]];
-        }// end loop over 'r'
-        
-        // Number of operations to compute ip constants: 3
-        // Number of operations: 3
-        const double Gip0 = F0*F0*G0*W5[ip];
-        
-        
-        // 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[nzc2[j]*12 + nzc3[k]] += FE0_f0_C0[ip][j]*FE0_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): 180
-      
-      // Loop quadrature points for integral
-      // Number of operations to compute element tensor for following IP loop = 180
-      for (unsigned int ip = 0; ip < 5; ip++)
-      {
-        
-        // Function declarations
-        double F0 = 0;
-        
-        // Total number of operations to compute function values = 6
-        for (unsigned int r = 0; r < 3; r++)
-        {
-          F0 += FE0_f0_C0[ip][r]*w[0][nzc5[r]];
-        }// end loop over 'r'
-        
-        // Number of operations to compute ip constants: 3
-        // Number of operations: 3
-        const double Gip0 = F0*F0*G0*W5[ip];
-        
-        
-        // 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[nzc4[j]*12 + nzc5[k]] += FE0_f0_C0[ip][j]*FE0_f0_C0[ip][k]*Gip0;
-          }// end loop over 'k'
-        }// end loop over 'j'
-      }// end loop over 'ip'
-      }
-      break;
-    }
-}
-
-/// Constructor
-solitarywave2d_0_exterior_facet_integral_0::solitarywave2d_0_exterior_facet_integral_0() : ufc::exterior_facet_integral()
-{
-    // Do nothing
-}
-
-/// Destructor
-solitarywave2d_0_exterior_facet_integral_0::~solitarywave2d_0_exterior_facet_integral_0()
-{
-    // Do nothing
-}
-
-/// Tabulate the tensor for the contribution from a local exterior facet
-void solitarywave2d_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
-solitarywave2d_form_0::solitarywave2d_form_0() : ufc::form()
-{
-    // Do nothing
-}
-
-/// Destructor
-solitarywave2d_form_0::~solitarywave2d_form_0()
-{
-    // Do nothing
-}
-
-/// Return a string identifying the form
-const char* solitarywave2d_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(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(Constant(Cell('triangle', 1, Space(2)), 2), Product(FloatValue(0.5, (), (), {}), Constant(Cell('triangle', 1, Space(2)), 1))))))), 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})), 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(1),), {FixedIndex(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, (), (), {}))), 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(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(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(Constant(Cell('triangle', 1, Space(2)), 2), 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})))), 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(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(2),), {Index(2): 2})), MultiIndex((FixedIndex(0),), {})), 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})), 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, (), (), {})))), 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(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(2),), {Index(2): 2})), MultiIndex((FixedIndex(0),), {})), MultiIndex((Index(2),), {Index(2): 2})), MultiIndex((Index(1),), {Index(1): 2}))), MultiIndex((Index(1),), {Index(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(1),), {FixedIndex(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, (), (), {}))), 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(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}))))))))))), Measure('cell', 0, None)), Integral(Product(Indexed(FacetNormal(Cell('triangle', 1, Space(2))), MultiIndex((FixedIndex(1),), {FixedIndex(1): 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})), 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(1),), {FixedIndex(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, (), (), {}))), 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(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})))))))), Measure('exterior_facet', 0, None))])";
-}
-
-/// Return the rank of the global tensor (r)
-unsigned int solitarywave2d_form_0::rank() const
-{
-    return 2;
-}
-
-/// Return the number of coefficients (n)
-unsigned int solitarywave2d_form_0::num_coefficients() const
-{
-    return 3;
-}
-
-/// Return the number of cell integrals
-unsigned int solitarywave2d_form_0::num_cell_integrals() const
-{
-    return 1;
-}
-
-/// Return the number of exterior facet integrals
-unsigned int solitarywave2d_form_0::num_exterior_facet_integrals() const
-{
-    return 1;
-}
-
-/// Return the number of interior facet integrals
-unsigned int solitarywave2d_form_0::num_interior_facet_integrals() const
-{
-    return 0;
-}
-
-/// Create a new finite element for argument function i
-ufc::finite_element* solitarywave2d_form_0::create_finite_element(unsigned int i) const
-{
-    switch ( i )
-    {
-    case 0:
-      return new solitarywave2d_0_finite_element_0();
-      break;
-    case 1:
-      return new solitarywave2d_0_finite_element_1();
-      break;
-    case 2:
-      return new solitarywave2d_0_finite_element_2();
-      break;
-    case 3:
-      return new solitarywave2d_0_finite_element_3();
-      break;
-    case 4:
-      return new solitarywave2d_0_finite_element_4();
-      break;
-    }
-    return 0;
-}
-
-/// Create a new dof map for argument function i
-ufc::dof_map* solitarywave2d_form_0::create_dof_map(unsigned int i) const
-{
-    switch ( i )
-    {
-    case 0:
-      return new solitarywave2d_0_dof_map_0();
-      break;
-    case 1:
-      return new solitarywave2d_0_dof_map_1();
-      break;
-    case 2:
-      return new solitarywave2d_0_dof_map_2();
-      break;
-    case 3:
-      return new solitarywave2d_0_dof_map_3();
-      break;
-    case 4:
-      return new solitarywave2d_0_dof_map_4();
-      break;
-    }
-    return 0;
-}
-
-/// Create a new cell integral on sub domain i
-ufc::cell_integral* solitarywave2d_form_0::create_cell_integral(unsigned int i) const
-{
-    return new solitarywave2d_0_cell_integral_0();
-}
-
-/// Create a new exterior facet integral on sub domain i
-ufc::exterior_facet_integral* solitarywave2d_form_0::create_exterior_facet_integral(unsigned int i) const
-{
-    return new solitarywave2d_0_exterior_facet_integral_0();
-}
-
-/// Create a new interior facet integral on sub domain i
-ufc::interior_facet_integral* solitarywave2d_form_0::create_interior_facet_integral(unsigned int i) const
-{
-    return 0;
-}
-
-
-/// Constructor
-solitarywave2d_1_finite_element_0_0::solitarywave2d_1_finite_element_0_0() : ufc::finite_element()
-{
-    // Do nothing
-}
-
-/// Destructor
-solitarywave2d_1_finite_element_0_0::~solitarywave2d_1_finite_element_0_0()
-{
-    // Do nothing
-}
-
-/// Return a string identifying the finite element
-const char* solitarywave2d_1_finite_element_0_0::signature() const
-{
-    return "FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
-}
-
-/// Return the cell shape
-ufc::shape solitarywave2d_1_finite_element_0_0::cell_shape() const
-{
-    return ufc::triangle;
-}
-
-/// Return the dimension of the finite element function space
-unsigned int solitarywave2d_1_finite_element_0_0::space_dimension() const
-{
-    return 6;
-}
-
-/// Return the rank of the value space
-unsigned int solitarywave2d_1_finite_element_0_0::value_rank() const
-{
-    return 0;
-}
-
-/// Return the dimension of the value space for axis i
-unsigned int solitarywave2d_1_finite_element_0_0::value_dimension(unsigned int i) const
-{
-    return 1;
-}
-
-/// Evaluate basis function i at given point in cell
-void solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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* solitarywave2d_1_finite_element_0_0::create_sub_element(unsigned int i) const
-{
-    return new solitarywave2d_1_finite_element_0_0();
-}
-
-
-/// Constructor
-solitarywave2d_1_finite_element_0_1::solitarywave2d_1_finite_element_0_1() : ufc::finite_element()
-{
-    // Do nothing
-}
-
-/// Destructor
-solitarywave2d_1_finite_element_0_1::~solitarywave2d_1_finite_element_0_1()
-{
-    // Do nothing
-}
-
-/// Return a string identifying the finite element
-const char* solitarywave2d_1_finite_element_0_1::signature() const
-{
-    return "FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
-}
-
-/// Return the cell shape
-ufc::shape solitarywave2d_1_finite_element_0_1::cell_shape() const
-{
-    return ufc::triangle;
-}
-
-/// Return the dimension of the finite element function space
-unsigned int solitarywave2d_1_finite_element_0_1::space_dimension() const
-{
-    return 6;
-}
-
-/// Return the rank of the value space
-unsigned int solitarywave2d_1_finite_element_0_1::value_rank() const
-{
-    return 0;
-}
-
-/// Return the dimension of the value space for axis i
-unsigned int solitarywave2d_1_finite_element_0_1::value_dimension(unsigned int i) const
-{
-    return 1;
-}
-
-/// Evaluate basis function i at given point in cell
-void solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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* solitarywave2d_1_finite_element_0_1::create_sub_element(unsigned int i) const
-{
-    return new solitarywave2d_1_finite_element_0_1();
-}
-
-
-/// Constructor
-solitarywave2d_1_finite_element_0::solitarywave2d_1_finite_element_0() : ufc::finite_element()
-{
-    // Do nothing
-}
-
-/// Destructor
-solitarywave2d_1_finite_element_0::~solitarywave2d_1_finite_element_0()
-{
-    // Do nothing
-}
-
-/// Return a string identifying the finite element
-const char* solitarywave2d_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 solitarywave2d_1_finite_element_0::cell_shape() const
-{
-    return ufc::triangle;
-}
-
-/// Return the dimension of the finite element function space
-unsigned int solitarywave2d_1_finite_element_0::space_dimension() const
-{
-    return 12;
-}
-
-/// Return the rank of the value space
-unsigned int solitarywave2d_1_finite_element_0::value_rank() const
-{
-    return 1;
-}
-
-/// Return the dimension of the value space for axis i
-unsigned int solitarywave2d_1_finite_element_0::value_dimension(unsigned int i) const
-{
-    return 2;
-}
-
-/// Evaluate basis function i at given point in cell
-void solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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* solitarywave2d_1_finite_element_0::create_sub_element(unsigned int i) const
-{
-    switch ( i )
-    {
-    case 0:
-      return new solitarywave2d_1_finite_element_0_0();
-      break;
-    case 1:
-      return new solitarywave2d_1_finite_element_0_1();
-      break;
-    }
-    return 0;
-}
-
-
-/// Constructor
-solitarywave2d_1_finite_element_1_0::solitarywave2d_1_finite_element_1_0() : ufc::finite_element()
-{
-    // Do nothing
-}
-
-/// Destructor
-solitarywave2d_1_finite_element_1_0::~solitarywave2d_1_finite_element_1_0()
-{
-    // Do nothing
-}
-
-/// Return a string identifying the finite element
-const char* solitarywave2d_1_finite_element_1_0::signature() const
-{
-    return "FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
-}
-
-/// Return the cell shape
-ufc::shape solitarywave2d_1_finite_element_1_0::cell_shape() const
-{
-    return ufc::triangle;
-}
-
-/// Return the dimension of the finite element function space
-unsigned int solitarywave2d_1_finite_element_1_0::space_dimension() const
-{
-    return 6;
-}
-
-/// Return the rank of the value space
-unsigned int solitarywave2d_1_finite_element_1_0::value_rank() const
-{
-    return 0;
-}
-
-/// Return the dimension of the value space for axis i
-unsigned int solitarywave2d_1_finite_element_1_0::value_dimension(unsigned int i) const
-{
-    return 1;
-}
-
-/// Evaluate basis function i at given point in cell
-void solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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* solitarywave2d_1_finite_element_1_0::create_sub_element(unsigned int i) const
-{
-    return new solitarywave2d_1_finite_element_1_0();
-}
-
-
-/// Constructor
-solitarywave2d_1_finite_element_1_1::solitarywave2d_1_finite_element_1_1() : ufc::finite_element()
-{
-    // Do nothing
-}
-
-/// Destructor
-solitarywave2d_1_finite_element_1_1::~solitarywave2d_1_finite_element_1_1()
-{
-    // Do nothing
-}
-
-/// Return a string identifying the finite element
-const char* solitarywave2d_1_finite_element_1_1::signature() const
-{
-    return "FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 2)";
-}
-
-/// Return the cell shape
-ufc::shape solitarywave2d_1_finite_element_1_1::cell_shape() const
-{
-    return ufc::triangle;
-}
-
-/// Return the dimension of the finite element function space
-unsigned int solitarywave2d_1_finite_element_1_1::space_dimension() const
-{
-    return 6;
-}
-
-/// Return the rank of the value space
-unsigned int solitarywave2d_1_finite_element_1_1::value_rank() const
-{
-    return 0;
-}
-
-/// Return the dimension of the value space for axis i
-unsigned int solitarywave2d_1_finite_element_1_1::value_dimension(unsigned int i) const
-{
-    return 1;
-}
-
-/// Evaluate basis function i at given point in cell
-void solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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* solitarywave2d_1_finite_element_1_1::create_sub_element(unsigned int i) const
-{
-    return new solitarywave2d_1_finite_element_1_1();
-}
-
-
-/// Constructor
-solitarywave2d_1_finite_element_1::solitarywave2d_1_finite_element_1() : ufc::finite_element()
-{
-    // Do nothing
-}
-
-/// Destructor
-solitarywave2d_1_finite_element_1::~solitarywave2d_1_finite_element_1()
-{
-    // Do nothing
-}
-
-/// Return a string identifying the finite element
-const char* solitarywave2d_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 solitarywave2d_1_finite_element_1::cell_shape() const
-{
-    return ufc::triangle;
-}
-
-/// Return the dimension of the finite element function space
-unsigned int solitarywave2d_1_finite_element_1::space_dimension() const
-{
-    return 12;
-}
-
-/// Return the rank of the value space
-unsigned int solitarywave2d_1_finite_element_1::value_rank() const
-{
-    return 1;
-}
-
-/// Return the dimension of the value space for axis i
-unsigned int solitarywave2d_1_finite_element_1::value_dimension(unsigned int i) const
-{
-    return 2;
-}
-
-/// Evaluate basis function i at given point in cell
-void solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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* solitarywave2d_1_finite_element_1::create_sub_element(unsigned int i) const
-{
-    switch ( i )
-    {
-    case 0:
-      return new solitarywave2d_1_finite_element_1_0();
-      break;
-    case 1:
-      return new solitarywave2d_1_finite_element_1_1();
-      break;
-    }
-    return 0;
-}
-
-
-/// Constructor
-solitarywave2d_1_finite_element_2::solitarywave2d_1_finite_element_2() : ufc::finite_element()
-{
-    // Do nothing
-}
-
-/// Destructor
-solitarywave2d_1_finite_element_2::~solitarywave2d_1_finite_element_2()
-{
-    // Do nothing
-}
-
-/// Return a string identifying the finite element
-const char* solitarywave2d_1_finite_element_2::signature() const
-{
-    return "FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 0)";
-}
-
-/// Return the cell shape
-ufc::shape solitarywave2d_1_finite_element_2::cell_shape() const
-{
-    return ufc::triangle;
-}
-
-/// Return the dimension of the finite element function space
-unsigned int solitarywave2d_1_finite_element_2::space_dimension() const
-{
-    return 1;
-}
-
-/// Return the rank of the value space
-unsigned int solitarywave2d_1_finite_element_2::value_rank() const
-{
-    return 0;
-}
-
-/// Return the dimension of the value space for axis i
-unsigned int solitarywave2d_1_finite_element_2::value_dimension(unsigned int i) const
-{
-    return 1;
-}
-
-/// Evaluate basis function i at given point in cell
-void solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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* solitarywave2d_1_finite_element_2::create_sub_element(unsigned int i) const
-{
-    return new solitarywave2d_1_finite_element_2();
-}
-
-
-/// Constructor
-solitarywave2d_1_finite_element_3::solitarywave2d_1_finite_element_3() : ufc::finite_element()
-{
-    // Do nothing
-}
-
-/// Destructor
-solitarywave2d_1_finite_element_3::~solitarywave2d_1_finite_element_3()
-{
-    // Do nothing
-}
-
-/// Return a string identifying the finite element
-const char* solitarywave2d_1_finite_element_3::signature() const
-{
-    return "FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 0)";
-}
-
-/// Return the cell shape
-ufc::shape solitarywave2d_1_finite_element_3::cell_shape() const
-{
-    return ufc::triangle;
-}
-
-/// Return the dimension of the finite element function space
-unsigned int solitarywave2d_1_finite_element_3::space_dimension() const
-{
-    return 1;
-}
-
-/// Return the rank of the value space
-unsigned int solitarywave2d_1_finite_element_3::value_rank() const
-{
-    return 0;
-}
-
-/// Return the dimension of the value space for axis i
-unsigned int solitarywave2d_1_finite_element_3::value_dimension(unsigned int i) const
-{
-    return 1;
-}
-
-/// Evaluate basis function i at given point in cell
-void solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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* solitarywave2d_1_finite_element_3::create_sub_element(unsigned int i) const
-{
-    return new solitarywave2d_1_finite_element_3();
-}
-
-/// Constructor
-solitarywave2d_1_dof_map_0_0::solitarywave2d_1_dof_map_0_0() : ufc::dof_map()
-{
-    __global_dimension = 0;
-}
-
-/// Destructor
-solitarywave2d_1_dof_map_0_0::~solitarywave2d_1_dof_map_0_0()
-{
-    // Do nothing
-}
-
-/// Return a string identifying the dof map
-const char* solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_1_dof_map_0_0::init_cell_finalize()
-{
-    // Do nothing
-}
-
-/// Return the dimension of the global finite element function space
-unsigned int solitarywave2d_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 solitarywave2d_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 solitarywave2d_1_dof_map_0_0::max_local_dimension() const
-{
-    return 6;
-}
-
-// Return the geometric dimension of the coordinates this dof map provides
-unsigned int solitarywave2d_1_dof_map_0_0::geometric_dimension() const
-{
-    return 2;
-}
-
-/// Return the number of dofs on each cell facet
-unsigned int solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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* solitarywave2d_1_dof_map_0_0::create_sub_dof_map(unsigned int i) const
-{
-    return new solitarywave2d_1_dof_map_0_0();
-}
-
-
-/// Constructor
-solitarywave2d_1_dof_map_0_1::solitarywave2d_1_dof_map_0_1() : ufc::dof_map()
-{
-    __global_dimension = 0;
-}
-
-/// Destructor
-solitarywave2d_1_dof_map_0_1::~solitarywave2d_1_dof_map_0_1()
-{
-    // Do nothing
-}
-
-/// Return a string identifying the dof map
-const char* solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_1_dof_map_0_1::init_cell_finalize()
-{
-    // Do nothing
-}
-
-/// Return the dimension of the global finite element function space
-unsigned int solitarywave2d_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 solitarywave2d_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 solitarywave2d_1_dof_map_0_1::max_local_dimension() const
-{
-    return 6;
-}
-
-// Return the geometric dimension of the coordinates this dof map provides
-unsigned int solitarywave2d_1_dof_map_0_1::geometric_dimension() const
-{
-    return 2;
-}
-
-/// Return the number of dofs on each cell facet
-unsigned int solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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* solitarywave2d_1_dof_map_0_1::create_sub_dof_map(unsigned int i) const
-{
-    return new solitarywave2d_1_dof_map_0_1();
-}
-
-
-/// Constructor
-solitarywave2d_1_dof_map_0::solitarywave2d_1_dof_map_0() : ufc::dof_map()
-{
-    __global_dimension = 0;
-}
-
-/// Destructor
-solitarywave2d_1_dof_map_0::~solitarywave2d_1_dof_map_0()
-{
-    // Do nothing
-}
-
-/// Return a string identifying the dof map
-const char* solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_1_dof_map_0::init_cell(const ufc::mesh& m,
-                              const ufc::cell& c)
-{
-    // Do nothing
-}
-
-/// Finish initialization of dof map for cells
-void solitarywave2d_1_dof_map_0::init_cell_finalize()
-{
-    // Do nothing
-}
-
-/// Return the dimension of the global finite element function space
-unsigned int solitarywave2d_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 solitarywave2d_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 solitarywave2d_1_dof_map_0::max_local_dimension() const
-{
-    return 12;
-}
-
-// Return the geometric dimension of the coordinates this dof map provides
-unsigned int solitarywave2d_1_dof_map_0::geometric_dimension() const
-{
-    return 2;
-}
-
-/// Return the number of dofs on each cell facet
-unsigned int solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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* solitarywave2d_1_dof_map_0::create_sub_dof_map(unsigned int i) const
-{
-    switch ( i )
-    {
-    case 0:
-      return new solitarywave2d_1_dof_map_0_0();
-      break;
-    case 1:
-      return new solitarywave2d_1_dof_map_0_1();
-      break;
-    }
-    return 0;
-}
-
-
-/// Constructor
-solitarywave2d_1_dof_map_1_0::solitarywave2d_1_dof_map_1_0() : ufc::dof_map()
-{
-    __global_dimension = 0;
-}
-
-/// Destructor
-solitarywave2d_1_dof_map_1_0::~solitarywave2d_1_dof_map_1_0()
-{
-    // Do nothing
-}
-
-/// Return a string identifying the dof map
-const char* solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_1_dof_map_1_0::init_cell_finalize()
-{
-    // Do nothing
-}
-
-/// Return the dimension of the global finite element function space
-unsigned int solitarywave2d_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 solitarywave2d_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 solitarywave2d_1_dof_map_1_0::max_local_dimension() const
-{
-    return 6;
-}
-
-// Return the geometric dimension of the coordinates this dof map provides
-unsigned int solitarywave2d_1_dof_map_1_0::geometric_dimension() const
-{
-    return 2;
-}
-
-/// Return the number of dofs on each cell facet
-unsigned int solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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* solitarywave2d_1_dof_map_1_0::create_sub_dof_map(unsigned int i) const
-{
-    return new solitarywave2d_1_dof_map_1_0();
-}
-
-
-/// Constructor
-solitarywave2d_1_dof_map_1_1::solitarywave2d_1_dof_map_1_1() : ufc::dof_map()
-{
-    __global_dimension = 0;
-}
-
-/// Destructor
-solitarywave2d_1_dof_map_1_1::~solitarywave2d_1_dof_map_1_1()
-{
-    // Do nothing
-}
-
-/// Return a string identifying the dof map
-const char* solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_1_dof_map_1_1::init_cell_finalize()
-{
-    // Do nothing
-}
-
-/// Return the dimension of the global finite element function space
-unsigned int solitarywave2d_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 solitarywave2d_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 solitarywave2d_1_dof_map_1_1::max_local_dimension() const
-{
-    return 6;
-}
-
-// Return the geometric dimension of the coordinates this dof map provides
-unsigned int solitarywave2d_1_dof_map_1_1::geometric_dimension() const
-{
-    return 2;
-}
-
-/// Return the number of dofs on each cell facet
-unsigned int solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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* solitarywave2d_1_dof_map_1_1::create_sub_dof_map(unsigned int i) const
-{
-    return new solitarywave2d_1_dof_map_1_1();
-}
-
-
-/// Constructor
-solitarywave2d_1_dof_map_1::solitarywave2d_1_dof_map_1() : ufc::dof_map()
-{
-    __global_dimension = 0;
-}
-
-/// Destructor
-solitarywave2d_1_dof_map_1::~solitarywave2d_1_dof_map_1()
-{
-    // Do nothing
-}
-
-/// Return a string identifying the dof map
-const char* solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_1_dof_map_1::init_cell(const ufc::mesh& m,
-                              const ufc::cell& c)
-{
-    // Do nothing
-}
-
-/// Finish initialization of dof map for cells
-void solitarywave2d_1_dof_map_1::init_cell_finalize()
-{
-    // Do nothing
-}
-
-/// Return the dimension of the global finite element function space
-unsigned int solitarywave2d_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 solitarywave2d_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 solitarywave2d_1_dof_map_1::max_local_dimension() const
-{
-    return 12;
-}
-
-// Return the geometric dimension of the coordinates this dof map provides
-unsigned int solitarywave2d_1_dof_map_1::geometric_dimension() const
-{
-    return 2;
-}
-
-/// Return the number of dofs on each cell facet
-unsigned int solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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* solitarywave2d_1_dof_map_1::create_sub_dof_map(unsigned int i) const
-{
-    switch ( i )
-    {
-    case 0:
-      return new solitarywave2d_1_dof_map_1_0();
-      break;
-    case 1:
-      return new solitarywave2d_1_dof_map_1_1();
-      break;
-    }
-    return 0;
-}
-
-
-/// Constructor
-solitarywave2d_1_dof_map_2::solitarywave2d_1_dof_map_2() : ufc::dof_map()
-{
-    __global_dimension = 0;
-}
-
-/// Destructor
-solitarywave2d_1_dof_map_2::~solitarywave2d_1_dof_map_2()
-{
-    // Do nothing
-}
-
-/// Return a string identifying the dof map
-const char* solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_1_dof_map_2::init_cell(const ufc::mesh& m,
-                              const ufc::cell& c)
-{
-    // Do nothing
-}
-
-/// Finish initialization of dof map for cells
-void solitarywave2d_1_dof_map_2::init_cell_finalize()
-{
-    // Do nothing
-}
-
-/// Return the dimension of the global finite element function space
-unsigned int solitarywave2d_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 solitarywave2d_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 solitarywave2d_1_dof_map_2::max_local_dimension() const
-{
-    return 1;
-}
-
-// Return the geometric dimension of the coordinates this dof map provides
-unsigned int solitarywave2d_1_dof_map_2::geometric_dimension() const
-{
-    return 2;
-}
-
-/// Return the number of dofs on each cell facet
-unsigned int solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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* solitarywave2d_1_dof_map_2::create_sub_dof_map(unsigned int i) const
-{
-    return new solitarywave2d_1_dof_map_2();
-}
-
-
-/// Constructor
-solitarywave2d_1_dof_map_3::solitarywave2d_1_dof_map_3() : ufc::dof_map()
-{
-    __global_dimension = 0;
-}
-
-/// Destructor
-solitarywave2d_1_dof_map_3::~solitarywave2d_1_dof_map_3()
-{
-    // Do nothing
-}
-
-/// Return a string identifying the dof map
-const char* solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_1_dof_map_3::init_cell(const ufc::mesh& m,
-                              const ufc::cell& c)
-{
-    // Do nothing
-}
-
-/// Finish initialization of dof map for cells
-void solitarywave2d_1_dof_map_3::init_cell_finalize()
-{
-    // Do nothing
-}
-
-/// Return the dimension of the global finite element function space
-unsigned int solitarywave2d_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 solitarywave2d_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 solitarywave2d_1_dof_map_3::max_local_dimension() const
-{
-    return 1;
-}
-
-// Return the geometric dimension of the coordinates this dof map provides
-unsigned int solitarywave2d_1_dof_map_3::geometric_dimension() const
-{
-    return 2;
-}
-
-/// Return the number of dofs on each cell facet
-unsigned int solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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 solitarywave2d_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* solitarywave2d_1_dof_map_3::create_sub_dof_map(unsigned int i) const
-{
-    return new solitarywave2d_1_dof_map_3();
-}
-
-
-/// Constructor
-solitarywave2d_1_cell_integral_0_quadrature::solitarywave2d_1_cell_integral_0_quadrature() : ufc::cell_integral()
-{
-    // Do nothing
-}
-
-/// Destructor
-solitarywave2d_1_cell_integral_0_quadrature::~solitarywave2d_1_cell_integral_0_quadrature()
-{
-    // Do nothing
-}
-
-/// Tabulate the tensor for the contribution from a local cell
-void solitarywave2d_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 W25[25] = {0.0114650803515925, 0.0198040831320473, 0.0173415064313656, 0.0087554991821638, 0.00186555216687783, 0.0231612219294983, 0.0400072873861603, 0.0350325045033716, 0.0176874521104834, 0.0037687016953276, 0.0275289856644697, 0.0475518970579538, 0.0416389652151948, 0.021022967487322, 0.00447940679728133, 0.0231612219294983, 0.0400072873861603, 0.0350325045033716, 0.0176874521104834, 0.0037687016953276, 0.0114650803515925, 0.0198040831320473, 0.0173415064313656, 0.0087554991821638, 0.00186555216687783};
-    // Quadrature points on the UFC reference element: (0.0450425935698037, 0.0398098570514687), (0.0376212523451112, 0.198013417873608), (0.0263646449444709, 0.437974810247386), (0.0142857943955714, 0.695464273353636), (0.00462228846504642, 0.901464914201174), (0.221578609552379, 0.0398098570514687), (0.185070710267389, 0.198013417873608), (0.129695936782254, 0.437974810247386), (0.0702762920082817, 0.695464273353636), (0.022738483063764, 0.901464914201174), (0.480095071474266, 0.0398098570514687), (0.400993291063196, 0.198013417873608), (0.281012594876307, 0.437974810247386), (0.152267863323182, 0.695464273353636), (0.0492675428994132, 0.901464914201174), (0.738611533396152, 0.0398098570514687), (0.616915871859002, 0.198013417873608), (0.43232925297036, 0.437974810247386), (0.234259434638082, 0.695464273353636), (0.0757966027350624, 0.901464914201174), (0.915147549378728, 0.0398098570514687), (0.764365329781281, 0.198013417873608), (0.535660544808143, 0.437974810247386), (0.290249932250792, 0.695464273353636), (0.09391279733378, 0.901464914201174)
-    
-    // Value of basis functions at quadrature points.
-    static const double FE1_C0[25][6] = \
-    {{0.759842524889054, -0.0409849230988148, -0.036640207614552, 0.00717255684496518, 0.145727572487076, 0.164882476492272},
-    {0.404143384962011, -0.0347905350890822, -0.119594790557632, 0.0297980510461638, 0.605418365816316, 0.115025523822223},
-    {0.03820389372017, -0.0249744559383749, -0.0543309414249183, 0.0461882014671774, 0.938423301877431, 0.0564900002985142},
-    {-0.121759885907613, -0.0138776265525463, 0.271876837668966, 0.0397410384743819, 0.807433832894958, 0.0165858034218535},
-    {-0.0762735703276687, -0.00457955736373819, 0.723813068870285, 0.0166673234982246, 0.338636367163553, 0.00173636815934486},
-    {0.352482461135478, -0.123384449130048, -0.036640207614552, 0.0352840510877737, 0.117616078244268, 0.65464206627708},
-    {0.144254514044104, -0.116568374669637, -0.119594790557632, 0.146585935553368, 0.488630481309112, 0.456692234320685},
-    {-0.0585120870225412, -0.0960538647466012, -0.0543309414249183, 0.227214213208259, 0.75739729013635, 0.224285389849452},
-    {-0.124504469204174, -0.0603987775714152, 0.271876837668966, 0.19549860142211, 0.65167626994723, 0.0658515377372835},
-    {-0.0643063527627087, -0.0217044058396819, 0.723813068870285, 0.0819917787365634, 0.273311911925214, 0.00689399907032842},
-    {-0.0191125161665052, -0.0191125161665052, -0.036640207614552, 0.0764500646660208, 0.0764500646660207, 0.921965110615521},
-    {-0.07940205210781, -0.0794020521078101, -0.119594790557632, 0.31760820843124, 0.31760820843124, 0.643182477910772},
-    {-0.123076437918076, -0.123076437918076, -0.0543309414249183, 0.492305751672304, 0.492305751672304, 0.315872313916462},
-    {-0.105896858921168, -0.105896858921168, 0.271876837668966, 0.42358743568467, 0.42358743568467, 0.092742008804029},
-    {-0.0444129613327222, -0.0444129613327222, 0.723813068870285, 0.177651845330889, 0.177651845330889, 0.00970916313338224},
-    {-0.123384449130048, 0.352482461135478, -0.036640207614552, 0.117616078244268, 0.0352840510877737, 0.65464206627708},
-    {-0.116568374669637, 0.144254514044103, -0.119594790557632, 0.488630481309112, 0.146585935553368, 0.456692234320686},
-    {-0.0960538647466012, -0.0585120870225412, -0.0543309414249183, 0.75739729013635, 0.227214213208259, 0.224285389849452},
-    {-0.0603987775714152, -0.124504469204174, 0.271876837668966, 0.651676269947229, 0.19549860142211, 0.0658515377372836},
-    {-0.0217044058396819, -0.0643063527627086, 0.723813068870285, 0.273311911925214, 0.0819917787365633, 0.00689399907032842},
-    {-0.0409849230988148, 0.759842524889054, -0.036640207614552, 0.145727572487076, 0.00717255684496521, 0.164882476492272},
-    {-0.0347905350890821, 0.404143384962011, -0.119594790557632, 0.605418365816316, 0.0297980510461639, 0.115025523822223},
-    {-0.024974455938375, 0.0382038937201699, -0.0543309414249183, 0.938423301877431, 0.0461882014671775, 0.0564900002985145},
-    {-0.0138776265525464, -0.121759885907613, 0.271876837668966, 0.807433832894958, 0.0397410384743822, 0.0165858034218536},
-    {-0.00457955736373822, -0.0762735703276687, 0.723813068870285, 0.338636367163553, 0.0166673234982245, 0.00173636815934486}};
-    
-    // Array of non-zero columns
-    static const unsigned int nzc0[6] = {0, 1, 2, 3, 4, 5};
-    // Array of non-zero columns
-    static const unsigned int nzc3[6] = {6, 7, 8, 9, 10, 11};
-    static const double FE1_C0_D01[25][5] = \
-    {{-2.66059019751491, -0.840760571794125, 0.180170374279215, 3.50135076930903, -0.180170374279215},
-    {-2.05746131912512, -0.207946328505567, 0.150485009380445, 2.26540764763069, -0.150485009380445},
-    {-1.14264217923257, 0.751899240989545, 0.105458579777884, 0.390742938243026, -0.105458579777884},
-    {-0.16099972900317, 1.78185709341454, 0.0571431775822861, -1.62085736441137, -0.0571431775822855},
-    {0.624348810664881, 2.60585965680469, 0.0184891538601872, -3.23020846746957, -0.018489153860186},
-    {-1.95444613358461, -0.840760571794126, 0.886314438209517, 2.79520670537873, -0.886314438209516},
-    {-1.46766348743601, -0.207946328505567, 0.740282841069557, 1.67560981594158, -0.740282841069557},
-    {-0.729317011881439, 0.751899240989545, 0.518783747129016, -0.0225822291081061, -0.518783747129016},
-    {0.0629622614476711, 1.78185709341454, 0.281105168033127, -1.84481935486222, -0.281105168033127},
-    {0.696813589059751, 2.60585965680469, 0.0909539322550576, -3.30267324586444, -0.0909539322550564},
-    {-0.920380285897062, -0.840760571794126, 1.92038028589706, 1.76114085769119, -1.92038028589706},
-    {-0.603973164252783, -0.207946328505567, 1.60397316425278, 0.811919492758351, -1.60397316425278},
-    {-0.124050379505228, 0.751899240989545, 1.12405037950523, -0.627848861484317, -1.12405037950523},
-    {0.390928546707272, 1.78185709341454, 0.609071453292728, -2.17278564012182, -0.609071453292728},
-    {0.802929828402348, 2.60585965680469, 0.197070171597654, -3.40878948520704, -0.197070171597653},
-    {0.113685561790484, -0.840760571794125, 2.95444613358461, 0.727075010003642, -2.95444613358461},
-    {0.259717158930443, -0.207946328505567, 2.46766348743601, -0.0517708304248748, -2.46766348743601},
-    {0.481216252870984, 0.751899240989544, 1.72931701188144, -1.23311549386053, -1.72931701188144},
-    {0.718894831966874, 1.78185709341454, 0.937037738552329, -2.50075192538142, -0.937037738552329},
-    {0.909046067744945, 2.60585965680469, 0.303186410940251, -3.51490572454964, -0.30318641094025},
-    {0.819829625720786, -0.840760571794125, 3.66059019751491, 0.0209309460733398, -3.66059019751491},
-    {0.849514990619556, -0.207946328505567, 3.05746131912512, -0.641568662113988, -3.05746131912512},
-    {0.894541420222117, 0.751899240989544, 2.14264217923257, -1.64644066121166, -2.14264217923257},
-    {0.942856822417715, 1.78185709341454, 1.16099972900317, -2.72471391583226, -1.16099972900317},
-    {0.981510846139815, 2.60585965680469, 0.375651189335121, -3.58737050294451, -0.37565118933512}};
-    
-    // Array of non-zero columns
-    static const unsigned int nzc1[5] = {0, 2, 3, 4, 5};
-    static const double FE1_C0_D10[25][5] = \
-    {{-2.66059019751491, -0.819829625720785, 0.159239428205874, -0.159239428205874, 3.4804198232357},
-    {-2.05746131912512, -0.849514990619555, 0.792053671494433, -0.792053671494433, 2.90697630974468},
-    {-1.14264217923257, -0.894541420222116, 1.75189924098954, -1.75189924098954, 2.03718359945469},
-    {-0.16099972900317, -0.942856822417714, 2.78185709341454, -2.78185709341454, 1.10385655142088},
-    {0.624348810664881, -0.981510846139815, 3.60585965680469, -3.60585965680469, 0.357162035474934},
-    {-1.95444613358461, -0.113685561790483, 0.159239428205875, -0.159239428205875, 2.06813169537509},
-    {-1.46766348743601, -0.259717158930442, 0.792053671494433, -0.792053671494433, 1.72738064636645},
-    {-0.729317011881439, -0.481216252870983, 1.75189924098954, -1.75189924098954, 1.21053326475242},
-    {0.0629622614476713, -0.718894831966873, 2.78185709341454, -2.78185709341454, 0.655932570519202},
-    {0.696813589059752, -0.909046067744944, 3.60585965680469, -3.60585965680469, 0.212232478685193},
-    {-0.920380285897062, 0.920380285897063, 0.159239428205875, -0.159239428205875, 0},
-    {-0.603973164252783, 0.603973164252784, 0.792053671494433, -0.792053671494433, 0},
-    {-0.124050379505228, 0.124050379505228, 1.75189924098954, -1.75189924098954, 0},
-    {0.390928546707273, -0.390928546707272, 2.78185709341454, -2.78185709341454, 0},
-    {0.802929828402348, -0.802929828402348, 3.60585965680469, -3.60585965680469, 0},
-    {0.113685561790483, 1.95444613358461, 0.159239428205875, -0.159239428205875, -2.06813169537509},
-    {0.259717158930442, 1.46766348743601, 0.792053671494433, -0.792053671494433, -1.72738064636645},
-    {0.481216252870984, 0.729317011881439, 1.75189924098954, -1.75189924098954, -1.21053326475242},
-    {0.718894831966873, -0.0629622614476713, 2.78185709341454, -2.78185709341454, -0.655932570519202},
-    {0.909046067744945, -0.696813589059751, 3.60585965680469, -3.60585965680469, -0.212232478685194},
-    {0.819829625720786, 2.66059019751491, 0.159239428205876, -0.159239428205876, -3.4804198232357},
-    {0.849514990619555, 2.05746131912512, 0.792053671494433, -0.792053671494433, -2.90697630974468},
-    {0.894541420222116, 1.14264217923257, 1.75189924098954, -1.75189924098954, -2.03718359945469},
-    {0.942856822417715, 0.16099972900317, 2.78185709341454, -2.78185709341454, -1.10385655142088},
-    {0.981510846139815, -0.624348810664881, 3.60585965680469, -3.60585965680469, -0.357162035474935}};
-    
-    // Array of non-zero columns
-    static const unsigned int nzc2[5] = {0, 1, 3, 4, 5};
-    
     // Number of operations to compute geometry constants: 18
     const double G0 = det*w[2][0];
     const double G1 = -0.5*det*w[1][0]*w[2][0];
diff -r 945ab07a21be -r 4d3585d24e75 MADDs-4/cpp/SolitaryWave3D.cpp
--- a/MADDs-4/cpp/SolitaryWave3D.cpp	Sat Dec 05 22:52:18 2009 -0500
+++ b/MADDs-4/cpp/SolitaryWave3D.cpp	Sun Dec 06 00:12:54 2009 -0500
@@ -10086,6 +10086,8278 @@ solitarywave3d_0_cell_integral_0_quadrat
 
 /// Tabulate the tensor for the contribution from a local cell
 void solitarywave3d_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_02 = x[3][0] - x[0][0];
+    const double J_10 = x[1][1] - x[0][1];
+    const double J_11 = x[2][1] - x[0][1];
+    const double J_12 = x[3][1] - x[0][1];
+    const double J_20 = x[1][2] - x[0][2];
+    const double J_21 = x[2][2] - x[0][2];
+    const double J_22 = x[3][2] - x[0][2];
+    
+    // Compute sub determinants
+    const double d_00 = J_11*J_22 - J_12*J_21;
+    const double d_01 = J_12*J_20 - J_10*J_22;
+    const double d_02 = J_10*J_21 - J_11*J_20;
+    
+    const double d_10 = J_02*J_21 - J_01*J_22;
+    const double d_11 = J_00*J_22 - J_02*J_20;
+    const double d_12 = J_01*J_20 - J_00*J_21;
+    
+    const double d_20 = J_01*J_12 - J_02*J_11;
+    const double d_21 = J_02*J_10 - J_00*J_12;
+    const double d_22 = J_00*J_11 - J_01*J_10;
+    
+    // Compute determinant of Jacobian
+    double detJ = J_00*d_00 + J_10*d_10 + J_20*d_20;
+    
+    // Compute inverse of Jacobian
+    const double Jinv_00 = d_00 / detJ;
+    const double Jinv_01 = d_10 / detJ;
+    const double Jinv_02 = d_20 / detJ;
+    const double Jinv_10 = d_01 / detJ;
+    const double Jinv_11 = d_11 / detJ;
+    const double Jinv_12 = d_21 / detJ;
+    const double Jinv_20 = d_02 / detJ;
+    const double Jinv_21 = d_12 / detJ;
+    const double Jinv_22 = d_22 / detJ;
+    
+    // Set scale factor
+    const double det = std::abs(detJ);
+    
+    
+    // Array of quadrature weights
+    static const double W125[125] = {0.000937439821766984, 0.00144688123847004, 0.00102268701578053, 0.000367520038007324, 4.71653365059364e-05, 0.00161927658526931, 0.00249925473264391, 0.00176652740822439, 0.000634831781565251, 8.1470536312884e-05, 0.00141792453255091, 0.00218848010941898, 0.00154686516950305, 0.000555892406098532, 7.13399262170554e-05, 0.000715891501943862, 0.00110493490770459, 0.000780991938624509, 0.000280662785913662, 3.60185932012982e-05, 0.000152536470498617, 0.000235430746830112, 0.000166407554052789, 5.9801395389292e-05, 7.67455552179798e-06, 0.00189377231486028, 0.00292292216383614, 0.00206598473020027, 0.000742446882427904, 9.52812185081393e-05, 0.00327118722298822, 0.00504887813656484, 0.00356865648488397, 0.00128245763045954, 0.000164582987156811, 0.00286442517370845, 0.00442106570107946, 0.00312490504969682, 0.00112298797668544, 0.000144117599953649, 0.00144621070637857, 0.0022321380949974, 0.00157772357985427, 0.000566981902660164, 7.27630862707133e-05, 0.000308147081155878, 0.000475606241660779, 0.000336168798819301, 0.000120807996789371, 1.55037800172006e-05, 0.00225090157446143, 0.00347412941301361, 0.00245558995953753, 0.00088245817276838, 0.000113249435042247, 0.00388807060532275, 0.00600100004508522, 0.00424163688396193, 0.00152430462570915, 0.00019562019257218, 0.0034046010087031, 0.0052547941847441, 0.00371420241029555, 0.00133476204345558, 0.000171295424533231, 0.00171893840164765, 0.00265307667295562, 0.00187525208922536, 0.000673903851785402, 8.64848134932762e-05, 0.000366257730507922, 0.000565296487744311, 0.00039956380849458, 0.000143590075769372, 1.8427496577589e-05, 0.00189377231486028, 0.00292292216383614, 0.00206598473020027, 0.000742446882427904, 9.52812185081393e-05, 0.00327118722298822, 0.00504887813656484, 0.00356865648488397, 0.00128245763045954, 0.000164582987156811, 0.00286442517370845, 0.00442106570107946, 0.00312490504969682, 0.00112298797668544, 0.000144117599953649, 0.00144621070637857, 0.0022321380949974, 0.00157772357985427, 0.000566981902660164, 7.27630862707133e-05, 0.000308147081155878, 0.000475606241660779, 0.000336168798819301, 0.000120807996789371, 1.55037800172006e-05, 0.000937439821766984, 0.00144688123847004, 0.00102268701578053, 0.000367520038007324, 4.71653365059364e-05, 0.00161927658526931, 0.00249925473264391, 0.00176652740822439, 0.000634831781565252, 8.1470536312884e-05, 0.00141792453255091, 0.00218848010941898, 0.00154686516950305, 0.000555892406098532, 7.13399262170554e-05, 0.000715891501943862, 0.00110493490770459, 0.000780991938624509, 0.000280662785913662, 3.60185932012982e-05, 0.000152536470498617, 0.000235430746830112, 0.000166407554052789, 5.9801395389292e-05, 7.67455552179798e-06};
+    // Quadrature points on the UFC reference element: (0.0434850684329929, 0.0384332743963333, 0.034578939918215), (0.0372285899889251, 0.0329036302803046, 0.173480320771696), (0.0274810994988124, 0.0242885357160768, 0.389886387065519), (0.0164705687743685, 0.0145571321830714, 0.634333472630887), (0.0067089045501621, 0.00592951049099777, 0.851054212947016), (0.0363203493206216, 0.191166323793956, 0.034578939918215), (0.0310947054204484, 0.163661986623795, 0.173480320771696), (0.0229532381913956, 0.120810681788372, 0.389886387065519), (0.0137568327003139, 0.0724068788863314, 0.634333472630887), (0.00560352704046152, 0.0294932643722359, 0.851054212947016), (0.025452983470971, 0.42283010559815, 0.034578939918215), (0.0217908978824722, 0.361994799675747, 0.173480320771696), (0.0160854287808059, 0.267214393854326, 0.389886387065519), (0.00964066816216436, 0.160152727938308, 0.634333472630887), (0.00392690279162666, 0.0652345028216781, 0.851054212947016), (0.0137918067694829, 0.671415856030076, 0.034578939918215), (0.0118074902013492, 0.574814908126993, 0.173480320771696), (0.00871595763232119, 0.42431222048264, 0.389886387065519), (0.00522383682733774, 0.254308005746508, 0.634333472630887), (0.00212780888992548, 0.103586473561889, 0.851054212947016), (0.00446245462992895, 0.870293213094632, 0.034578939918215), (0.00382041237943087, 0.745078491721125, 0.173480320771696), (0.00282012111543484, 0.54999601573695, 0.389886387065519), (0.00169021617151183, 0.329635544721039, 0.634333472630887), (0.000688470393412244, 0.134269401146344, 0.851054212947016), (0.213916656125506, 0.0384332743963333, 0.034578939918215), (0.183139081291086, 0.0329036302803046, 0.173480320771696), (0.135188126023001, 0.0242885357160768, 0.389886387065519), (0.0810238806942951, 0.0145571321830714, 0.634333472630887), (0.0330032003938849, 0.00592951049099777, 0.851054212947016), (0.178671161296432, 0.191166323793956, 0.034578939918215), (0.152964584084757, 0.163661986623795, 0.173480320771696), (0.112914159689587, 0.120810681788372, 0.389886387065519), (0.0676741639412116, 0.0724068788863314, 0.634333472630887), (0.027565502601231, 0.0294932643722359, 0.851054212947016), (0.125211188776624, 0.42283010559815, 0.034578939918215), (0.107196244066483, 0.361994799675747, 0.173480320771696), (0.0791292565731431, 0.267214393854326, 0.389886387065519), (0.0474254628170509, 0.160152727938308, 0.634333472630887), (0.0193176633816068, 0.0652345028216781, 0.851054212947016), (0.0678462123292524, 0.671415856030076, 0.034578939918215), (0.0580847383280397, 0.574814908126993, 0.173480320771696), (0.0428765224208113, 0.42431222048264, 0.389886387065519), (0.0256976876550462, 0.254308005746508, 0.634333472630887), (0.0104673576243388, 0.103586473561889, 0.851054212947016), (0.0219522104240708, 0.870293213094632, 0.034578939918215), (0.0187938037280005, 0.745078491721125, 0.173480320771696), (0.0138730580546826, 0.54999601573695, 0.389886387065519), (0.00831470213956798, 0.329635544721039, 0.634333472630887), (0.00338680125632329, 0.134269401146344, 0.851054212947016), (0.463493892842726, 0.0384332743963333, 0.034578939918215), (0.396808024474, 0.0329036302803046, 0.173480320771696), (0.292912538609202, 0.0242885357160768, 0.389886387065519), (0.175554697593021, 0.0145571321830714, 0.634333472630887), (0.0715081382809929, 0.00592951049099777, 0.851054212947016), (0.387127368143914, 0.191166323793956, 0.034578939918215), (0.331428846302255, 0.163661986623795, 0.173480320771696), (0.244651465573054, 0.120810681788372, 0.389886387065519), (0.146629824241391, 0.0724068788863314, 0.634333472630887), (0.0597262613403738, 0.0294932643722359, 0.851054212947016), (0.271295477241817, 0.42283010559815, 0.034578939918215), (0.232262439776279, 0.361994799675747, 0.173480320771696), (0.171449609540077, 0.267214393854326, 0.389886387065519), (0.102756899715403, 0.160152727938308, 0.634333472630887), (0.0418556421156527, 0.0652345028216781, 0.851054212947016), (0.147002602025855, 0.671415856030076, 0.034578939918215), (0.125852385550656, 0.574814908126993, 0.173480320771696), (0.0929006962259202, 0.42431222048264, 0.389886387065519), (0.0556792608113027, 0.254308005746508, 0.634333472630887), (0.0226796567455474, 0.103586473561889, 0.851054212947016), (0.0475639234935763, 0.870293213094632, 0.034578939918215), (0.0407205937535897, 0.745078491721125, 0.173480320771696), (0.0300587985987655, 0.54999601573695, 0.389886387065519), (0.0180154913240372, 0.329635544721039, 0.634333472630887), (0.00733819295331972, 0.134269401146344, 0.851054212947016), (0.713071129559946, 0.0384332743963333, 0.034578939918215), (0.610476967656914, 0.0329036302803046, 0.173480320771696), (0.450636951195403, 0.0242885357160768, 0.389886387065519), (0.270085514491747, 0.0145571321830714, 0.634333472630887), (0.110013076168101, 0.00592951049099777, 0.851054212947016), (0.595583574991397, 0.191166323793956, 0.034578939918215), (0.509893108519752, 0.163661986623795, 0.173480320771696), (0.376388771456521, 0.120810681788372, 0.389886387065519), (0.22558548454157, 0.0724068788863314, 0.634333472630887), (0.0918870200795167, 0.0294932643722359, 0.851054212947016), (0.417379765707011, 0.42283010559815, 0.034578939918215), (0.357328635486074, 0.361994799675747, 0.173480320771696), (0.263769962507011, 0.267214393854326, 0.389886387065519), (0.158088336613754, 0.160152727938308, 0.634333472630887), (0.0643936208496987, 0.0652345028216781, 0.851054212947016), (0.226158991722457, 0.671415856030076, 0.034578939918215), (0.193620032773272, 0.574814908126993, 0.173480320771696), (0.142924870031029, 0.42431222048264, 0.389886387065519), (0.0856608339675592, 0.254308005746508, 0.634333472630887), (0.0348919558667561, 0.103586473561889, 0.851054212947016), (0.0731756365630818, 0.870293213094632, 0.034578939918215), (0.062647383779179, 0.745078491721125, 0.173480320771696), (0.0462445391428484, 0.54999601573695, 0.389886387065519), (0.0277162805085065, 0.329635544721039, 0.634333472630887), (0.0112895846503162, 0.134269401146344, 0.851054212947016), (0.883502717252459, 0.0384332743963333, 0.034578939918215), (0.756387458959075, 0.0329036302803046, 0.173480320771696), (0.558343977719591, 0.0242885357160768, 0.389886387065519), (0.334638826411673, 0.0145571321830714, 0.634333472630887), (0.136307372011824, 0.00592951049099777, 0.851054212947016), (0.737934386967207, 0.191166323793956, 0.034578939918215), (0.631762987184061, 0.163661986623795, 0.173480320771696), (0.466349692954713, 0.120810681788372, 0.389886387065519), (0.279502815782468, 0.0724068788863314, 0.634333472630887), (0.113848995640286, 0.0294932643722359, 0.851054212947016), (0.517137971012664, 0.42283010559815, 0.034578939918215), (0.442733981670085, 0.361994799675747, 0.173480320771696), (0.326813790299348, 0.267214393854326, 0.389886387065519), (0.195873131268641, 0.160152727938308, 0.634333472630887), (0.0797843814396788, 0.0652345028216781, 0.851054212947016), (0.280213397282226, 0.671415856030076, 0.034578939918215), (0.239897280899962, 0.574814908126993, 0.173480320771696), (0.177085434819519, 0.42431222048264, 0.389886387065519), (0.106134684795268, 0.254308005746508, 0.634333472630887), (0.0432315046011695, 0.103586473561889, 0.851054212947016), (0.0906653923572237, 0.870293213094632, 0.034578939918215), (0.0776207751277486, 0.745078491721125, 0.173480320771696), (0.0572974760820962, 0.54999601573695, 0.389886387065519), (0.0343407664765626, 0.329635544721039, 0.634333472630887), (0.0139879155132272, 0.134269401146344, 0.851054212947016)
+    
+    // Value of basis functions at quadrature points.
+    static const double FE1_C0[125][10] = \
+    {{0.677651385532498, -0.0397031660797488, -0.0354790412346856, -0.03218753374648, 0.00531592754484438, 0.00601467027473595, 0.00668509426891429, 0.12220234950981, 0.135823609448279, 0.153676704481834},
+    {0.387856517182057, -0.0344566541637981, -0.0307383325090586, -0.113289477381595, 0.0228325293423221, 0.0258337109326268, 0.00489982304341056, 0.524873356031632, 0.0995515731929938, 0.112636954329409},
+    {0.0651520171918798, -0.0259706778394852, -0.0231086697816145, -0.0858635974275115, 0.0378790777498121, 0.0428580263847204, 0.00266990266677583, 0.870762864851529, 0.0542454305787948, 0.0613756256250992},
+    {-0.110672538127309, -0.015928009502866, -0.0141333119882805, 0.170424436369033, 0.036936304836938, 0.0417913323474042, 0.000959056987115393, 0.849090435339365, 0.0194855265186504, 0.0220467672199497},
+    {-0.0991479726822843, -0.00661888574963566, -0.00585919230167203, 0.597532333802715, 0.0201853395363087, 0.0228385659266996, 0.000159122079653143, 0.464019852825595, 0.00323294396937779, 0.0036578925932431},
+    {0.351159931970128, -0.0336820137710776, -0.118077197088165, -0.03218753374648, 0.026441315299429, 0.00502367670786558, 0.0277729106341423, 0.102067955322095, 0.564272815830671, 0.107208138841391},
+    {0.166485956767395, -0.0291609440100794, -0.1100914948925, -0.113289477381595, 0.113568535750516, 0.0215772778825633, 0.0203560850503691, 0.438393782673502, 0.413582342231706, 0.0785779359281236},
+    {-0.0313856207168029, -0.0218995359044537, -0.0916202401200295, -0.0858635974275115, 0.188409760965562, 0.0357966204395903, 0.0110919854206136, 0.727293587580909, 0.225360097430627, 0.0428169423314949},
+    {-0.123259167721812, -0.013378331808425, -0.0619213666662117, 0.170424436369033, 0.183720427705323, 0.0349056778367692, 0.00398435727676459, 0.709191966981616, 0.080951706122999, 0.0153802939039443},
+    {-0.0879258080236823, -0.00554072800987512, -0.0277535590855747, 0.597532333802715, 0.100401467590206, 0.0190756211805894, 0.000661065217685219, 0.387566669517808, 0.01343111410773, 0.00255182370239899},
+    {0.0177253911135257, -0.0241572747358239, -0.0652595091978645, -0.03218753374648, 0.0584840672683638, 0.00352054874472827, 0.0430491507552746, 0.0715283313162981, 0.874646011568391, 0.0526508169135872},
+    {-0.0507072246191906, -0.0208412114214236, -0.0999143296911785, -0.113289477381595, 0.251195895861737, 0.0151211678182184, 0.0315527668548808, 0.307222532626625, 0.641069596017233, 0.0385902839346927},
+    {-0.113199283239695, -0.0155679467426812, -0.124407329288456, -0.0858635974275115, 0.416733018367064, 0.0250859588469928, 0.0171930324062, 0.509680991772005, 0.349317395512301, 0.0210277597937817},
+    {-0.119140564162676, -0.00945478319693843, -0.108854935406145, 0.170424436369033, 0.406360944257666, 0.0244615940551512, 0.00617591722127442, 0.49699553421089, 0.125478465209964, 0.00755339144178016},
+    {-0.0670532863962545, -0.00389606166055687, -0.056723422104895, 0.597532333802715, 0.222072393823573, 0.0133680286585892, 0.00102467820496327, 0.271603335806442, 0.0208187778246103, 0.00125322204081482},
+    {-0.123174301249333, -0.0134113789015495, 0.230182647427123, -0.03218753374648, 0.0928673941832035, 0.00190762423058252, 0.0370401509933353, 0.0387579289156041, 0.752558872029367, 0.0154585961181473},
+    {-0.124795870133571, -0.0115286565516393, 0.0860094490830938, -0.113289477381595, 0.398876298584894, 0.00819346875055505, 0.0271484855811957, 0.166469828971132, 0.551586133921709, 0.0113303391742265},
+    {-0.114366932369083, -0.00856402179742438, -0.0642304995808229, -0.0858635974275115, 0.661734234526899, 0.0135929329243276, 0.0147931493464113, 0.276172801534836, 0.300558056253616, 0.00617387658875251},
+    {-0.083605542162086, -0.00516925988494044, -0.124962882172976, 0.170424436369033, 0.645264321612071, 0.0132546182205693, 0.00531385410362168, 0.269299132691067, 0.107963600123275, 0.00221772110036569},
+    {-0.0394935786210076, -0.00211875374858136, -0.082126158551913, 0.597532333802715, 0.35263081891668, 0.00724352288046892, 0.00088164887728405, 0.147169416491454, 0.0179127964336388, 0.000367953519260986},
+    {-0.0742249656146451, -0.00442262762728059, 0.644527340422526, -0.03218753374648, 0.120375266907318, 0.000617227802144467, 0.0155345759126796, 0.0125404526199273, 0.315621902524215, 0.00161836079959531},
+    {-0.0655708056648836, -0.00379122127793308, 0.365205425929728, -0.113289477381595, 0.517025822975488, 0.00265106546025555, 0.0113860283736764, 0.053862707870838, 0.23133428023363, 0.00118617348079641},
+    {-0.0507314745513395, -0.00280421494922342, 0.0549952189160882, -0.0858635974275115, 0.857743837904439, 0.00439810733113653, 0.00620422150953917, 0.0893580237504861, 0.126053534227744, 0.000646343288641082},
+    {-0.0319821899921671, -0.00168450251009896, -0.112316360033967, 0.170424436369033, 0.836395439141882, 0.0042886427742881, 0.00222862131357039, 0.0871339906075373, 0.0452797490545588, 0.000232173275363283},
+    {-0.0135965919524168, -0.000687522410446964, -0.0982128569779484, 0.597532333802715, 0.457082158061876, 0.00234370251521121, 0.000369762029721776, 0.0476178977115156, 0.00751259615698667, 3.85210627857485e-05},
+    {0.303869742063848, -0.12239598458967, -0.0354790412346856, -0.03218753374648, 0.00531592754484438, 0.0295880447986775, 0.0328860701712706, 0.0986289749858682, 0.109622633545923, 0.610151166460404},
+    {0.134887288422247, -0.1160592350988, -0.0307383325090586, -0.113289477381595, 0.0228325293423221, 0.127084106272845, 0.0241037624827062, 0.423622960691414, 0.0803476337536982, 0.447208764024221},
+    {-0.0444896276300268, -0.0986364671877792, -0.0231086697816145, -0.0858635974275115, 0.0378790777498121, 0.210832040117064, 0.0131340865091965, 0.702788851119186, 0.0437812467363741, 0.2436830597953},
+    {-0.124193144215204, -0.0678941422087684, -0.0141333119882805, 0.170424436369033, 0.036936304836938, 0.205584638427372, 0.004717901365009, 0.685297129259398, 0.0157266821407568, 0.0875335060137464},
+    {-0.0858073223121642, -0.030824777921407, -0.00585919230167206, 0.597532333802715, 0.0201853395363087, 0.112350050943802, 0.000782771291888182, 0.374508367808493, 0.00260929475714278, 0.0145231343948943},
+    {0.113856014607669, -0.114824393538401, -0.118077197088165, -0.03218753374648, 0.026441315299429, 0.0247130374063482, 0.136623636292144, 0.0823785946236127, 0.45542209017267, 0.425654435971174},
+    {0.0100888557121195, -0.106168256116312, -0.1100914948925, -0.113289477381595, 0.113568535750516, 0.106145380454931, 0.100137950857575, 0.353825680101135, 0.333800476424499, 0.311982349089632},
+    {-0.0930517568994226, -0.0874149447727761, -0.0916202401200295, -0.0858635974275115, 0.188409760965562, 0.17609477507965, 0.0545649464626408, 0.58699543294085, 0.1818871363886, 0.169998487382437},
+    {-0.12380786286986, -0.0585145790109275, -0.0619213666662117, 0.170424436369033, 0.183720427705323, 0.171711949680883, 0.0196002999689002, 0.572385695137502, 0.0653357634308634, 0.0610652362544955},
+    {-0.0750005711613296, -0.026045788733914, -0.0277535590855747, 0.597532333802715, 0.100401467590206, 0.0938389484831186, 0.00325198662308666, 0.312803342215279, 0.0108401927023285, 0.0101316475640852},
+    {-0.0689680280637322, -0.0938555051869132, -0.0652595091978645, -0.03218753374648, 0.0584840672683638, 0.0173186806951808, 0.211772240689959, 0.0577301993658455, 0.705922921633706, 0.209042466541935},
+    {-0.101961128009395, -0.084214174582561, -0.0999143296911785, -0.113289477381595, 0.251195895861737, 0.0743857552246981, 0.155217931587356, 0.247957945220146, 0.517404431284758, 0.153217150486034},
+    {-0.124620776265111, -0.0666063780815064, -0.124407329288456, -0.0858635974275115, 0.416733018367064, 0.123405679825933, 0.0845779053253436, 0.411361270793064, 0.281932522593157, 0.0834876841580225},
+    {-0.108104492267147, -0.0429271137702279, -0.108854935406145, 0.170424436369033, 0.406360944257666, 0.120334234079468, 0.03038126897555, 0.401122894186573, 0.101273113455689, 0.0299896501195402},
+    {-0.0561005440374291, -0.0185713191445566, -0.056723422104895, 0.597532333802715, 0.222072393823573, 0.0657615152208353, 0.00504071266550263, 0.219209849244195, 0.0168027433640709, 0.00497573716598929},
+    {-0.12386321264862, -0.0586399952744004, 0.230182647427123, -0.03218753374648, 0.0928673941832035, 0.0093842003992469, 0.182212090917773, 0.0312813527469397, 0.607386932104929, 0.0613761238902858},
+    {-0.118642598591026, -0.051337064674766, 0.0860094490830938, -0.113289477381595, 0.398876298584894, 0.0403062361483535, 0.13355189410245, 0.134357061573334, 0.445182725400454, 0.0449854757548079},
+    {-0.102069833084256, -0.0391997300710066, -0.0642304995808229, -0.0858635974275115, 0.661734234526899, 0.0668678896663356, 0.0727721297397925, 0.222897844792828, 0.242579075860235, 0.0245124855775079},
+    {-0.0709852770155237, -0.0243769453534135, -0.124962882172976, 0.170424436369033, 0.645264321612071, 0.0652036137952374, 0.0261405107994058, 0.217350137116399, 0.0871369434274908, 0.00880514142227651},
+    {-0.0324570586983408, -0.0102482264730672, -0.082126158551913, 0.597532333802715, 0.35263081891668, 0.0356331552184666, 0.00433710665526561, 0.118779784153456, 0.0144573386556573, 0.00146090632108002},
+    {-0.0624662889902574, -0.0209884113390654, 0.644527340422526, -0.03218753374648, 0.120375266907318, 0.00303633666130401, 0.0764194389779763, 0.0101213437607678, 0.254737039458918, 0.00642546788699245},
+    {-0.0547979943904275, -0.0180873896108673, 0.365205425929728, -0.113289477381595, 0.517025822975488, 0.0130414203970155, 0.0560114357414459, 0.043472352934078, 0.18670887286586, 0.00470953053927457},
+    {-0.0419674243417796, -0.0134881345751054, 0.0549952189160882, -0.0858635974275115, 0.857743837904439, 0.0216356659299618, 0.0305205066246512, 0.0721204651516608, 0.101737249112632, 0.00256621270496322},
+    {-0.0261798960980541, -0.00817643359622851, -0.112316360033967, 0.170424436369033, 0.836395439141882, 0.0210971755283347, 0.0109632854758787, 0.0703254578534908, 0.0365450848922505, 0.000921810467379901},
+    {-0.0110346752071629, -0.00336386041082359, -0.0982128569779484, 0.597532333802715, 0.457082158061876, 0.0115294059104329, 0.00181897510595286, 0.0384321943162941, 0.00606338308075562, 0.000152942317908342},
+    {-0.0338407154377174, -0.0338407154377172, -0.0354790412346856, -0.03218753374648, 0.00531592754484438, 0.0641085098922729, 0.0712543518585967, 0.0641085098922728, 0.0712543518585967, 0.859306354810017},
+    {-0.0818948079000829, -0.0818948079000828, -0.0307383325090586, -0.113289477381595, 0.0228325293423221, 0.27535353348213, 0.0522256981182022, 0.275353533482129, 0.0522256981182022, 0.629826433147834},
+    {-0.121317028060228, -0.121317028060227, -0.0231086697816145, -0.0858635974275114, 0.0378790777498121, 0.456810445618125, 0.0284576666227853, 0.456810445618125, 0.0284576666227853, 0.343191021097949},
+    {-0.113915793899067, -0.113915793899067, -0.0141333119882805, 0.170424436369033, 0.036936304836938, 0.445440883843385, 0.0102222917528829, 0.445440883843385, 0.0102222917528829, 0.123277807387908},
+    {-0.0612813106001657, -0.0612813106001656, -0.00585919230167206, 0.597532333802715, 0.0201853395363087, 0.243429209376147, 0.00169603302451547, 0.243429209376147, 0.00169603302451546, 0.0204536553616545},
+    {-0.0873921698118468, -0.0873921698118467, -0.118077197088165, -0.03218753374648, 0.026441315299429, 0.0535458160149806, 0.296022863232407, 0.0535458160149805, 0.296022863232407, 0.599470396664135},
+    {-0.111738685979768, -0.111738685979767, -0.1100914948925, -0.113289477381595, 0.113568535750516, 0.229985530278033, 0.216969213641037, 0.229985530278033, 0.216969213641037, 0.439380320644974},
+    {-0.124942786358968, -0.124942786358967, -0.0916202401200295, -0.0858635974275114, 0.188409760965562, 0.38154510401025, 0.118226041425621, 0.38154510401025, 0.118226041425621, 0.239417358428173},
+    {-0.103629213527269, -0.103629213527268, -0.0619213666662117, 0.170424436369033, 0.183720427705323, 0.372048822409193, 0.0424680316998818, 0.372048822409192, 0.0424680316998817, 0.0860012214282448},
+    {-0.0525918087529765, -0.0525918087529765, -0.0277535590855747, 0.597532333802715, 0.100401467590206, 0.203321145349199, 0.00704608966270762, 0.203321145349198, 0.00704608966270757, 0.0142689051747946},
+    {-0.124093005298086, -0.124093005298086, -0.0652595091978644, -0.03218753374648, 0.0584840672683638, 0.0375244400305132, 0.458847581161833, 0.037524440030513, 0.458847581161833, 0.294404943887462},
+    {-0.12437075791462, -0.12437075791462, -0.0999143296911785, -0.113289477381595, 0.251195895861737, 0.161171850222422, 0.336311181436057, 0.161171850222422, 0.336311181436057, 0.215783363723318},
+    {-0.112659672317187, -0.112659672317187, -0.124407329288456, -0.0858635974275115, 0.416733018367064, 0.267383475309499, 0.183255213959251, 0.267383475309499, 0.18325521395925, 0.11757987444578},
+    {-0.08163893883716, -0.0816389388371599, -0.108854935406145, 0.170424436369033, 0.406360944257666, 0.260728564133021, 0.0658271912156194, 0.26072856413302, 0.0658271912156194, 0.0422359217564853},
+    {-0.0383518525618255, -0.0383518525618255, -0.056723422104895, 0.597532333802715, 0.222072393823573, 0.142485682232515, 0.0109217280147868, 0.142485682232515, 0.0109217280147868, 0.00700757910765451},
+    {-0.103783072021111, -0.103783072021111, 0.230182647427123, -0.03218753374648, 0.0928673941832035, 0.0203327765730934, 0.394799511511351, 0.0203327765730932, 0.394799511511351, 0.0864390600094873},
+    {-0.094174739653074, -0.0941747396530738, 0.0860094490830938, -0.113289477381595, 0.398876298584894, 0.0873316488608436, 0.289367309751452, 0.0873316488608435, 0.289367309751452, 0.0633552917951636},
+    {-0.0756396175073989, -0.0756396175073988, -0.0642304995808229, -0.0858635974275115, 0.661734234526899, 0.144882867229582, 0.157675602800014, 0.144882867229582, 0.157675602800014, 0.0345221574370429},
+    {-0.0494789006423166, -0.0494789006423165, -0.124962882172976, 0.170424436369033, 0.645264321612071, 0.141276875455818, 0.0566387271134483, 0.141276875455818, 0.0566387271134482, 0.0124007203379724},
+    {-0.0216509230853557, -0.0216509230853557, -0.082126158551913, 0.597532333802715, 0.35263081891668, 0.0772064696859616, 0.00939722265546143, 0.0772064696859615, 0.00939722265546143, 0.00205746732038352},
+    {-0.0430392698573708, -0.0430392698573707, 0.644527340422526, -0.03218753374648, 0.120375266907318, 0.00657884021103598, 0.165578239218447, 0.0065788402110358, 0.165578239218447, 0.00904930727241116},
+    {-0.0374042602423, -0.0374042602422999, 0.365205425929728, -0.113289477381595, 0.517025822975488, 0.0282568866655468, 0.121360154303653, 0.0282568866655467, 0.121360154303653, 0.00663266702257968},
+    {-0.0282517358523633, -0.0282517358523632, 0.0549952189160882, -0.0858635974275115, 0.857743837904439, 0.0468780655408114, 0.0661288778686417, 0.0468780655408113, 0.0661288778686419, 0.0036141254928047},
+    {-0.0173663754687444, -0.0173663754687443, -0.112316360033967, 0.170424436369033, 0.836395439141882, 0.0457113166909128, 0.0237541851840646, 0.0457113166909126, 0.0237541851840646, 0.00129823171058596},
+    {-0.00723049480167941, -0.00723049480167938, -0.0982128569779484, 0.597532333802715, 0.457082158061876, 0.0249808001133636, 0.00394117909335424, 0.0249808001133633, 0.00394117909335422, 0.000215396303280713},
+    {-0.12239598458967, 0.303869742063848, -0.0354790412346856, -0.03218753374648, 0.00531592754484438, 0.0986289749858684, 0.109622633545923, 0.0295880447986774, 0.0328860701712705, 0.610151166460404},
+    {-0.1160592350988, 0.134887288422247, -0.0307383325090586, -0.113289477381595, 0.0228325293423221, 0.423622960691414, 0.0803476337536981, 0.127084106272845, 0.0241037624827062, 0.447208764024221},
+    {-0.0986364671877794, -0.0444896276300268, -0.0231086697816145, -0.0858635974275114, 0.0378790777498121, 0.702788851119186, 0.0437812467363741, 0.210832040117064, 0.0131340865091965, 0.2436830597953},
+    {-0.0678941422087684, -0.124193144215204, -0.0141333119882805, 0.170424436369033, 0.036936304836938, 0.685297129259398, 0.0157266821407568, 0.205584638427371, 0.00471790136500898, 0.0875335060137464},
+    {-0.030824777921407, -0.0858073223121641, -0.00585919230167206, 0.597532333802715, 0.0201853395363087, 0.374508367808493, 0.00260929475714279, 0.112350050943801, 0.000782771291888154, 0.0145231343948942},
+    {-0.114824393538401, 0.113856014607669, -0.118077197088165, -0.03218753374648, 0.026441315299429, 0.0823785946236129, 0.45542209017267, 0.0247130374063481, 0.136623636292144, 0.425654435971174},
+    {-0.106168256116312, 0.0100888557121194, -0.1100914948925, -0.113289477381595, 0.113568535750516, 0.353825680101135, 0.333800476424499, 0.106145380454931, 0.100137950857575, 0.311982349089632},
+    {-0.0874149447727762, -0.0930517568994225, -0.0916202401200295, -0.0858635974275114, 0.188409760965562, 0.58699543294085, 0.1818871363886, 0.17609477507965, 0.0545649464626407, 0.169998487382437},
+    {-0.0585145790109276, -0.12380786286986, -0.0619213666662117, 0.170424436369033, 0.183720427705323, 0.572385695137502, 0.0653357634308634, 0.171711949680883, 0.0196002999689001, 0.0610652362544955},
+    {-0.026045788733914, -0.0750005711613296, -0.0277535590855747, 0.597532333802715, 0.100401467590206, 0.312803342215279, 0.0108401927023285, 0.0938389484831182, 0.00325198662308662, 0.0101316475640852},
+    {-0.0938555051869133, -0.0689680280637323, -0.0652595091978644, -0.03218753374648, 0.0584840672683638, 0.0577301993658456, 0.705922921633706, 0.0173186806951806, 0.211772240689959, 0.209042466541935},
+    {-0.0842141745825612, -0.101961128009395, -0.0999143296911785, -0.113289477381595, 0.251195895861737, 0.247957945220146, 0.517404431284758, 0.0743857552246979, 0.155217931587356, 0.153217150486034},
+    {-0.0666063780815065, -0.124620776265111, -0.124407329288456, -0.0858635974275114, 0.416733018367064, 0.411361270793064, 0.281932522593158, 0.123405679825933, 0.0845779053253435, 0.0834876841580226},
+    {-0.042927113770228, -0.108104492267147, -0.108854935406145, 0.170424436369033, 0.406360944257666, 0.401122894186574, 0.101273113455689, 0.120334234079468, 0.0303812689755499, 0.0299896501195402},
+    {-0.0185713191445567, -0.0561005440374291, -0.056723422104895, 0.597532333802715, 0.222072393823573, 0.219209849244196, 0.016802743364071, 0.065761515220835, 0.00504071266550261, 0.00497573716598929},
+    {-0.0586399952744005, -0.12386321264862, 0.230182647427123, -0.03218753374648, 0.0928673941832035, 0.0312813527469399, 0.607386932104929, 0.00938420039924669, 0.182212090917773, 0.0613761238902859},
+    {-0.0513370646747661, -0.118642598591026, 0.0860094490830938, -0.113289477381595, 0.398876298584894, 0.134357061573334, 0.445182725400454, 0.0403062361483534, 0.13355189410245, 0.0449854757548079},
+    {-0.0391997300710068, -0.102069833084256, -0.0642304995808229, -0.0858635974275115, 0.661734234526899, 0.222897844792828, 0.242579075860235, 0.0668678896663356, 0.0727721297397927, 0.024512485577508},
+    {-0.0243769453534136, -0.0709852770155237, -0.124962882172976, 0.170424436369033, 0.645264321612071, 0.217350137116399, 0.0871369434274908, 0.0652036137952371, 0.0261405107994057, 0.00880514142227651},
+    {-0.0102482264730672, -0.0324570586983408, -0.082126158551913, 0.597532333802715, 0.35263081891668, 0.118779784153457, 0.0144573386556573, 0.0356331552184663, 0.0043371066552656, 0.00146090632108002},
+    {-0.0209884113390655, -0.0624662889902573, 0.644527340422526, -0.03218753374648, 0.120375266907318, 0.010121343760768, 0.254737039458918, 0.0030363366613038, 0.0764194389779762, 0.00642546788699245},
+    {-0.0180873896108673, -0.0547979943904275, 0.365205425929728, -0.113289477381595, 0.517025822975488, 0.0434723529340782, 0.186708872865861, 0.0130414203970153, 0.0560114357414458, 0.00470953053927457},
+    {-0.0134881345751056, -0.0419674243417795, 0.0549952189160882, -0.0858635974275115, 0.857743837904439, 0.0721204651516608, 0.101737249112632, 0.0216356659299618, 0.0305205066246514, 0.00256621270496323},
+    {-0.00817643359622858, -0.0261798960980541, -0.112316360033967, 0.170424436369033, 0.836395439141882, 0.0703254578534909, 0.0365450848922505, 0.0210971755283345, 0.0109632854758786, 0.000921810467379901},
+    {-0.00336386041082355, -0.0110346752071629, -0.0982128569779484, 0.597532333802715, 0.457082158061876, 0.0384321943162945, 0.00606338308075567, 0.0115294059104325, 0.00181897510595279, 0.000152942317908342},
+    {-0.0397031660797491, 0.677651385532497, -0.0354790412346856, -0.03218753374648, 0.00531592754484438, 0.12220234950981, 0.135823609448279, 0.00601467027473575, 0.00668509426891421, 0.153676704481834},
+    {-0.0344566541637982, 0.387856517182057, -0.0307383325090586, -0.113289477381595, 0.0228325293423221, 0.524873356031632, 0.0995515731929938, 0.0258337109326267, 0.00489982304341051, 0.112636954329409},
+    {-0.0259706778394854, 0.0651520171918798, -0.0231086697816145, -0.0858635974275114, 0.0378790777498121, 0.870762864851529, 0.0542454305787948, 0.0428580263847204, 0.00266990266677576, 0.0613756256250995},
+    {-0.0159280095028661, -0.110672538127309, -0.0141333119882806, 0.170424436369033, 0.036936304836938, 0.849090435339365, 0.0194855265186504, 0.0417913323474039, 0.000959056987115348, 0.0220467672199497},
+    {-0.00661888574963571, -0.0991479726822842, -0.00585919230167209, 0.597532333802715, 0.0201853395363087, 0.464019852825596, 0.0032329439693778, 0.0228385659266992, 0.000159122079653129, 0.00365789259324308},
+    {-0.0336820137710778, 0.351159931970128, -0.118077197088165, -0.0321875337464799, 0.026441315299429, 0.102067955322096, 0.564272815830671, 0.00502367670786549, 0.0277729106341421, 0.107208138841391},
+    {-0.0291609440100797, 0.166485956767395, -0.1100914948925, -0.113289477381595, 0.113568535750516, 0.438393782673502, 0.413582342231706, 0.0215772778825632, 0.0203560850503691, 0.0785779359281241},
+    {-0.0218995359044539, -0.0313856207168029, -0.0916202401200295, -0.0858635974275114, 0.188409760965562, 0.727293587580909, 0.225360097430628, 0.0357966204395903, 0.0110919854206136, 0.0428169423314951},
+    {-0.0133783318084251, -0.123259167721811, -0.0619213666662117, 0.170424436369033, 0.183720427705323, 0.709191966981616, 0.080951706122999, 0.034905677836769, 0.00398435727676454, 0.0153802939039443},
+    {-0.00554072800987505, -0.0879258080236823, -0.0277535590855747, 0.597532333802715, 0.100401467590206, 0.387566669517808, 0.01343111410773, 0.0190756211805888, 0.000661065217685206, 0.00255182370239895},
+    {-0.0241572747358242, 0.0177253911135256, -0.0652595091978644, -0.03218753374648, 0.0584840672683638, 0.0715283313162982, 0.874646011568391, 0.00352054874472813, 0.0430491507552746, 0.0526508169135876},
+    {-0.0208412114214238, -0.0507072246191906, -0.0999143296911785, -0.113289477381595, 0.251195895861737, 0.307222532626626, 0.641069596017233, 0.0151211678182183, 0.0315527668548808, 0.0385902839346929},
+    {-0.0155679467426813, -0.113199283239695, -0.124407329288456, -0.0858635974275114, 0.416733018367064, 0.509680991772005, 0.349317395512301, 0.0250859588469928, 0.0171930324062, 0.0210277597937819},
+    {-0.00945478319693848, -0.119140564162676, -0.108854935406145, 0.170424436369033, 0.406360944257666, 0.49699553421089, 0.125478465209964, 0.024461594055151, 0.00617591722127439, 0.00755339144178018},
+    {-0.00389606166055691, -0.0670532863962544, -0.0567234221048951, 0.597532333802715, 0.222072393823573, 0.271603335806442, 0.0208187778246103, 0.013368028658589, 0.0010246782049633, 0.00125322204081482},
+    {-0.0134113789015497, -0.123174301249333, 0.230182647427123, -0.03218753374648, 0.0928673941832035, 0.0387579289156042, 0.752558872029367, 0.00190762423058233, 0.0370401509933354, 0.0154585961181475},
+    {-0.0115286565516395, -0.124795870133571, 0.0860094490830939, -0.113289477381595, 0.398876298584894, 0.166469828971132, 0.551586133921708, 0.00819346875055493, 0.0271484855811958, 0.0113303391742266},
+    {-0.00856402179742457, -0.114366932369083, -0.0642304995808229, -0.0858635974275115, 0.661734234526899, 0.276172801534836, 0.300558056253616, 0.0135929329243277, 0.0147931493464114, 0.00617387658875263},
+    {-0.00516925988494049, -0.083605542162086, -0.124962882172976, 0.170424436369033, 0.645264321612071, 0.269299132691067, 0.107963600123275, 0.013254618220569, 0.0053138541036216, 0.00221772110036569},
+    {-0.00211875374858132, -0.0394935786210076, -0.082126158551913, 0.597532333802715, 0.35263081891668, 0.147169416491455, 0.0179127964336388, 0.00724352288046848, 0.000881648877284022, 0.000367953519260972},
+    {-0.00442262762728068, -0.074224965614645, 0.644527340422526, -0.03218753374648, 0.120375266907318, 0.0125404526199275, 0.315621902524215, 0.000617227802144259, 0.0155345759126795, 0.00161836079959531},
+    {-0.00379122127793318, -0.0655708056648835, 0.365205425929728, -0.113289477381595, 0.517025822975488, 0.0538627078708381, 0.23133428023363, 0.00265106546025539, 0.0113860283736764, 0.00118617348079642},
+    {-0.00280421494922354, -0.0507314745513394, 0.0549952189160882, -0.0858635974275115, 0.857743837904439, 0.0893580237504861, 0.126053534227744, 0.0043981073311365, 0.00620422150953936, 0.000646343288641096},
+    {-0.001684502510099, -0.031982189992167, -0.112316360033967, 0.170424436369033, 0.836395439141882, 0.0871339906075375, 0.0452797490545588, 0.00428864277428789, 0.00222862131357036, 0.000232173275363283},
+    {-0.000687522410446992, -0.0135965919524168, -0.0982128569779484, 0.597532333802715, 0.457082158061876, 0.0476178977115159, 0.0075125961569867, 0.00234370251521104, 0.000369762029721762, 3.85210627857485e-05}};
+    
+    // Array of non-zero columns
+    static const unsigned int nzc0[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+    // Array of non-zero columns
+    static const unsigned int nzc4[10] = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19};
+    static const double FE1_C0_D001[125][7] = \
+    {{-2.53401086900984, -0.861684240327141, 0.153733097585334, 0.173940273731973, 3.39569510933698, -0.153733097585335, -0.173940273731971},
+    {-2.0255498358363, -0.306078716913218, 0.131614521121219, 0.148914359955701, 2.33162855274952, -0.131614521121219, -0.1489143599557},
+    {-1.23337591087837, 0.559545548262077, 0.0971541428643073, 0.10992439799525, 0.673830362616288, -0.0971541428643072, -0.109924397995249},
+    {-0.338555305646693, 1.53733389052355, 0.0582285287322854, 0.0658822750974736, -1.19877858487685, -0.0582285287322849, -0.065882275097473},
+    {0.454770511952704, 2.40421685178807, 0.0237180419639913, 0.0268356182006482, -2.85898736374077, -0.0237180419639907, -0.0268356182006476},
+    {-1.95173754786883, -0.86168424032714, 0.764665295175825, 0.145281397282487, 2.81342178819597, -0.764665295175825, -0.145281397282486},
+    {-1.52705194873624, -0.306078716913217, 0.654647946495179, 0.124378821681794, 1.83313066564946, -0.654647946495179, -0.124378821681793},
+    {-0.865398771818851, 0.559545548262077, 0.483242727153488, 0.0918129527655822, 0.305853223556774, -0.483242727153488, -0.0918129527655815},
+    {-0.118011263129872, 1.53733389052355, 0.289627515545325, 0.0550273308012553, -1.41932262739368, -0.289627515545325, -0.0550273308012548},
+    {0.544604017438855, 2.40421685178807, 0.117973057488944, 0.0224141081618458, -2.94882086922692, -0.117973057488943, -0.0224141081618453},
+    {-1.06855188405066, -0.86168424032714, 1.6913204223926, 0.101811933883884, 1.9302361243778, -1.6913204223926, -0.101811933883883},
+    {-0.77093592668034, -0.306078716913217, 1.44797919870299, 0.0871635915298887, 1.07701464359356, -1.44797919870299, -0.0871635915298881},
+    {-0.307255161197394, 0.559545548262078, 1.0688575754173, 0.0643417151232235, -0.252290387064684, -1.0688575754173, -0.0643417151232229},
+    {0.216507474925436, 1.53733389052355, 0.640610911753232, 0.0385626726486572, -1.75384136544898, -0.640610911753231, -0.0385626726486566},
+    {0.680862474241284, 2.40421685178807, 0.260938011286713, 0.0157076111665065, -3.08507932602935, -0.260938011286712, -0.0157076111665059},
+    {-0.120853589128906, -0.86168424032714, 2.6856634241203, 0.0551672270779315, 0.982537829456046, -2.6856634241203, -0.0551672270779307},
+    {0.0404108764001508, -0.306078716913217, 2.29925963250797, 0.0472299608053964, 0.265667840513066, -2.29925963250797, -0.0472299608053958},
+    {0.291658260721922, 0.559545548262078, 1.69724888193056, 0.0348638305292846, -0.851203808984, -1.69724888193056, -0.034863830529284},
+    {0.575461260818928, 1.53733389052355, 1.01723202298603, 0.0208953473093509, -2.11279515134248, -1.01723202298603, -0.0208953473093502},
+    {0.827073981595321, 2.40421685178807, 0.414345894247555, 0.00851123555970183, -3.23129083338339, -0.414345894247554, -0.0085112355597012},
+    {0.637338430571104, -0.861684240327141, 3.48117285237853, 0.0178498185197158, 0.224345809756035, -3.48117285237853, -0.0178498185197148},
+    {0.689516899489004, -0.306078716913218, 2.9803139668845, 0.0152816495177238, -0.383438182575788, -2.9803139668845, -0.0152816495177229},
+    {0.770810095671614, 0.559545548262077, 2.1999840629478, 0.0112804844617395, -1.33035564393369, -2.1999840629478, -0.0112804844617387},
+    {0.862636934093748, 1.53733389052355, 1.31854217888416, 0.00676086468604747, -2.3999708246173, -1.31854217888415, -0.00676086468604671},
+    {0.94404833794709, 2.40421685178807, 0.537077604585377, 0.00275388157364889, -3.34826518973516, -0.537077604585376, -0.00275388157364832},
+    {-1.85228451823978, -0.86168424032714, 0.153733097585334, 0.855666624502025, 2.71396875856692, -0.153733097585334, -0.855666624502024},
+    {-1.44190787062765, -0.306078716913217, 0.131614521121219, 0.732556325164345, 1.74798658754087, -0.131614521121219, -0.732556325164345},
+    {-0.802547804781613, 0.559545548262077, 0.0971541428643073, 0.540752504092003, 0.243002256519535, -0.0971541428643072, -0.540752504092002},
+    {-0.0803420579669869, 1.53733389052355, 0.0582285287322856, 0.32409552277718, -1.45699183255656, -0.0582285287322852, -0.32409552277718},
+    {0.559947695327595, 2.40421685178807, 0.0237180419639915, 0.132012801575539, -2.96416454711566, -0.0237180419639909, -0.132012801575539},
+    {-1.38233429996559, -0.86168424032714, 0.764665295175825, 0.714684645185728, 2.24401854029273, -0.764665295175825, -0.714684645185728},
+    {-1.03957243407901, -0.306078716913217, 0.654647946495179, 0.611858336339029, 1.34565115099223, -0.654647946495179, -0.611858336339028},
+    {-0.505555085826084, 0.559545548262077, 0.483242727153489, 0.45165663875835, -0.0539904624359933, -0.483242727153488, -0.451656638758349},
+    {0.0976580618337187, 1.53733389052355, 0.289627515545326, 0.270696655764846, -1.63499195235727, -0.289627515545325, -0.270696655764845},
+    {0.632451919681933, 2.40421685178807, 0.117973057488944, 0.110262010404924, -3.03666877147, -0.117973057488943, -0.110262010404923},
+    {-0.669519062828044, -0.86168424032714, 1.6913204223926, 0.500844755106496, 1.53120330315518, -1.6913204223926, -0.500844755106495},
+    {-0.429314541944297, -0.306078716913217, 1.44797919870299, 0.428784976265932, 0.735393258857514, -1.44797919870299, -0.428784976265932},
+    {-0.0550798500280451, 0.559545548262077, 1.06885757541731, 0.316517026292572, -0.504465698234032, -1.0688575754173, -0.316517026292572},
+    {0.367646653544982, 1.53733389052355, 0.640610911753232, 0.189701851268203, -1.90498054406853, -0.640610911753231, -0.189701851268203},
+    {0.742425516601204, 2.40421685178807, 0.260938011286713, 0.0772706535264272, -3.14664236838927, -0.260938011286712, -0.0772706535264267},
+    {0.0953640331101715, -0.86168424032714, 2.6856634241203, 0.271384849317009, 0.766320207216968, -2.6856634241203, -0.271384849317009},
+    {0.225519868906913, -0.306078716913217, 2.29925963250797, 0.232338953312159, 0.0805588480063038, -2.29925963250797, -0.232338953312158},
+    {0.428300519875882, 0.559545548262078, 1.69724888193056, 0.171506089683245, -0.98784606813796, -1.69724888193056, -0.171506089683244},
+    {0.657356664129762, 1.53733389052355, 1.01723202298603, 0.102790750620185, -2.19469055465331, -1.01723202298603, -0.102790750620184},
+    {0.860432176532974, 2.40421685178807, 0.414345894247555, 0.0418694304973552, -3.26464902832104, -0.414345894247555, -0.0418694304973546},
+    {0.707297453747672, -0.861684240327141, 3.48117285237853, 0.0878088416962833, 0.154386786579467, -3.48117285237853, -0.0878088416962823},
+    {0.749410464883283, -0.306078716913218, 2.9803139668845, 0.0751752149120023, -0.443331747970067, -2.9803139668845, -0.0751752149120014},
+    {0.815021843428605, 0.559545548262077, 2.1999840629478, 0.0554922322187305, -1.37456739169068, -2.1999840629478, -0.0554922322187298},
+    {0.889134877965972, 1.53733389052355, 1.31854217888416, 0.0332588085582721, -2.42646876848952, -1.31854217888415, -0.0332588085582713},
+    {0.954841661398734, 2.40421685178807, 0.537077604585377, 0.0135472050252931, -3.3590585131868, -0.537077604585376, -0.0135472050252925},
+    {-0.853975571370904, -0.86168424032714, 0.153733097585333, 1.8539755713709, 1.71565981169804, -0.153733097585333, -1.8539755713709},
+    {-0.587232097896, -0.306078716913217, 0.131614521121218, 1.587232097896, 0.893310814809216, -0.131614521121218, -1.587232097896},
+    {-0.171650154436808, 0.559545548262077, 0.0971541428643073, 1.17165015443681, -0.387895393825269, -0.0971541428643073, -1.17165015443681},
+    {0.297781209627916, 1.53733389052355, 0.0582285287322859, 0.702218790372083, -1.83511510015146, -0.0582285287322855, -0.702218790372083},
+    {0.713967446876027, 2.40421685178807, 0.0237180419639917, 0.286032553123971, -3.11818429866409, -0.0237180419639911, -0.286032553123971},
+    {-0.548509472575658, -0.86168424032714, 0.764665295175825, 1.54850947257566, 1.4101937129028, -0.764665295175825, -1.54850947257566},
+    {-0.325715385209019, -0.306078716913217, 0.654647946495179, 1.32571538520902, 0.631794102122236, -0.654647946495179, -1.32571538520902},
+    {0.0213941377077832, 0.559545548262077, 0.483242727153489, 0.978605862292217, -0.58093968596986, -0.483242727153489, -0.978605862292217},
+    {0.413480703034436, 1.53733389052355, 0.289627515545326, 0.586519296965564, -1.95081459355798, -0.289627515545326, -0.586519296965563},
+    {0.761094954638504, 2.40421685178807, 0.117973057488944, 0.238905045361495, -3.16531180642657, -0.117973057488944, -0.238905045361495},
+    {-0.0851819089672699, -0.86168424032714, 1.6913204223926, 1.08518190896727, 0.94686614929441, -1.6913204223926, -1.08518190896727},
+    {0.0709502408948852, -0.306078716913217, 1.44797919870299, 0.929049759105114, 0.235128476018332, -1.44797919870299, -0.929049759105114},
+    {0.314201561839691, 0.559545548262078, 1.06885757541731, 0.685798438160309, -0.873747110101769, -1.06885757541731, -0.685798438160308},
+    {0.588972401138389, 1.53733389052355, 0.640610911753232, 0.41102759886161, -2.12630629166194, -0.640610911753232, -0.41102759886161},
+    {0.832577431537388, 2.40421685178807, 0.260938011286713, 0.167422568462611, -3.23679428332545, -0.260938011286712, -0.16742256846261},
+    {0.411989591896581, -0.861684240327141, 2.6856634241203, 0.588010408103419, 0.449694648430559, -2.6856634241203, -0.588010408103418},
+    {0.496590457797377, -0.306078716913217, 2.29925963250797, 0.503409542202622, -0.19051174088416, -2.29925963250797, -0.503409542202622},
+    {0.628397215096318, 0.559545548262078, 1.69724888193056, 0.371602784903681, -1.1879427633584, -1.69724888193056, -0.37160278490368},
+    {0.777282956754788, 1.53733389052355, 1.01723202298603, 0.222717043245211, -2.31461684727834, -1.01723202298603, -0.22271704324521},
+    {0.909281373017809, 2.40421685178807, 0.414345894247555, 0.0907186269821898, -3.31349822480587, -0.414345894247555, -0.0907186269821892},
+    {0.809744306025694, -0.861684240327141, 3.48117285237853, 0.190255693974306, 0.0519399343014453, -3.48117285237853, -0.190255693974305},
+    {0.83711762498564, -0.306078716913218, 2.9803139668845, 0.162882375014359, -0.531038908072423, -2.9803139668845, -0.162882375014358},
+    {0.879764805604936, 0.559545548262077, 2.1999840629478, 0.120235194395062, -1.43931035386701, -2.1999840629478, -0.120235194395062},
+    {0.92793803470385, 1.53733389052355, 1.31854217888416, 0.0720619652961492, -2.4652719252274, -1.31854217888415, -0.0720619652961484},
+    {0.97064722818672, 2.40421685178807, 0.537077604585377, 0.0293527718132788, -3.37486407997479, -0.537077604585376, -0.0293527718132783},
+    {0.144333375497976, -0.86168424032714, 0.153733097585332, 2.85228451823978, 0.717350864829163, -0.153733097585332, -2.85228451823978},
+    {0.267443674835655, -0.306078716913217, 0.131614521121218, 2.44190787062765, 0.0386350420775618, -0.131614521121218, -2.44190787062765},
+    {0.459247495907997, 0.559545548262077, 0.0971541428643074, 1.80254780478161, -1.01879304417007, -0.0971541428643074, -1.80254780478161},
+    {0.675904477222819, 1.53733389052355, 0.0582285287322862, 1.08034205796699, -2.21323836774637, -0.0582285287322859, -1.08034205796699},
+    {0.86798719842446, 2.40421685178807, 0.0237180419639919, 0.440052304672404, -3.27220405021253, -0.0237180419639914, -0.440052304672404},
+    {0.285315354814272, -0.86168424032714, 0.764665295175825, 2.38233429996559, 0.576368885512868, -0.764665295175825, -2.38233429996559},
+    {0.388141663660971, -0.306078716913217, 0.654647946495179, 2.03957243407901, -0.0820629467477537, -0.654647946495179, -2.03957243407901},
+    {0.54834336124165, 0.559545548262077, 0.483242727153489, 1.50555508582608, -1.10788890950373, -0.483242727153489, -1.50555508582608},
+    {0.729303344235153, 1.53733389052355, 0.289627515545326, 0.902341938166281, -2.2666372347587, -0.289627515545326, -0.902341938166281},
+    {0.889737989595075, 2.40421685178807, 0.117973057488944, 0.367548080318067, -3.29395484138314, -0.117973057488944, -0.367548080318066},
+    {0.499155244893504, -0.86168424032714, 1.6913204223926, 1.66951906282804, 0.362528995433636, -1.6913204223926, -1.66951906282804},
+    {0.571215023734067, -0.306078716913217, 1.44797919870299, 1.4293145419443, -0.26513630682085, -1.44797919870299, -1.4293145419443},
+    {0.683482973707427, 0.559545548262078, 1.06885757541731, 1.05507985002804, -1.2430285219695, -1.06885757541731, -1.05507985002804},
+    {0.810298148731796, 1.53733389052355, 0.640610911753232, 0.632353346455017, -2.34763203925534, -0.640610911753232, -0.632353346455017},
+    {0.922729346473571, 2.40421685178807, 0.260938011286713, 0.257574483398795, -3.32694619826164, -0.260938011286713, -0.257574483398794},
+    {0.72861515068299, -0.861684240327141, 2.6856634241203, 0.904635966889828, 0.13306908964415, -2.6856634241203, -0.904635966889828},
+    {0.76766104668784, -0.306078716913217, 2.29925963250797, 0.774480131093086, -0.461582329774624, -2.29925963250797, -0.774480131093086},
+    {0.828493910316754, 0.559545548262078, 1.69724888193056, 0.571699480124117, -1.38803945857883, -1.69724888193056, -0.571699480124116},
+    {0.897209249379814, 1.53733389052355, 1.01723202298603, 0.342643335870237, -2.43454313990336, -1.01723202298603, -0.342643335870237},
+    {0.958130569502644, 2.40421685178807, 0.414345894247555, 0.139567823467025, -3.36234742129071, -0.414345894247555, -0.139567823467024},
+    {0.912191158303716, -0.861684240327141, 3.48117285237853, 0.292702546252328, -0.050506917976577, -3.48117285237853, -0.292702546252327},
+    {0.924824785087997, -0.306078716913218, 2.9803139668845, 0.250589535116716, -0.61874606817478, -2.9803139668845, -0.250589535116716},
+    {0.944507767781268, 0.559545548262077, 2.1999840629478, 0.184978156571394, -1.50405331604335, -2.1999840629478, -0.184978156571393},
+    {0.966741191441727, 1.53733389052355, 1.31854217888416, 0.110865122034026, -2.50407508196527, -1.31854217888415, -0.110865122034026},
+    {0.986452794974706, 2.40421685178807, 0.537077604585377, 0.0451583386012648, -3.39066964676277, -0.537077604585376, -0.0451583386012643},
+    {0.826059726268027, -0.861684240327139, 0.153733097585331, 3.53401086900984, 0.0356245140591109, -0.153733097585331, -3.53401086900983},
+    {0.8510856400443, -0.306078716913217, 0.131614521121218, 3.0255498358363, -0.545006923131083, -0.131614521121217, -3.0255498358363},
+    {0.890075602004749, 0.559545548262077, 0.0971541428643075, 2.23337591087837, -1.44962115026683, -0.0971541428643074, -2.23337591087836},
+    {0.934117724902526, 1.53733389052355, 0.0582285287322864, 1.33855530564669, -2.47145161542607, -0.0582285287322861, -1.33855530564669},
+    {0.973164381799351, 2.40421685178807, 0.023718041963992, 0.545229488047295, -3.37738123358742, -0.0237180419639916, -0.545229488047295},
+    {0.854718602717513, -0.86168424032714, 0.764665295175825, 2.95173754786883, 0.00696563760962579, -0.764665295175824, -2.95173754786883},
+    {0.875621178318205, -0.306078716913217, 0.654647946495179, 2.52705194873624, -0.569542461404989, -0.654647946495179, -2.52705194873624},
+    {0.908187047234417, 0.559545548262077, 0.483242727153489, 1.86539877181885, -1.46773259549649, -0.483242727153489, -1.86539877181885},
+    {0.944972669198744, 1.53733389052355, 0.289627515545326, 1.11801126312987, -2.48230655972229, -0.289627515545326, -1.11801126312987},
+    {0.977585891838153, 2.40421685178807, 0.117973057488945, 0.455395982561145, -3.38180274362622, -0.117973057488944, -0.455395982561144},
+    {0.898188066116116, -0.86168424032714, 1.6913204223926, 2.06855188405066, -0.0365038257889762, -1.6913204223926, -2.06855188405065},
+    {0.91283640847011, -0.306078716913217, 1.44797919870299, 1.77093592668034, -0.606757691556894, -1.44797919870299, -1.77093592668034},
+    {0.935658284876775, 0.559545548262078, 1.06885757541731, 1.30725516119739, -1.49520383313885, -1.06885757541731, -1.30725516119739},
+    {0.961437327351342, 1.53733389052355, 0.640610911753233, 0.783492525074564, -2.49877121787489, -0.640610911753232, -0.783492525074563},
+    {0.984292388833492, 2.40421685178807, 0.260938011286713, 0.319137525758715, -3.38850924062156, -0.260938011286713, -0.319137525758715},
+    {0.944832772922068, -0.861684240327141, 2.6856634241203, 1.12085358912891, -0.083148532594928, -2.6856634241203, -1.12085358912891},
+    {0.952770039194602, -0.306078716913217, 2.29925963250797, 0.959589123599848, -0.646691322281386, -2.29925963250797, -0.959589123599848},
+    {0.965136169470714, 0.559545548262077, 1.69724888193056, 0.708341739278077, -1.52468171773279, -1.69724888193056, -0.708341739278077},
+    {0.979104652690648, 1.53733389052355, 1.01723202298603, 0.424538739181071, -2.5164385432142, -1.01723202298603, -0.42453873918107},
+    {0.991488764440297, 2.40421685178807, 0.414345894247555, 0.172926018404678, -3.39570561622836, -0.414345894247555, -0.172926018404678},
+    {0.982150181480283, -0.861684240327141, 3.48117285237853, 0.362661569428895, -0.120465941153144, -3.48117285237853, -0.362661569428894},
+    {0.984718350482275, -0.306078716913218, 2.9803139668845, 0.310483100510995, -0.678639633569059, -2.9803139668845, -0.310483100510994},
+    {0.988719515538259, 0.559545548262078, 2.1999840629478, 0.229189904328385, -1.54826506380034, -2.1999840629478, -0.229189904328384},
+    {0.993239135313951, 1.53733389052355, 1.31854217888416, 0.137363065906251, -2.5305730258375, -1.31854217888415, -0.13736306590625},
+    {0.997246118426349, 2.40421685178807, 0.537077604585377, 0.0559516620529087, -3.40146297021442, -0.537077604585376, -0.0559516620529083}};
+    
+    // Array of non-zero columns
+    static const unsigned int nzc1[7] = {0, 3, 4, 5, 7, 8, 9};
+    static const double FE1_C0_D010[125][7] = \
+    {{-2.53401086900984, -0.846266902414667, 0.138315759672862, 0.173940273731974, -0.138315759672862, 3.3802777714245, -0.173940273731973},
+    {-2.0255498358363, -0.868385478878781, 0.693921283086784, 0.148914359955701, -0.693921283086783, 2.89393531471508, -0.148914359955701},
+    {-1.23337591087837, -0.902845857135692, 1.55954554826208, 0.109924397995249, -1.55954554826208, 2.13622176801406, -0.109924397995249},
+    {-0.338555305646693, -0.941771471267714, 2.53733389052355, 0.065882275097473, -2.53733389052355, 1.28032677691441, -0.0658822750974729},
+    {0.454770511952705, -0.976281958036009, 3.40421685178806, 0.0268356182006484, -3.40421685178806, 0.521511446083304, -0.0268356182006486},
+    {-1.95173754786883, -0.235334704824175, 0.138315759672861, 0.145281397282487, -0.138315759672861, 2.187072252693, -0.145281397282487},
+    {-1.52705194873624, -0.345352053504821, 0.693921283086783, 0.124378821681794, -0.693921283086783, 1.87240400224106, -0.124378821681793},
+    {-0.865398771818851, -0.516757272846511, 1.55954554826208, 0.0918129527655817, -1.55954554826208, 1.38215604466536, -0.0918129527655814},
+    {-0.118011263129871, -0.710372484454674, 2.53733389052355, 0.0550273308012549, -2.53733389052355, 0.828383747584545, -0.0550273308012547},
+    {0.544604017438855, -0.882026942511057, 3.40421685178806, 0.0224141081618461, -3.40421685178806, 0.337422925072202, -0.0224141081618463},
+    {-1.06855188405066, 0.6913204223926, 0.138315759672859, 0.101811933883883, -0.13831575967286, 0.377231461658056, -0.101811933883884},
+    {-0.77093592668034, 0.447979198702987, 0.693921283086782, 0.0871635915298881, -0.693921283086782, 0.322956727977352, -0.0871635915298884},
+    {-0.307255161197393, 0.0688575754173049, 1.55954554826208, 0.0643417151232227, -1.55954554826208, 0.238397585780088, -0.0643417151232226},
+    {0.216507474925436, -0.359389088246769, 2.53733389052355, 0.0385626726486567, -2.53733389052355, 0.142881613321332, -0.0385626726486567},
+    {0.680862474241284, -0.739061988713288, 3.40421685178806, 0.0157076111665069, -3.40421685178806, 0.058199514472004, -0.015707611166507},
+    {-0.120853589128906, 1.6856634241203, 0.138315759672859, 0.0551672270779304, -0.138315759672859, -1.5648098349914, -0.0551672270779314},
+    {0.0404108764001513, 1.29925963250797, 0.693921283086782, 0.0472299608053954, -0.693921283086782, -1.33967050890812, -0.0472299608053959},
+    {0.291658260721923, 0.69724888193056, 1.55954554826208, 0.034863830529284, -1.55954554826208, -0.988907142652483, -0.0348638305292839},
+    {0.575461260818929, 0.0172320229860303, 2.53733389052355, 0.0208953473093507, -2.53733389052355, -0.59269328380496, -0.0208953473093506},
+    {0.827073981595321, -0.585654105752446, 3.40421685178807, 0.00851123555970239, -3.40421685178807, -0.241419875842875, -0.00851123555970248},
+    {0.637338430571105, 2.48117285237853, 0.138315759672859, 0.0178498185197145, -0.138315759672859, -3.11851128294963, -0.0178498185197154},
+    {0.689516899489005, 1.9803139668845, 0.693921283086782, 0.0152816495177227, -0.693921283086782, -2.6698308663735, -0.015281649517723},
+    {0.770810095671614, 1.1999840629478, 1.55954554826208, 0.011280484461739, -1.55954554826208, -1.97079415861941, -0.0112804844617389},
+    {0.862636934093749, 0.318542178884154, 2.53733389052355, 0.00676086468604743, -2.53733389052355, -1.1811791129779, -0.00676086468604731},
+    {0.94404833794709, -0.462922395414624, 3.40421685178807, 0.00275388157364971, -3.40421685178807, -0.481125942532466, -0.00275388157364974},
+    {-1.85228451823978, -0.846266902414667, 0.138315759672862, 0.855666624502025, -0.138315759672862, 2.69855142065445, -0.855666624502025},
+    {-1.44190787062765, -0.868385478878781, 0.693921283086783, 0.732556325164345, -0.693921283086783, 2.31029334950644, -0.732556325164345},
+    {-0.802547804781612, -0.902845857135692, 1.55954554826208, 0.540752504092002, -1.55954554826208, 1.7053936619173, -0.540752504092002},
+    {-0.0803420579669867, -0.941771471267714, 2.53733389052355, 0.32409552277718, -2.53733389052355, 1.0221135292347, -0.32409552277718},
+    {0.559947695327596, -0.976281958036009, 3.40421685178806, 0.13201280157554, -3.40421685178806, 0.416334262708413, -0.13201280157554},
+    {-1.38233429996559, -0.235334704824175, 0.138315759672861, 0.714684645185729, -0.138315759672861, 1.61766900478976, -0.714684645185729},
+    {-1.03957243407901, -0.345352053504821, 0.693921283086783, 0.611858336339028, -0.693921283086783, 1.38492448758383, -0.611858336339029},
+    {-0.505555085826084, -0.516757272846511, 1.55954554826208, 0.451656638758349, -1.55954554826208, 1.02231235867259, -0.451656638758349},
+    {0.097658061833719, -0.710372484454674, 2.53733389052355, 0.270696655764845, -2.53733389052355, 0.612714422620955, -0.270696655764845},
+    {0.632451919681933, -0.882026942511056, 3.40421685178806, 0.110262010404924, -3.40421685178806, 0.249575022829124, -0.110262010404925},
+    {-0.669519062828044, 0.6913204223926, 0.13831575967286, 0.500844755106495, -0.13831575967286, -0.0218013595645561, -0.500844755106496},
+    {-0.429314541944297, 0.447979198702988, 0.693921283086782, 0.428784976265932, -0.693921283086782, -0.0186646567586911, -0.428784976265932},
+    {-0.0550798500280447, 0.0688575754173051, 1.55954554826208, 0.316517026292572, -1.55954554826208, -0.0137777253892607, -0.316517026292571},
+    {0.367646653544982, -0.359389088246769, 2.53733389052355, 0.189701851268203, -2.53733389052355, -0.00825756529821425, -0.189701851268203},
+    {0.742425516601205, -0.739061988713288, 3.40421685178806, 0.0772706535264277, -3.40421685178806, -0.00336352788791668, -0.0772706535264278},
+    {0.0953640331101717, 1.6856634241203, 0.138315759672859, 0.271384849317008, -0.138315759672859, -1.78102745723047, -0.271384849317009},
+    {0.225519868906913, 1.29925963250797, 0.693921283086782, 0.232338953312158, -0.693921283086782, -1.52477950141488, -0.232338953312158},
+    {0.428300519875883, 0.69724888193056, 1.55954554826208, 0.171506089683245, -1.55954554826208, -1.12554940180644, -0.171506089683245},
+    {0.657356664129763, 0.0172320229860303, 2.53733389052355, 0.102790750620184, -2.53733389052355, -0.674588687115793, -0.102790750620184},
+    {0.860432176532975, -0.585654105752446, 3.40421685178807, 0.0418694304973558, -3.40421685178807, -0.274778070780529, -0.0418694304973559},
+    {0.707297453747672, 2.48117285237853, 0.138315759672859, 0.087808841696282, -0.138315759672859, -3.1884703061262, -0.0878088416962829},
+    {0.749410464883284, 1.9803139668845, 0.693921283086782, 0.0751752149120012, -0.693921283086782, -2.72972443176778, -0.0751752149120015},
+    {0.815021843428605, 1.1999840629478, 1.55954554826208, 0.05549223221873, -1.55954554826208, -2.0150059063764, -0.0554922322187298},
+    {0.889134877965973, 0.318542178884154, 2.53733389052355, 0.0332588085582721, -2.53733389052355, -1.20767705685013, -0.033258808558272},
+    {0.954841661398734, -0.462922395414624, 3.40421685178807, 0.0135472050252939, -3.40421685178807, -0.49191926598411, -0.013547205025294},
+    {-0.853975571370904, -0.846266902414667, 0.138315759672861, 1.8539755713709, -0.138315759672861, 1.70024247378557, -1.8539755713709},
+    {-0.587232097895999, -0.868385478878781, 0.693921283086783, 1.587232097896, -0.693921283086783, 1.45561757677478, -1.587232097896},
+    {-0.171650154436808, -0.902845857135692, 1.55954554826208, 1.17165015443681, -1.55954554826208, 1.0744960115725, -1.17165015443681},
+    {0.297781209627916, -0.941771471267714, 2.53733389052355, 0.702218790372083, -2.53733389052355, 0.643990261639798, -0.702218790372083},
+    {0.713967446876028, -0.976281958036009, 3.40421685178806, 0.286032553123972, -3.40421685178806, 0.262314511159981, -0.286032553123972},
+    {-0.548509472575657, -0.235334704824175, 0.13831575967286, 1.54850947257566, -0.13831575967286, 0.783844177399832, -1.54850947257566},
+    {-0.325715385209019, -0.345352053504821, 0.693921283086783, 1.32571538520902, -0.693921283086783, 0.67106743871384, -1.32571538520902},
+    {0.0213941377077833, -0.516757272846511, 1.55954554826208, 0.978605862292217, -1.55954554826208, 0.495363135138727, -0.978605862292217},
+    {0.413480703034436, -0.710372484454674, 2.53733389052355, 0.586519296965563, -2.53733389052355, 0.296891781420238, -0.586519296965563},
+    {0.761094954638504, -0.882026942511056, 3.40421685178806, 0.238905045361496, -3.40421685178806, 0.120931987872552, -0.238905045361496},
+    {-0.08518190896727, 0.6913204223926, 0.13831575967286, 1.08518190896727, -0.13831575967286, -0.60613851342533, -1.08518190896727},
+    {0.0709502408948853, 0.447979198702988, 0.693921283086783, 0.929049759105114, -0.693921283086783, -0.518929439597874, -0.929049759105114},
+    {0.314201561839691, 0.0688575754173052, 1.55954554826208, 0.685798438160308, -1.55954554826208, -0.383059137256997, -0.685798438160308},
+    {0.588972401138389, -0.359389088246769, 2.53733389052355, 0.41102759886161, -2.53733389052355, -0.229583312891621, -0.41102759886161},
+    {0.832577431537388, -0.739061988713288, 3.40421685178806, 0.167422568462611, -3.40421685178806, -0.0935154428241002, -0.167422568462612},
+    {0.411989591896581, 1.6856634241203, 0.138315759672859, 0.588010408103418, -0.138315759672859, -2.09765301601688, -0.588010408103419},
+    {0.496590457797377, 1.29925963250797, 0.693921283086782, 0.503409542202622, -0.693921283086782, -1.79585009030535, -0.503409542202622},
+    {0.628397215096319, 0.69724888193056, 1.55954554826208, 0.37160278490368, -1.55954554826208, -1.32564609702688, -0.37160278490368},
+    {0.777282956754789, 0.0172320229860304, 2.53733389052355, 0.222717043245211, -2.53733389052355, -0.79451497974082, -0.222717043245211},
+    {0.909281373017809, -0.585654105752446, 3.40421685178807, 0.0907186269821904, -3.40421685178807, -0.323627267265363, -0.0907186269821905},
+    {0.809744306025694, 2.48117285237853, 0.138315759672859, 0.190255693974304, -0.138315759672859, -3.29091715840422, -0.190255693974305},
+    {0.83711762498564, 1.9803139668845, 0.693921283086782, 0.162882375014358, -0.693921283086783, -2.81743159187014, -0.162882375014359},
+    {0.879764805604937, 1.1999840629478, 1.55954554826208, 0.120235194395062, -1.55954554826208, -2.07974886855273, -0.120235194395062},
+    {0.92793803470385, 0.318542178884154, 2.53733389052355, 0.0720619652961492, -2.53733389052355, -1.246480213588, -0.0720619652961491},
+    {0.97064722818672, -0.462922395414624, 3.40421685178807, 0.0293527718132797, -3.40421685178807, -0.507724832772096, -0.0293527718132797},
+    {0.144333375497976, -0.846266902414667, 0.13831575967286, 2.85228451823978, -0.13831575967286, 0.701933526916691, -2.85228451823978},
+    {0.267443674835655, -0.868385478878781, 0.693921283086782, 2.44190787062765, -0.693921283086783, 0.600941804043126, -2.44190787062765},
+    {0.459247495907997, -0.902845857135692, 1.55954554826208, 1.80254780478161, -1.55954554826208, 0.443598361227695, -1.80254780478161},
+    {0.675904477222819, -0.941771471267714, 2.53733389052355, 1.08034205796699, -2.53733389052355, 0.265866994044895, -1.08034205796699},
+    {0.86798719842446, -0.976281958036009, 3.40421685178806, 0.440052304672404, -3.40421685178806, 0.108294759611549, -0.440052304672405},
+    {0.285315354814272, -0.235334704824175, 0.13831575967286, 2.38233429996559, -0.13831575967286, -0.0499806499900974, -2.38233429996559},
+    {0.388141663660971, -0.345352053504821, 0.693921283086783, 2.03957243407901, -0.693921283086783, -0.0427896101561506, -2.03957243407901},
+    {0.54834336124165, -0.516757272846511, 1.55954554826208, 1.50555508582608, -1.55954554826208, -0.0315860883951393, -1.50555508582608},
+    {0.729303344235153, -0.710372484454674, 2.53733389052355, 0.902341938166281, -2.53733389052355, -0.0189308597804795, -0.902341938166281},
+    {0.889737989595075, -0.882026942511056, 3.40421685178807, 0.367548080318067, -3.40421685178807, -0.00771104708401874, -0.367548080318067},
+    {0.499155244893504, 0.691320422392601, 0.13831575967286, 1.66951906282804, -0.13831575967286, -1.1904756672861, -1.66951906282804},
+    {0.571215023734067, 0.447979198702988, 0.693921283086783, 1.4293145419443, -0.693921283086783, -1.01919422243706, -1.4293145419443},
+    {0.683482973707427, 0.0688575754173054, 1.55954554826208, 1.05507985002804, -1.55954554826208, -0.752340549124733, -1.05507985002804},
+    {0.810298148731796, -0.359389088246768, 2.53733389052355, 0.632353346455017, -2.53733389052355, -0.450909060485028, -0.632353346455017},
+    {0.922729346473572, -0.739061988713288, 3.40421685178806, 0.257574483398795, -3.40421685178806, -0.183667357760284, -0.257574483398796},
+    {0.72861515068299, 1.6856634241203, 0.138315759672859, 0.904635966889828, -0.13831575967286, -2.41427857480329, -0.904635966889828},
+    {0.767661046687841, 1.29925963250797, 0.693921283086783, 0.774480131093086, -0.693921283086783, -2.06692067919581, -0.774480131093086},
+    {0.828493910316754, 0.69724888193056, 1.55954554826208, 0.571699480124116, -1.55954554826208, -1.52574279224731, -0.571699480124116},
+    {0.897209249379815, 0.0172320229860305, 2.53733389052355, 0.342643335870237, -2.53733389052355, -0.914441272365846, -0.342643335870237},
+    {0.958130569502644, -0.585654105752446, 3.40421685178807, 0.139567823467025, -3.40421685178807, -0.372476463750198, -0.139567823467025},
+    {0.912191158303716, 2.48117285237853, 0.138315759672859, 0.292702546252327, -0.138315759672859, -3.39336401068225, -0.292702546252327},
+    {0.924824785087997, 1.9803139668845, 0.693921283086783, 0.250589535116716, -0.693921283086783, -2.9051387519725, -0.250589535116716},
+    {0.944507767781269, 1.1999840629478, 1.55954554826208, 0.184978156571394, -1.55954554826208, -2.14449183072907, -0.184978156571393},
+    {0.966741191441727, 0.318542178884154, 2.53733389052355, 0.110865122034026, -2.53733389052355, -1.28528337032588, -0.110865122034026},
+    {0.986452794974706, -0.462922395414624, 3.40421685178807, 0.0451583386012654, -3.40421685178807, -0.523530399560082, -0.0451583386012656},
+    {0.826059726268028, -0.846266902414667, 0.138315759672859, 3.53401086900983, -0.138315759672859, 0.0202071761466383, -3.53401086900983},
+    {0.8510856400443, -0.868385478878782, 0.693921283086782, 3.0255498358363, -0.693921283086782, 0.0172998388344806, -3.0255498358363},
+    {0.89007560200475, -0.902845857135692, 1.55954554826208, 2.23337591087836, -1.55954554826208, 0.012770255130942, -2.23337591087836},
+    {0.934117724902525, -0.941771471267714, 2.53733389052355, 1.33855530564669, -2.53733389052355, 0.00765374636518801, -1.33855530564669},
+    {0.973164381799351, -0.976281958036009, 3.40421685178806, 0.545229488047295, -3.40421685178806, 0.00311757623665807, -0.545229488047296},
+    {0.854718602717513, -0.235334704824175, 0.138315759672859, 2.95173754786883, -0.13831575967286, -0.61938389789334, -2.95173754786883},
+    {0.875621178318206, -0.345352053504821, 0.693921283086783, 2.52705194873624, -0.693921283086783, -0.530269124813386, -2.52705194873624},
+    {0.908187047234417, -0.516757272846511, 1.55954554826208, 1.86539877181885, -1.55954554826208, -0.391429774387907, -1.86539877181885},
+    {0.944972669198744, -0.710372484454674, 2.53733389052355, 1.11801126312987, -2.53733389052355, -0.23460018474407, -1.11801126312987},
+    {0.977585891838153, -0.882026942511056, 3.40421685178807, 0.455395982561145, -3.40421685178807, -0.0955589493270969, -0.455395982561146},
+    {0.898188066116116, 0.691320422392601, 0.13831575967286, 2.06855188405065, -0.13831575967286, -1.58950848850872, -2.06855188405066},
+    {0.91283640847011, 0.447979198702988, 0.693921283086783, 1.77093592668034, -0.693921283086783, -1.3608156071731, -1.77093592668034},
+    {0.935658284876775, 0.0688575754173055, 1.55954554826208, 1.30725516119739, -1.55954554826208, -1.00451586029408, -1.30725516119739},
+    {0.961437327351342, -0.359389088246768, 2.53733389052355, 0.783492525074564, -2.53733389052355, -0.602048239104574, -0.783492525074564},
+    {0.984292388833492, -0.739061988713288, 3.40421685178807, 0.319137525758716, -3.40421685178807, -0.245230400120204, -0.319137525758716},
+    {0.944832772922068, 1.6856634241203, 0.138315759672859, 1.12085358912891, -0.13831575967286, -2.63049619704237, -1.12085358912891},
+    {0.952770039194603, 1.29925963250797, 0.693921283086783, 0.959589123599848, -0.693921283086783, -2.25202967170258, -0.959589123599848},
+    {0.965136169470714, 0.69724888193056, 1.55954554826208, 0.708341739278077, -1.55954554826208, -1.66238505140128, -0.708341739278077},
+    {0.979104652690649, 0.0172320229860305, 2.53733389052355, 0.424538739181071, -2.53733389052355, -0.996336675676679, -0.424538739181071},
+    {0.991488764440297, -0.585654105752446, 3.40421685178807, 0.172926018404679, -3.40421685178807, -0.405834658687851, -0.172926018404679},
+    {0.982150181480284, 2.48117285237853, 0.138315759672859, 0.362661569428894, -0.13831575967286, -3.46332303385881, -0.362661569428895},
+    {0.984718350482276, 1.9803139668845, 0.693921283086783, 0.310483100510994, -0.693921283086783, -2.96503231736678, -0.310483100510994},
+    {0.98871951553826, 1.1999840629478, 1.55954554826208, 0.229189904328385, -1.55954554826208, -2.18870357848606, -0.229189904328385},
+    {0.993239135313952, 0.318542178884154, 2.53733389052355, 0.137363065906251, -2.53733389052355, -1.31178131419811, -0.137363065906251},
+    {0.99724611842635, -0.462922395414624, 3.40421685178807, 0.0559516620529094, -3.40421685178807, -0.534323723011726, -0.0559516620529098}};
+    
+    // Array of non-zero columns
+    static const unsigned int nzc2[7] = {0, 2, 4, 6, 7, 8, 9};
+    static const double FE1_C0_D100[125][7] = \
+    {{-2.53401086900984, -0.82605972626803, 0.138315759672862, 0.153733097585335, -0.138315759672862, -0.153733097585336, 3.36007059527787},
+    {-2.0255498358363, -0.8510856400443, 0.693921283086783, 0.13161452112122, -0.693921283086783, -0.13161452112122, 2.8766354758806},
+    {-1.23337591087837, -0.89007560200475, 1.55954554826208, 0.0971541428643072, -1.55954554826208, -0.0971541428643071, 2.12345151288312},
+    {-0.338555305646693, -0.934117724902525, 2.53733389052355, 0.0582285287322848, -2.53733389052355, -0.0582285287322848, 1.27267303054922},
+    {0.454770511952704, -0.973164381799351, 3.40421685178806, 0.0237180419639906, -3.40421685178806, -0.0237180419639906, 0.518393869846646},
+    {-1.95173754786883, -0.854718602717514, 0.138315759672861, 0.764665295175825, -0.138315759672861, -0.764665295175826, 2.80645615058634},
+    {-1.52705194873624, -0.875621178318207, 0.693921283086783, 0.654647946495179, -0.693921283086783, -0.654647946495179, 2.40267312705445},
+    {-0.865398771818852, -0.908187047234418, 1.55954554826208, 0.483242727153488, -1.55954554826208, -0.483242727153488, 1.77358581905327},
+    {-0.118011263129872, -0.944972669198744, 2.53733389052355, 0.289627515545325, -2.53733389052355, -0.289627515545325, 1.06298393232862},
+    {0.544604017438855, -0.977585891838153, 3.40421685178807, 0.117973057488943, -3.40421685178807, -0.117973057488943, 0.432981874399299},
+    {-1.06855188405066, -0.898188066116116, 0.13831575967286, 1.6913204223926, -0.13831575967286, -1.6913204223926, 1.96673995016677},
+    {-0.77093592668034, -0.912836408470111, 0.693921283086782, 1.44797919870299, -0.693921283086782, -1.44797919870299, 1.68377233515045},
+    {-0.307255161197394, -0.935658284876776, 1.55954554826208, 1.0688575754173, -1.55954554826208, -1.0688575754173, 1.24291344607417},
+    {0.216507474925436, -0.961437327351342, 2.53733389052355, 0.640610911753231, -2.53733389052355, -0.640610911753231, 0.744929852425906},
+    {0.680862474241284, -0.984292388833493, 3.40421685178807, 0.260938011286712, -3.40421685178807, -0.260938011286712, 0.303429914592209},
+    {-0.120853589128906, -0.944832772922068, 0.138315759672859, 2.6856634241203, -0.138315759672859, -2.6856634241203, 1.06568636205097},
+    {0.0404108764001512, -0.952770039194603, 0.693921283086782, 2.29925963250797, -0.693921283086782, -2.29925963250797, 0.912359162794452},
+    {0.291658260721922, -0.965136169470715, 1.55954554826208, 1.69724888193056, -1.55954554826208, -1.69724888193056, 0.673477908748793},
+    {0.575461260818929, -0.979104652690649, 2.53733389052355, 1.01723202298603, -2.53733389052355, -1.01723202298603, 0.40364339187172},
+    {0.827073981595321, -0.991488764440298, 3.40421685178807, 0.414345894247555, -3.40421685178807, -0.414345894247555, 0.164414782844977},
+    {0.637338430571105, -0.982150181480284, 0.138315759672859, 3.48117285237853, -0.138315759672859, -3.48117285237853, 0.344811750909179},
+    {0.689516899489005, -0.984718350482277, 0.693921283086783, 2.9803139668845, -0.693921283086783, -2.9803139668845, 0.295201450993271},
+    {0.770810095671615, -0.988719515538262, 1.55954554826208, 2.1999840629478, -1.55954554826208, -2.1999840629478, 0.217909419866647},
+    {0.862636934093749, -0.993239135313953, 2.53733389052355, 1.31854217888416, -2.53733389052355, -1.31854217888416, 0.130602201220204},
+    {0.94404833794709, -0.997246118426351, 3.40421685178807, 0.537077604585377, -3.40421685178807, -0.537077604585377, 0.053197780479261},
+    {-1.85228451823978, -0.144333375497977, 0.138315759672862, 0.153733097585335, -0.138315759672862, -0.153733097585335, 1.99661789373776},
+    {-1.44190787062765, -0.267443674835656, 0.693921283086783, 0.131614521121219, -0.693921283086783, -0.131614521121219, 1.70935154546331},
+    {-0.802547804781613, -0.459247495907997, 1.55954554826208, 0.0971541428643072, -1.55954554826208, -0.0971541428643073, 1.26179530068961},
+    {-0.0803420579669868, -0.675904477222819, 2.53733389052355, 0.0582285287322851, -2.53733389052355, -0.0582285287322851, 0.756246535189806},
+    {0.559947695327596, -0.86798719842446, 3.40421685178806, 0.0237180419639908, -3.40421685178806, -0.0237180419639908, 0.308039503096864},
+    {-1.38233429996559, -0.285315354814272, 0.138315759672861, 0.764665295175825, -0.138315759672861, -0.764665295175825, 1.66764965477986},
+    {-1.03957243407901, -0.388141663660972, 0.693921283086783, 0.654647946495179, -0.693921283086783, -0.654647946495179, 1.42771409773998},
+    {-0.505555085826084, -0.54834336124165, 1.55954554826208, 0.483242727153488, -1.55954554826208, -0.483242727153488, 1.05389844706773},
+    {0.0976580618337188, -0.729303344235153, 2.53733389052355, 0.289627515545325, -2.53733389052355, -0.289627515545325, 0.631645282401435},
+    {0.632451919681933, -0.889737989595075, 3.40421685178807, 0.117973057488944, -3.40421685178807, -0.117973057488944, 0.257286069913143},
+    {-0.669519062828044, -0.499155244893504, 0.13831575967286, 1.6913204223926, -0.13831575967286, -1.6913204223926, 1.16867430772155},
+    {-0.429314541944297, -0.571215023734068, 0.693921283086782, 1.44797919870299, -0.693921283086782, -1.44797919870299, 1.00052956567836},
+    {-0.0550798500280449, -0.683482973707428, 1.55954554826208, 1.0688575754173, -1.55954554826208, -1.06885757541731, 0.738562823735472},
+    {0.367646653544982, -0.810298148731796, 2.53733389052355, 0.640610911753231, -2.53733389052355, -0.640610911753232, 0.442651495186814},
+    {0.742425516601204, -0.922729346473572, 3.40421685178807, 0.260938011286712, -3.40421685178807, -0.260938011286712, 0.180303829872368},
+    {0.0953640331101717, -0.72861515068299, 0.138315759672859, 2.6856634241203, -0.138315759672859, -2.6856634241203, 0.633251117572818},
+    {0.225519868906913, -0.767661046687841, 0.693921283086782, 2.29925963250797, -0.693921283086782, -2.29925963250797, 0.542141177780928},
+    {0.428300519875883, -0.828493910316755, 1.55954554826208, 1.69724888193056, -1.55954554826208, -1.69724888193056, 0.400193390440872},
+    {0.657356664129763, -0.897209249379815, 2.53733389052355, 1.01723202298603, -2.53733389052355, -1.01723202298603, 0.239852585250053},
+    {0.860432176532975, -0.958130569502645, 3.40421685178807, 0.414345894247555, -3.40421685178807, -0.414345894247555, 0.09769839296967},
+    {0.707297453747673, -0.912191158303717, 0.13831575967286, 3.48117285237853, -0.13831575967286, -3.48117285237853, 0.204893704556044},
+    {0.749410464883284, -0.924824785087998, 0.693921283086783, 2.9803139668845, -0.693921283086783, -2.9803139668845, 0.175414320204715},
+    {0.815021843428606, -0.944507767781271, 1.55954554826208, 2.1999840629478, -1.55954554826208, -2.1999840629478, 0.129485924352665},
+    {0.889134877965973, -0.966741191441729, 2.53733389052355, 1.31854217888416, -2.53733389052355, -1.31854217888416, 0.0776063134757553},
+    {0.954841661398734, -0.986452794974707, 3.40421685178807, 0.537077604585377, -3.40421685178807, -0.537077604585377, 0.0316111335759726},
+    {-0.853975571370903, 0.853975571370903, 0.138315759672861, 0.153733097585334, -0.138315759672861, -0.153733097585334, 0},
+    {-0.587232097895999, 0.587232097895999, 0.693921283086783, 0.131614521121219, -0.693921283086783, -0.131614521121219, 0},
+    {-0.171650154436808, 0.171650154436808, 1.55954554826208, 0.0971541428643074, -1.55954554826208, -0.0971541428643074, 0},
+    {0.297781209627916, -0.297781209627916, 2.53733389052355, 0.0582285287322856, -2.53733389052355, -0.0582285287322856, 0},
+    {0.713967446876028, -0.713967446876028, 3.40421685178807, 0.0237180419639911, -3.40421685178807, -0.0237180419639911, 0},
+    {-0.548509472575657, 0.548509472575658, 0.13831575967286, 0.764665295175825, -0.13831575967286, -0.764665295175825, 0},
+    {-0.325715385209019, 0.325715385209019, 0.693921283086783, 0.654647946495179, -0.693921283086783, -0.654647946495179, 0},
+    {0.0213941377077832, -0.0213941377077827, 1.55954554826208, 0.483242727153488, -1.55954554826208, -0.483242727153489, 0},
+    {0.413480703034436, -0.413480703034436, 2.53733389052355, 0.289627515545326, -2.53733389052355, -0.289627515545326, 0},
+    {0.761094954638504, -0.761094954638504, 3.40421685178807, 0.117973057488944, -3.40421685178807, -0.117973057488944, 0},
+    {-0.0851819089672702, 0.0851819089672698, 0.13831575967286, 1.6913204223926, -0.13831575967286, -1.6913204223926, 0},
+    {0.0709502408948851, -0.0709502408948855, 0.693921283086783, 1.44797919870299, -0.693921283086783, -1.44797919870299, 0},
+    {0.314201561839691, -0.314201561839691, 1.55954554826208, 1.06885757541731, -1.55954554826208, -1.06885757541731, 0},
+    {0.588972401138389, -0.58897240113839, 2.53733389052355, 0.640610911753232, -2.53733389052355, -0.640610911753232, 0},
+    {0.832577431537388, -0.832577431537389, 3.40421685178807, 0.260938011286713, -3.40421685178807, -0.260938011286713, 0},
+    {0.411989591896581, -0.411989591896581, 0.13831575967286, 2.6856634241203, -0.13831575967286, -2.6856634241203, 0},
+    {0.496590457797377, -0.496590457797378, 0.693921283086783, 2.29925963250797, -0.693921283086783, -2.29925963250797, 0},
+    {0.628397215096318, -0.62839721509632, 1.55954554826208, 1.69724888193056, -1.55954554826208, -1.69724888193056, 0},
+    {0.777282956754789, -0.777282956754789, 2.53733389052355, 1.01723202298603, -2.53733389052355, -1.01723202298603, 0},
+    {0.909281373017809, -0.90928137301781, 3.40421685178807, 0.414345894247555, -3.40421685178807, -0.414345894247555, 0},
+    {0.809744306025695, -0.809744306025695, 0.13831575967286, 3.48117285237853, -0.13831575967286, -3.48117285237853, 0},
+    {0.837117624985641, -0.837117624985642, 0.693921283086783, 2.9803139668845, -0.693921283086783, -2.9803139668845, 0},
+    {0.879764805604937, -0.879764805604939, 1.55954554826208, 2.1999840629478, -1.55954554826208, -2.1999840629478, 0},
+    {0.92793803470385, -0.927938034703852, 2.53733389052355, 1.31854217888416, -2.53733389052355, -1.31854217888416, 0},
+    {0.97064722818672, -0.970647228186721, 3.40421685178807, 0.537077604585377, -3.40421685178807, -0.537077604585377, 0},
+    {0.144333375497977, 1.85228451823978, 0.13831575967286, 0.153733097585332, -0.13831575967286, -0.153733097585332, -1.99661789373776},
+    {0.267443674835656, 1.44190787062765, 0.693921283086782, 0.131614521121218, -0.693921283086782, -0.131614521121218, -1.70935154546331},
+    {0.459247495907997, 0.802547804781612, 1.55954554826208, 0.0971541428643074, -1.55954554826208, -0.0971541428643075, -1.26179530068961},
+    {0.675904477222819, 0.0803420579669871, 2.53733389052355, 0.058228528732286, -2.53733389052355, -0.058228528732286, -0.756246535189806},
+    {0.86798719842446, -0.559947695327595, 3.40421685178807, 0.0237180419639914, -3.40421685178807, -0.0237180419639914, -0.308039503096864},
+    {0.285315354814272, 1.38233429996559, 0.13831575967286, 0.764665295175824, -0.13831575967286, -0.764665295175825, -1.66764965477986},
+    {0.388141663660971, 1.03957243407901, 0.693921283086782, 0.654647946495179, -0.693921283086782, -0.654647946495179, -1.42771409773998},
+    {0.54834336124165, 0.505555085826084, 1.55954554826208, 0.483242727153489, -1.55954554826208, -0.483242727153489, -1.05389844706773},
+    {0.729303344235153, -0.0976580618337189, 2.53733389052355, 0.289627515545326, -2.53733389052355, -0.289627515545326, -0.631645282401434},
+    {0.889737989595075, -0.632451919681933, 3.40421685178807, 0.117973057488944, -3.40421685178807, -0.117973057488944, -0.257286069913142},
+    {0.499155244893504, 0.669519062828043, 0.13831575967286, 1.6913204223926, -0.13831575967286, -1.6913204223926, -1.16867430772155},
+    {0.571215023734067, 0.429314541944296, 0.693921283086783, 1.44797919870299, -0.693921283086783, -1.44797919870299, -1.00052956567836},
+    {0.683482973707427, 0.0550798500280444, 1.55954554826208, 1.06885757541731, -1.55954554826208, -1.06885757541731, -0.738562823735472},
+    {0.810298148731796, -0.367646653544983, 2.53733389052355, 0.640610911753232, -2.53733389052355, -0.640610911753233, -0.442651495186813},
+    {0.922729346473572, -0.742425516601205, 3.40421685178807, 0.260938011286713, -3.40421685178807, -0.260938011286713, -0.180303829872367},
+    {0.72861515068299, -0.0953640331101723, 0.13831575967286, 2.6856634241203, -0.13831575967286, -2.6856634241203, -0.633251117572818},
+    {0.767661046687841, -0.225519868906914, 0.693921283086783, 2.29925963250797, -0.693921283086783, -2.29925963250797, -0.542141177780927},
+    {0.828493910316754, -0.428300519875884, 1.55954554826208, 1.69724888193056, -1.55954554826208, -1.69724888193056, -0.40019339044087},
+    {0.897209249379815, -0.657356664129763, 2.53733389052355, 1.01723202298603, -2.53733389052355, -1.01723202298603, -0.239852585250051},
+    {0.958130569502644, -0.860432176532975, 3.40421685178807, 0.414345894247555, -3.40421685178807, -0.414345894247555, -0.0976983929696684},
+    {0.912191158303717, -0.707297453747673, 0.13831575967286, 3.48117285237853, -0.13831575967286, -3.48117285237853, -0.204893704556044},
+    {0.924824785087998, -0.749410464883284, 0.693921283086783, 2.9803139668845, -0.693921283086783, -2.9803139668845, -0.175414320204713},
+    {0.944507767781269, -0.815021843428607, 1.55954554826208, 2.1999840629478, -1.55954554826208, -2.1999840629478, -0.129485924352662},
+    {0.966741191441727, -0.889134877965975, 2.53733389052355, 1.31854217888416, -2.53733389052355, -1.31854217888416, -0.0776063134757528},
+    {0.986452794974706, -0.954841661398735, 3.40421685178807, 0.537077604585377, -3.40421685178807, -0.537077604585377, -0.0316111335759707},
+    {0.826059726268029, 2.53401086900983, 0.138315759672859, 0.153733097585331, -0.138315759672859, -0.153733097585331, -3.36007059527786},
+    {0.851085640044301, 2.0255498358363, 0.693921283086782, 0.131614521121217, -0.693921283086782, -0.131614521121218, -2.8766354758806},
+    {0.89007560200475, 1.23337591087837, 1.55954554826208, 0.0971541428643073, -1.55954554826208, -0.0971541428643074, -2.12345151288312},
+    {0.934117724902526, 0.338555305646693, 2.53733389052355, 0.0582285287322862, -2.53733389052355, -0.0582285287322862, -1.27267303054922},
+    {0.973164381799351, -0.454770511952705, 3.40421685178807, 0.0237180419639916, -3.40421685178807, -0.0237180419639916, -0.518393869846646},
+    {0.854718602717514, 1.95173754786883, 0.138315759672859, 0.764665295175824, -0.138315759672859, -0.764665295175824, -2.80645615058634},
+    {0.875621178318206, 1.52705194873624, 0.693921283086782, 0.654647946495179, -0.693921283086782, -0.654647946495179, -2.40267312705445},
+    {0.908187047234417, 0.865398771818851, 1.55954554826208, 0.483242727153489, -1.55954554826208, -0.483242727153489, -1.77358581905327},
+    {0.944972669198744, 0.118011263129871, 2.53733389052355, 0.289627515545326, -2.53733389052355, -0.289627515545326, -1.06298393232862},
+    {0.977585891838153, -0.544604017438855, 3.40421685178807, 0.117973057488944, -3.40421685178807, -0.117973057488944, -0.432981874399298},
+    {0.898188066116116, 1.06855188405065, 0.13831575967286, 1.6913204223926, -0.13831575967286, -1.6913204223926, -1.96673995016677},
+    {0.91283640847011, 0.77093592668034, 0.693921283086783, 1.44797919870299, -0.693921283086783, -1.44797919870299, -1.68377233515045},
+    {0.935658284876776, 0.307255161197392, 1.55954554826208, 1.06885757541731, -1.55954554826208, -1.06885757541731, -1.24291344607417},
+    {0.961437327351342, -0.216507474925437, 2.53733389052355, 0.640610911753233, -2.53733389052355, -0.640610911753233, -0.744929852425905},
+    {0.984292388833492, -0.680862474241285, 3.40421685178807, 0.260938011286713, -3.40421685178807, -0.260938011286713, -0.303429914592208},
+    {0.944832772922068, 0.120853589128905, 0.13831575967286, 2.6856634241203, -0.13831575967286, -2.6856634241203, -1.06568636205097},
+    {0.952770039194603, -0.0404108764001523, 0.693921283086783, 2.29925963250797, -0.693921283086783, -2.29925963250797, -0.912359162794451},
+    {0.965136169470714, -0.291658260721924, 1.55954554826208, 1.69724888193056, -1.55954554826208, -1.69724888193056, -0.673477908748791},
+    {0.979104652690648, -0.57546126081893, 2.53733389052355, 1.01723202298603, -2.53733389052355, -1.01723202298603, -0.403643391871719},
+    {0.991488764440297, -0.827073981595322, 3.40421685178807, 0.414345894247555, -3.40421685178807, -0.414345894247555, -0.164414782844975},
+    {0.982150181480284, -0.637338430571106, 0.13831575967286, 3.48117285237853, -0.13831575967286, -3.48117285237853, -0.344811750909179},
+    {0.984718350482276, -0.689516899489006, 0.693921283086783, 2.9803139668845, -0.693921283086783, -2.9803139668845, -0.29520145099327},
+    {0.98871951553826, -0.770810095671616, 1.55954554826208, 2.1999840629478, -1.55954554826208, -2.1999840629478, -0.217909419866644},
+    {0.993239135313952, -0.86263693409375, 2.53733389052355, 1.31854217888416, -2.53733389052355, -1.31854217888416, -0.130602201220202},
+    {0.99724611842635, -0.944048337947091, 3.40421685178807, 0.537077604585377, -3.40421685178807, -0.537077604585377, -0.0531977804792586}};
+    
+    // Array of non-zero columns
+    static const unsigned int nzc3[7] = {0, 1, 5, 6, 7, 8, 9};
+    
+    // Number of operations to compute geometry constants: 88
+    const double G0 = det*(Jinv_10*Jinv_20 + Jinv_11*Jinv_21 + Jinv_12*Jinv_22);
+    const double G1 = -3*Jinv_22*det;
+    const double G2 = 3*det*(Jinv_20*Jinv_20 + Jinv_21*Jinv_21 + Jinv_22*Jinv_22);
+    const double G3 = 3*det*(Jinv_00*Jinv_20 + Jinv_01*Jinv_21 + Jinv_02*Jinv_22);
+    const double G4 = 3*det*(Jinv_10*Jinv_20 + Jinv_11*Jinv_21 + Jinv_12*Jinv_22);
+    const double G5 = det*(Jinv_00*Jinv_00 + Jinv_01*Jinv_01 + Jinv_02*Jinv_02);
+    const double G6 = det*w[2][0];
+    const double G7 = -3*Jinv_02*det;
+    const double G8 = 3*det*(Jinv_00*Jinv_00 + Jinv_01*Jinv_01 + Jinv_02*Jinv_02);
+    const double G9 = 3*det*(Jinv_00*Jinv_10 + Jinv_01*Jinv_11 + Jinv_02*Jinv_12);
+    const double G10 = det*(Jinv_00*Jinv_10 + Jinv_01*Jinv_11 + Jinv_02*Jinv_12);
+    const double G11 = -3*Jinv_12*det;
+    const double G12 = 3*det*(Jinv_10*Jinv_10 + Jinv_11*Jinv_11 + Jinv_12*Jinv_12);
+    const double G13 = det*(Jinv_10*Jinv_10 + Jinv_11*Jinv_11 + Jinv_12*Jinv_12);
+    const double G14 = det*(Jinv_20*Jinv_20 + Jinv_21*Jinv_21 + Jinv_22*Jinv_22);
+    const double G15 = det*(Jinv_00*Jinv_20 + Jinv_01*Jinv_21 + Jinv_02*Jinv_22);
+    const double G16 = -0.5*det*w[1][0]*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: 371213
+    
+    // Loop quadrature points for integral
+    // Number of operations to compute element tensor for following IP loop = 371125
+    for (unsigned int ip = 0; ip < 125; ip++)
+    {
+      
+      // Function declarations
+      double F0 = 0;
+      double F1 = 0;
+      double F2 = 0;
+      double F3 = 0;
+      
+      // Total number of operations to compute function values = 20
+      for (unsigned int r = 0; r < 10; r++)
+      {
+        F0 += FE1_C0[ip][r]*w[0][nzc4[r]];
+      }// end loop over 'r'
+      
+      // Total number of operations to compute function values = 42
+      for (unsigned int r = 0; r < 7; r++)
+      {
+        F1 += FE1_C0_D100[ip][r]*w[0][nzc3[r]];
+        F2 += FE1_C0_D010[ip][r]*w[0][nzc2[r]];
+        F3 += FE1_C0_D001[ip][r]*w[0][nzc1[r]];
+      }// end loop over 'r'
+      
+      // Number of operations to compute ip constants: 54
+      // Number of operations: 4
+      const double Gip0 = F0*F0*F0*G0*W125[ip];
+      
+      // Number of operations: 1
+      const double Gip1 = W125[ip]*det;
+      
+      // Number of operations: 9
+      const double Gip2 = F0*F0*W125[ip]*(G1 + F1*G3 + F2*G4 + F3*G2);
+      
+      // Number of operations: 4
+      const double Gip3 = F0*F0*F0*G5*W125[ip];
+      
+      // Number of operations: 1
+      const double Gip4 = G6*W125[ip];
+      
+      // Number of operations: 9
+      const double Gip5 = F0*F0*W125[ip]*(G7 + F1*G8 + F2*G9 + F3*G3);
+      
+      // Number of operations: 4
+      const double Gip6 = F0*F0*F0*G10*W125[ip];
+      
+      // Number of operations: 9
+      const double Gip7 = F0*F0*W125[ip]*(G11 + F1*G9 + F2*G12 + F3*G4);
+      
+      // Number of operations: 4
+      const double Gip8 = F0*F0*F0*G13*W125[ip];
+      
+      // Number of operations: 4
+      const double Gip9 = F0*F0*F0*G14*W125[ip];
+      
+      // Number of operations: 4
+      const double Gip10 = F0*F0*F0*G15*W125[ip];
+      
+      // Number of operations: 1
+      const double Gip11 = G16*W125[ip];
+      
+      
+      // Number of operations for primary indices: 1323
+      for (unsigned int j = 0; j < 7; j++)
+      {
+        for (unsigned int k = 0; k < 7; k++)
+        {
+          // Number of operations to compute entry: 3
+          A[nzc2[j]*20 + nzc1[k]] += FE1_C0_D001[ip][k]*FE1_C0_D010[ip][j]*Gip0;
+          // Number of operations to compute entry: 3
+          A[nzc3[j]*20 + nzc3[k]] += FE1_C0_D100[ip][j]*FE1_C0_D100[ip][k]*Gip3;
+          // Number of operations to compute entry: 3
+          A[nzc2[j]*20 + nzc3[k]] += FE1_C0_D010[ip][j]*FE1_C0_D100[ip][k]*Gip6;
+          // Number of operations to compute entry: 3
+          A[nzc3[j]*20 + nzc2[k]] += FE1_C0_D010[ip][k]*FE1_C0_D100[ip][j]*Gip6;
+          // Number of operations to compute entry: 3
+          A[nzc1[j]*20 + nzc2[k]] += FE1_C0_D001[ip][j]*FE1_C0_D010[ip][k]*Gip0;
+          // Number of operations to compute entry: 3
+          A[nzc2[j]*20 + nzc2[k]] += FE1_C0_D010[ip][j]*FE1_C0_D010[ip][k]*Gip8;
+          // Number of operations to compute entry: 3
+          A[nzc1[j]*20 + nzc1[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*Gip9;
+          // Number of operations to compute entry: 3
+          A[nzc3[j]*20 + nzc1[k]] += FE1_C0_D001[ip][k]*FE1_C0_D100[ip][j]*Gip10;
+          // Number of operations to compute entry: 3
+          A[nzc1[j]*20 + nzc3[k]] += FE1_C0_D001[ip][j]*FE1_C0_D100[ip][k]*Gip10;
+        }// end loop over 'k'
+      }// end loop over 'j'
+      
+      // Number of operations for primary indices: 900
+      for (unsigned int j = 0; j < 10; j++)
+      {
+        for (unsigned int k = 0; k < 10; k++)
+        {
+          // Number of operations to compute entry: 3
+          A[nzc4[j]*20 + nzc4[k]] += FE1_C0[ip][j]*FE1_C0[ip][k]*Gip1;
+          // Number of operations to compute entry: 3
+          A[nzc0[j]*20 + nzc0[k]] += FE1_C0[ip][j]*FE1_C0[ip][k]*Gip4;
+          // Number of operations to compute entry: 3
+          A[nzc4[j]*20 + nzc0[k]] += FE1_C0[ip][j]*FE1_C0[ip][k]*Gip11;
+        }// end loop over 'k'
+      }// end loop over 'j'
+      
+      // Number of operations for primary indices: 630
+      for (unsigned int j = 0; j < 7; j++)
+      {
+        for (unsigned int k = 0; k < 10; k++)
+        {
+          // Number of operations to compute entry: 3
+          A[nzc1[j]*20 + nzc4[k]] += FE1_C0[ip][k]*FE1_C0_D001[ip][j]*Gip2;
+          // Number of operations to compute entry: 3
+          A[nzc3[j]*20 + nzc4[k]] += FE1_C0[ip][k]*FE1_C0_D100[ip][j]*Gip5;
+          // Number of operations to compute entry: 3
+          A[nzc2[j]*20 + nzc4[k]] += FE1_C0[ip][k]*FE1_C0_D010[ip][j]*Gip7;
+        }// end loop over 'k'
+      }// end loop over 'j'
+    }// end loop over 'ip'
+}
+
+/// Constructor
+solitarywave3d_0_cell_integral_0::solitarywave3d_0_cell_integral_0() : ufc::cell_integral()
+{
+    // Do nothing
+}
+
+/// Destructor
+solitarywave3d_0_cell_integral_0::~solitarywave3d_0_cell_integral_0()
+{
+    // Do nothing
+}
+
+/// Tabulate the tensor for the contribution from a local cell
+void solitarywave3d_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 < 400; j++)
+      A[j] = 0;
+    
+    // Add all contributions to element tensor
+    integral_0_quadrature.tabulate_tensor(A, w, c);
+}
+
+/// Constructor
+solitarywave3d_0_exterior_facet_integral_0_quadrature::solitarywave3d_0_exterior_facet_integral_0_quadrature() : ufc::exterior_facet_integral()
+{
+    // Do nothing
+}
+
+/// Destructor
+solitarywave3d_0_exterior_facet_integral_0_quadrature::~solitarywave3d_0_exterior_facet_integral_0_quadrature()
+{
+    // Do nothing
+}
+
+/// Tabulate the tensor for the contribution from a local exterior facet
+void solitarywave3d_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
+    
+    // Compute sub determinants
+    
+    
+    
+    // Compute determinant of Jacobian
+    
+    // Compute inverse of Jacobian
+    
+    // Vertices on faces
+    static unsigned int face_vertices[4][3] = {{1, 2, 3}, {0, 2, 3}, {0, 1, 3}, {0, 1, 2}};
+    
+    // Get vertices
+    const unsigned int v0 = face_vertices[facet][0];
+    const unsigned int v1 = face_vertices[facet][1];
+    const unsigned int v2 = face_vertices[facet][2];
+    
+    // Compute scale factor (area of face scaled by area of reference triangle)
+    const double a0 = (x[v0][1]*x[v1][2] + x[v0][2]*x[v2][1] + x[v1][1]*x[v2][2])
+                  - (x[v2][1]*x[v1][2] + x[v2][2]*x[v0][1] + x[v1][1]*x[v0][2]);
+    const double a1 = (x[v0][2]*x[v1][0] + x[v0][0]*x[v2][2] + x[v1][2]*x[v2][0])
+                  - (x[v2][2]*x[v1][0] + x[v2][0]*x[v0][2] + x[v1][2]*x[v0][0]);
+    const double a2 = (x[v0][0]*x[v1][1] + x[v0][1]*x[v2][0] + x[v1][0]*x[v2][1])
+                  - (x[v2][0]*x[v1][1] + x[v2][1]*x[v0][0] + x[v1][0]*x[v0][1]);
+    const double det = std::sqrt(a0*a0 + a1*a1 + a2*a2);
+    
+    const bool direction = a0*(x[facet][0] - x[v0][0]) + a1*(x[facet][1] - x[v0][1])  + a2*(x[facet][2] - x[v0][2]) < 0;
+    // Compute facet normals from the facet scale factor constants
+    const double n2 = direction ? a2 / det : -a2 / det;
+    
+    
+    // Array of quadrature weights
+    static const double W25[25] = {0.0114650803515925, 0.0198040831320473, 0.0173415064313656, 0.0087554991821638, 0.00186555216687783, 0.0231612219294983, 0.0400072873861603, 0.0350325045033716, 0.0176874521104834, 0.0037687016953276, 0.0275289856644697, 0.0475518970579538, 0.0416389652151948, 0.021022967487322, 0.00447940679728133, 0.0231612219294983, 0.0400072873861603, 0.0350325045033716, 0.0176874521104834, 0.0037687016953276, 0.0114650803515925, 0.0198040831320473, 0.0173415064313656, 0.0087554991821638, 0.00186555216687783};
+    // Quadrature points on the UFC reference element: (0.0450425935698037, 0.0398098570514687), (0.0376212523451112, 0.198013417873608), (0.0263646449444709, 0.437974810247386), (0.0142857943955714, 0.695464273353636), (0.00462228846504642, 0.901464914201174), (0.221578609552379, 0.0398098570514687), (0.185070710267389, 0.198013417873608), (0.129695936782254, 0.437974810247386), (0.0702762920082817, 0.695464273353636), (0.022738483063764, 0.901464914201174), (0.480095071474266, 0.0398098570514687), (0.400993291063196, 0.198013417873608), (0.281012594876307, 0.437974810247386), (0.152267863323182, 0.695464273353636), (0.0492675428994132, 0.901464914201174), (0.738611533396152, 0.0398098570514687), (0.616915871859002, 0.198013417873608), (0.43232925297036, 0.437974810247386), (0.234259434638082, 0.695464273353636), (0.0757966027350624, 0.901464914201174), (0.915147549378728, 0.0398098570514687), (0.764365329781281, 0.198013417873608), (0.535660544808143, 0.437974810247386), (0.290249932250792, 0.695464273353636), (0.09391279733378, 0.901464914201174)
+    
+    // Value of basis functions at quadrature points.
+    static const double FE0_f0_C0[25][6] = \
+    {{0.759842524889053, -0.0409849230988147, -0.036640207614552, 0.00717255684496518, 0.145727572487076, 0.164882476492272},
+    {0.404143384962011, -0.0347905350890821, -0.119594790557632, 0.0297980510461638, 0.605418365816316, 0.115025523822223},
+    {0.0382038937201701, -0.0249744559383749, -0.0543309414249183, 0.0461882014671774, 0.938423301877432, 0.0564900002985142},
+    {-0.121759885907613, -0.0138776265525463, 0.271876837668966, 0.0397410384743819, 0.807433832894958, 0.0165858034218534},
+    {-0.0762735703276686, -0.00457955736373825, 0.723813068870285, 0.0166673234982245, 0.338636367163553, 0.00173636815934473},
+    {0.352482461135478, -0.123384449130048, -0.036640207614552, 0.0352840510877737, 0.117616078244268, 0.65464206627708},
+    {0.144254514044104, -0.116568374669637, -0.119594790557632, 0.146585935553368, 0.488630481309112, 0.456692234320685},
+    {-0.0585120870225411, -0.0960538647466012, -0.0543309414249183, 0.227214213208259, 0.75739729013635, 0.224285389849452},
+    {-0.124504469204174, -0.0603987775714152, 0.271876837668966, 0.19549860142211, 0.65167626994723, 0.0658515377372834},
+    {-0.0643063527627086, -0.0217044058396819, 0.723813068870285, 0.0819917787365634, 0.273311911925214, 0.00689399907032827},
+    {-0.0191125161665051, -0.0191125161665051, -0.036640207614552, 0.0764500646660208, 0.0764500646660208, 0.921965110615521},
+    {-0.0794020521078099, -0.07940205210781, -0.119594790557632, 0.31760820843124, 0.31760820843124, 0.643182477910772},
+    {-0.123076437918076, -0.123076437918076, -0.0543309414249183, 0.492305751672305, 0.492305751672305, 0.315872313916461},
+    {-0.105896858921167, -0.105896858921168, 0.271876837668966, 0.42358743568467, 0.42358743568467, 0.0927420088040289},
+    {-0.0444129613327221, -0.0444129613327222, 0.723813068870285, 0.177651845330889, 0.177651845330888, 0.0097091631333821},
+    {-0.123384449130048, 0.352482461135478, -0.036640207614552, 0.117616078244268, 0.0352840510877739, 0.65464206627708},
+    {-0.116568374669637, 0.144254514044103, -0.119594790557632, 0.488630481309112, 0.146585935553368, 0.456692234320685},
+    {-0.0960538647466012, -0.0585120870225412, -0.0543309414249184, 0.75739729013635, 0.227214213208259, 0.224285389849452},
+    {-0.0603987775714152, -0.124504469204174, 0.271876837668966, 0.65167626994723, 0.195498601422111, 0.0658515377372834},
+    {-0.0217044058396818, -0.0643063527627087, 0.723813068870285, 0.273311911925214, 0.0819917787365635, 0.00689399907032831},
+    {-0.0409849230988147, 0.759842524889053, -0.036640207614552, 0.145727572487076, 0.0071725568449653, 0.164882476492272},
+    {-0.0347905350890821, 0.404143384962011, -0.119594790557632, 0.605418365816316, 0.029798051046164, 0.115025523822223},
+    {-0.024974455938375, 0.0382038937201699, -0.0543309414249184, 0.938423301877431, 0.0461882014671778, 0.0564900002985144},
+    {-0.0138776265525463, -0.121759885907613, 0.271876837668966, 0.807433832894958, 0.0397410384743823, 0.0165858034218534},
+    {-0.00457955736373818, -0.0762735703276687, 0.723813068870285, 0.338636367163553, 0.0166673234982247, 0.00173636815934472}};
+    
+    // Array of non-zero columns
+    static const unsigned int nzc1[6] = {11, 12, 13, 14, 15, 16};
+    // Array of non-zero columns
+    static const unsigned int nzc0[6] = {1, 2, 3, 4, 5, 6};
+    // Array of non-zero columns
+    static const unsigned int nzc5[6] = {10, 11, 13, 15, 17, 19};
+    // Array of non-zero columns
+    static const unsigned int nzc4[6] = {0, 1, 3, 5, 7, 9};
+    // Array of non-zero columns
+    static const unsigned int nzc2[6] = {0, 2, 3, 4, 7, 8};
+    // Array of non-zero columns
+    static const unsigned int nzc3[6] = {10, 12, 13, 14, 17, 18};
+    // Array of non-zero columns
+    static const unsigned int nzc6[6] = {0, 1, 2, 6, 8, 9};
+    // Array of non-zero columns
+    static const unsigned int nzc7[6] = {10, 11, 12, 16, 18, 19};
+    
+    // Number of operations to compute geometry constants: 2
+    // Should be added to total operation count.
+    const double G0 = 3*det*n2;
+    
+    // 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): 3075
+      
+      // Loop quadrature points for integral
+      // Number of operations to compute element tensor for following IP loop = 3075
+      for (unsigned int ip = 0; ip < 25; ip++)
+      {
+        
+        // Function declarations
+        double F0 = 0;
+        
+        // Total number of operations to compute function values = 12
+        for (unsigned int r = 0; r < 6; r++)
+        {
+          F0 += FE0_f0_C0[ip][r]*w[0][nzc1[r]];
+        }// end loop over 'r'
+        
+        // Number of operations to compute ip constants: 3
+        // Number of operations: 3
+        const double Gip0 = F0*F0*G0*W25[ip];
+        
+        
+        // Number of operations for primary indices: 108
+        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]*20 + nzc1[k]] += FE0_f0_C0[ip][j]*FE0_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): 3075
+      
+      // Loop quadrature points for integral
+      // Number of operations to compute element tensor for following IP loop = 3075
+      for (unsigned int ip = 0; ip < 25; ip++)
+      {
+        
+        // Function declarations
+        double F0 = 0;
+        
+        // Total number of operations to compute function values = 12
+        for (unsigned int r = 0; r < 6; r++)
+        {
+          F0 += FE0_f0_C0[ip][r]*w[0][nzc3[r]];
+        }// end loop over 'r'
+        
+        // Number of operations to compute ip constants: 3
+        // Number of operations: 3
+        const double Gip0 = F0*F0*G0*W25[ip];
+        
+        
+        // Number of operations for primary indices: 108
+        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]*20 + nzc3[k]] += FE0_f0_C0[ip][j]*FE0_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): 3075
+      
+      // Loop quadrature points for integral
+      // Number of operations to compute element tensor for following IP loop = 3075
+      for (unsigned int ip = 0; ip < 25; ip++)
+      {
+        
+        // Function declarations
+        double F0 = 0;
+        
+        // Total number of operations to compute function values = 12
+        for (unsigned int r = 0; r < 6; r++)
+        {
+          F0 += FE0_f0_C0[ip][r]*w[0][nzc5[r]];
+        }// end loop over 'r'
+        
+        // Number of operations to compute ip constants: 3
+        // Number of operations: 3
+        const double Gip0 = F0*F0*G0*W25[ip];
+        
+        
+        // Number of operations for primary indices: 108
+        for (unsigned int j = 0; j < 6; j++)
+        {
+          for (unsigned int k = 0; k < 6; k++)
+          {
+            // Number of operations to compute entry: 3
+            A[nzc4[j]*20 + nzc5[k]] += FE0_f0_C0[ip][j]*FE0_f0_C0[ip][k]*Gip0;
+          }// end loop over 'k'
+        }// end loop over 'j'
+      }// end loop over 'ip'
+      }
+      break;
+    case 3:
+      {
+      // Total number of operations to compute element tensor (from this point): 3075
+      
+      // Loop quadrature points for integral
+      // Number of operations to compute element tensor for following IP loop = 3075
+      for (unsigned int ip = 0; ip < 25; ip++)
+      {
+        
+        // Function declarations
+        double F0 = 0;
+        
+        // Total number of operations to compute function values = 12
+        for (unsigned int r = 0; r < 6; r++)
+        {
+          F0 += FE0_f0_C0[ip][r]*w[0][nzc7[r]];
+        }// end loop over 'r'
+        
+        // Number of operations to compute ip constants: 3
+        // Number of operations: 3
+        const double Gip0 = F0*F0*G0*W25[ip];
+        
+        
+        // Number of operations for primary indices: 108
+        for (unsigned int j = 0; j < 6; j++)
+        {
+          for (unsigned int k = 0; k < 6; k++)
+          {
+            // Number of operations to compute entry: 3
+            A[nzc6[j]*20 + nzc7[k]] += FE0_f0_C0[ip][j]*FE0_f0_C0[ip][k]*Gip0;
+          }// end loop over 'k'
+        }// end loop over 'j'
+      }// end loop over 'ip'
+      }
+      break;
+    }
+}
+
+/// Constructor
+solitarywave3d_0_exterior_facet_integral_0::solitarywave3d_0_exterior_facet_integral_0() : ufc::exterior_facet_integral()
+{
+    // Do nothing
+}
+
+/// Destructor
+solitarywave3d_0_exterior_facet_integral_0::~solitarywave3d_0_exterior_facet_integral_0()
+{
+    // Do nothing
+}
+
+/// Tabulate the tensor for the contribution from a local exterior facet
+void solitarywave3d_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 < 400; j++)
+      A[j] = 0;
+    
+    // Add all contributions to element tensor
+    integral_0_quadrature.tabulate_tensor(A, w, c, facet);
+}
+
+/// Constructor
+solitarywave3d_form_0::solitarywave3d_form_0() : ufc::form()
+{
+    // Do nothing
+}
+
+/// Destructor
+solitarywave3d_form_0::~solitarywave3d_form_0()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the form
+const char* solitarywave3d_form_0::signature() const
+{
+    return "Form([Integral(Sum(Product(Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})), Sum(Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) }), 1), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})), Product(IntValue(-1, (), (), {}), Product(Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) }), 1), MultiIndex((FixedIndex(0),), {FixedIndex(0): 2})), Product(Constant(Cell('tetrahedron', 1, Space(3)), 2), Product(FloatValue(0.5, (), (), {}), Constant(Cell('tetrahedron', 1, Space(3)), 1))))))), Sum(Product(IntValue(-1, (), (), {}), Product(Indexed(SpatialDerivative(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(2),), {FixedIndex(2): 3})), MultiIndex((FixedIndex(0),), {FixedIndex(0): 2})), Sum(Product(Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) }), 1), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})), Power(Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})), IntValue(2, (), (), {}))), Product(Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})), Product(Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})), Product(IntValue(2, (), (), {}), Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) }), 1), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})))))))), Sum(Product(Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) }), 1), MultiIndex((FixedIndex(0),), {FixedIndex(0): 2})), Product(Constant(Cell('tetrahedron', 1, Space(3)), 2), Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(0),), {FixedIndex(0): 2})))), Sum(Product(IndexSum(Product(Indexed(ComponentTensor(Indexed(SpatialDerivative(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((Index(0),), {Index(0): 3})), MultiIndex((FixedIndex(0),), {})), MultiIndex((Index(0),), {Index(0): 3})), MultiIndex((Index(1),), {Index(1): 3})), Indexed(ComponentTensor(Indexed(SpatialDerivative(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) }), 1), MultiIndex((Index(2),), {Index(2): 3})), MultiIndex((FixedIndex(0),), {})), MultiIndex((Index(2),), {Index(2): 3})), MultiIndex((Index(1),), {Index(1): 3}))), MultiIndex((Index(1),), {Index(1): 3})), Product(Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})), Power(Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 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('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((Index(0),), {Index(0): 3})), MultiIndex((FixedIndex(0),), {})), MultiIndex((Index(0),), {Index(0): 3})), MultiIndex((Index(1),), {Index(1): 3})), Indexed(ComponentTensor(Indexed(SpatialDerivative(Function(MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((Index(2),), {Index(2): 3})), MultiIndex((FixedIndex(0),), {})), MultiIndex((Index(2),), {Index(2): 3})), MultiIndex((Index(1),), {Index(1): 3}))), MultiIndex((Index(1),), {Index(1): 3})), Sum(Product(Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) }), 1), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})), Power(Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})), IntValue(2, (), (), {}))), Product(Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})), Product(Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})), Product(IntValue(2, (), (), {}), Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) }), 1), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2}))))))))))), Measure('cell', 0, None)), Integral(Product(Indexed(FacetNormal(Cell('tetrahedron', 1, Space(3))), MultiIndex((FixedIndex(2),), {FixedIndex(2): 3})), Product(Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(0),), {FixedIndex(0): 2})), Sum(Product(Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) }), 1), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})), Power(Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})), IntValue(2, (), (), {}))), Product(Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})), Product(Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})), Product(IntValue(2, (), (), {}), Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) }), 1), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})))))))), Measure('exterior_facet', 0, None))])";
+}
+
+/// Return the rank of the global tensor (r)
+unsigned int solitarywave3d_form_0::rank() const
+{
+    return 2;
+}
+
+/// Return the number of coefficients (n)
+unsigned int solitarywave3d_form_0::num_coefficients() const
+{
+    return 3;
+}
+
+/// Return the number of cell integrals
+unsigned int solitarywave3d_form_0::num_cell_integrals() const
+{
+    return 1;
+}
+
+/// Return the number of exterior facet integrals
+unsigned int solitarywave3d_form_0::num_exterior_facet_integrals() const
+{
+    return 1;
+}
+
+/// Return the number of interior facet integrals
+unsigned int solitarywave3d_form_0::num_interior_facet_integrals() const
+{
+    return 0;
+}
+
+/// Create a new finite element for argument function i
+ufc::finite_element* solitarywave3d_form_0::create_finite_element(unsigned int i) const
+{
+    switch ( i )
+    {
+    case 0:
+      return new solitarywave3d_0_finite_element_0();
+      break;
+    case 1:
+      return new solitarywave3d_0_finite_element_1();
+      break;
+    case 2:
+      return new solitarywave3d_0_finite_element_2();
+      break;
+    case 3:
+      return new solitarywave3d_0_finite_element_3();
+      break;
+    case 4:
+      return new solitarywave3d_0_finite_element_4();
+      break;
+    }
+    return 0;
+}
+
+/// Create a new dof map for argument function i
+ufc::dof_map* solitarywave3d_form_0::create_dof_map(unsigned int i) const
+{
+    switch ( i )
+    {
+    case 0:
+      return new solitarywave3d_0_dof_map_0();
+      break;
+    case 1:
+      return new solitarywave3d_0_dof_map_1();
+      break;
+    case 2:
+      return new solitarywave3d_0_dof_map_2();
+      break;
+    case 3:
+      return new solitarywave3d_0_dof_map_3();
+      break;
+    case 4:
+      return new solitarywave3d_0_dof_map_4();
+      break;
+    }
+    return 0;
+}
+
+/// Create a new cell integral on sub domain i
+ufc::cell_integral* solitarywave3d_form_0::create_cell_integral(unsigned int i) const
+{
+    return new solitarywave3d_0_cell_integral_0();
+}
+
+/// Create a new exterior facet integral on sub domain i
+ufc::exterior_facet_integral* solitarywave3d_form_0::create_exterior_facet_integral(unsigned int i) const
+{
+    return new solitarywave3d_0_exterior_facet_integral_0();
+}
+
+/// Create a new interior facet integral on sub domain i
+ufc::interior_facet_integral* solitarywave3d_form_0::create_interior_facet_integral(unsigned int i) const
+{
+    return 0;
+}
+
+
+/// Constructor
+solitarywave3d_1_finite_element_0_0::solitarywave3d_1_finite_element_0_0() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+solitarywave3d_1_finite_element_0_0::~solitarywave3d_1_finite_element_0_0()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* solitarywave3d_1_finite_element_0_0::signature() const
+{
+    return "FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)";
+}
+
+/// Return the cell shape
+ufc::shape solitarywave3d_1_finite_element_0_0::cell_shape() const
+{
+    return ufc::tetrahedron;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int solitarywave3d_1_finite_element_0_0::space_dimension() const
+{
+    return 10;
+}
+
+/// Return the rank of the value space
+unsigned int solitarywave3d_1_finite_element_0_0::value_rank() const
+{
+    return 0;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int solitarywave3d_1_finite_element_0_0::value_dimension(unsigned int i) const
+{
+    return 1;
+}
+
+/// Evaluate basis function i at given point in cell
+void solitarywave3d_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_02 = element_coordinates[3][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];
+    const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
+    const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
+    const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
+    const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
+    
+    // Compute sub determinants
+    const double d00 = J_11*J_22 - J_12*J_21;
+    const double d01 = J_12*J_20 - J_10*J_22;
+    const double d02 = J_10*J_21 - J_11*J_20;
+    
+    const double d10 = J_02*J_21 - J_01*J_22;
+    const double d11 = J_00*J_22 - J_02*J_20;
+    const double d12 = J_01*J_20 - J_00*J_21;
+    
+    const double d20 = J_01*J_12 - J_02*J_11;
+    const double d21 = J_02*J_10 - J_00*J_12;
+    const double d22 = J_00*J_11 - J_01*J_10;
+    
+    // Compute determinant of Jacobian
+    double detJ = J_00*d00 + J_10*d10 + J_20*d20;
+    
+    // Compute inverse of Jacobian
+    
+    // Compute constants
+    const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
+                    + d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
+                    + d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
+    
+    const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
+                    + d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
+                    + d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
+    
+    const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
+                    + d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
+                    + d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
+    
+    // Get coordinates and map to the UFC reference element
+    double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
+    double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
+    double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
+    
+    // Map coordinates to the reference cube
+    if (std::abs(y + z - 1.0) < 1e-14)
+      x = 1.0;
+    else
+      x = -2.0 * x/(y + z - 1.0) - 1.0;
+    if (std::abs(z - 1.0) < 1e-14)
+      y = -1.0;
+    else
+      y = 2.0 * y/(1.0 - z) - 1.0;
+    z = 2.0 * z - 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);
+    const double scalings_z_0 = 1;
+    const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
+    const double scalings_z_2 = scalings_z_1*(0.5 - 0.5*z);
+    
+    // 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 psitilde_cs
+    const double psitilde_cs_00_0 = 1;
+    const double psitilde_cs_00_1 = 2*z + 1;
+    const double psitilde_cs_00_2 = 0.3125*psitilde_cs_00_1 + 1.875*z*psitilde_cs_00_1 - 0.5625*psitilde_cs_00_0;
+    const double psitilde_cs_01_0 = 1;
+    const double psitilde_cs_01_1 = 3*z + 2;
+    const double psitilde_cs_02_0 = 1;
+    const double psitilde_cs_10_0 = 1;
+    const double psitilde_cs_10_1 = 3*z + 2;
+    const double psitilde_cs_11_0 = 1;
+    const double psitilde_cs_20_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.866025403784439*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
+    const double basisvalue1 = 2.73861278752583*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
+    const double basisvalue2 = 1.58113883008419*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
+    const double basisvalue3 = 1.11803398874989*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
+    const double basisvalue4 = 5.1234753829798*psitilde_a_2*scalings_y_2*psitilde_bs_2_0*scalings_z_2*psitilde_cs_20_0;
+    const double basisvalue5 = 3.96862696659689*psitilde_a_1*scalings_y_1*psitilde_bs_1_1*scalings_z_2*psitilde_cs_11_0;
+    const double basisvalue6 = 2.29128784747792*psitilde_a_0*scalings_y_0*psitilde_bs_0_2*scalings_z_2*psitilde_cs_02_0;
+    const double basisvalue7 = 3.24037034920393*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_1;
+    const double basisvalue8 = 1.87082869338697*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_1;
+    const double basisvalue9 = 1.3228756555323*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_2;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[10][10] = \
+    {{-0.0577350269189626, -0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, 0.0503952630678969, 0.0290957186981323, 0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
+    {-0.0577350269189625, 0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, -0.050395263067897, 0.0290957186981323, -0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
+    {-0.0577350269189625, 0, 0.0702728368926306, -0.0248451997499977, 0, 0, 0.0872871560943969, 0, -0.0475131096733199, 0.0167984210226323},
+    {-0.0577350269189626, 0, 0, 0.074535599249993, 0, 0, 0, 0, 0, 0.100790526135794},
+    {0.23094010767585, 0, 0.140545673785261, 0.0993807989999906, 0, 0, 0, 0, 0.1187827741833, -0.0671936840905293},
+    {0.230940107675851, 0.121716123890037, -0.0702728368926306, 0.0993807989999907, 0, 0, 0, 0.102868899974728, -0.0593913870916499, -0.0671936840905293},
+    {0.23094010767585, 0.121716123890037, 0.0702728368926307, -0.0993807989999907, 0, 0.100790526135794, -0.087287156094397, -0.0205737799949456, -0.01187827741833, 0.0167984210226323},
+    {0.23094010767585, -0.121716123890037, -0.0702728368926307, 0.0993807989999906, 0, 0, 0, -0.102868899974728, -0.0593913870916499, -0.0671936840905293},
+    {0.23094010767585, -0.121716123890037, 0.0702728368926306, -0.0993807989999906, 0, -0.100790526135794, -0.0872871560943969, 0.0205737799949456, -0.01187827741833, 0.0167984210226323},
+    {0.23094010767585, 0, -0.140545673785261, -0.0993807989999906, -0.130120009726471, 0, 0.0290957186981323, 0, 0.02375655483666, 0.0167984210226323}};
+    
+    // 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];
+    const double coeff0_6 = coefficients0[dof][6];
+    const double coeff0_7 = coefficients0[dof][7];
+    const double coeff0_8 = coefficients0[dof][8];
+    const double coeff0_9 = coefficients0[dof][9];
+    
+    // Compute value(s)
+    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5 + coeff0_6*basisvalue6 + coeff0_7*basisvalue7 + coeff0_8*basisvalue8 + coeff0_9*basisvalue9;
+}
+
+/// Evaluate all basis functions at given point in cell
+void solitarywave3d_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 solitarywave3d_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_02 = element_coordinates[3][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];
+    const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
+    const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
+    const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
+    const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
+    
+    // Compute sub determinants
+    const double d00 = J_11*J_22 - J_12*J_21;
+    const double d01 = J_12*J_20 - J_10*J_22;
+    const double d02 = J_10*J_21 - J_11*J_20;
+    
+    const double d10 = J_02*J_21 - J_01*J_22;
+    const double d11 = J_00*J_22 - J_02*J_20;
+    const double d12 = J_01*J_20 - J_00*J_21;
+    
+    const double d20 = J_01*J_12 - J_02*J_11;
+    const double d21 = J_02*J_10 - J_00*J_12;
+    const double d22 = J_00*J_11 - J_01*J_10;
+    
+    // Compute determinant of Jacobian
+    double detJ = J_00*d00 + J_10*d10 + J_20*d20;
+    
+    // Compute inverse of Jacobian
+    
+    // Compute constants
+    const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
+                    + d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
+                    + d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
+    
+    const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
+                    + d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
+                    + d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
+    
+    const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
+                    + d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
+                    + d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
+    
+    // Get coordinates and map to the UFC reference element
+    double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
+    double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
+    double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
+    
+    // Map coordinates to the reference cube
+    if (std::abs(y + z - 1.0) < 1e-14)
+      x = 1.0;
+    else
+      x = -2.0 * x/(y + z - 1.0) - 1.0;
+    if (std::abs(z - 1.0) < 1e-14)
+      y = -1.0;
+    else
+      y = 2.0 * y/(1.0 - z) - 1.0;
+    z = 2.0 * z - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 3;
+    
+    
+    // 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 > 2)
+            combinations[row][col] = 0;
+          else
+          {
+            combinations[row][col] += 1;
+            break;
+          }
+        }
+      }
+    }
+    
+    // Compute inverse of Jacobian
+    const double Jinv[3][3] ={{d00 / detJ, d10 / detJ, d20 / detJ}, {d01 / detJ, d11 / detJ, d21 / detJ}, {d02 / detJ, d12 / detJ, d22 / 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);
+    const double scalings_z_0 = 1;
+    const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
+    const double scalings_z_2 = scalings_z_1*(0.5 - 0.5*z);
+    
+    // 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 psitilde_cs
+    const double psitilde_cs_00_0 = 1;
+    const double psitilde_cs_00_1 = 2*z + 1;
+    const double psitilde_cs_00_2 = 0.3125*psitilde_cs_00_1 + 1.875*z*psitilde_cs_00_1 - 0.5625*psitilde_cs_00_0;
+    const double psitilde_cs_01_0 = 1;
+    const double psitilde_cs_01_1 = 3*z + 2;
+    const double psitilde_cs_02_0 = 1;
+    const double psitilde_cs_10_0 = 1;
+    const double psitilde_cs_10_1 = 3*z + 2;
+    const double psitilde_cs_11_0 = 1;
+    const double psitilde_cs_20_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.866025403784439*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
+    const double basisvalue1 = 2.73861278752583*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
+    const double basisvalue2 = 1.58113883008419*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
+    const double basisvalue3 = 1.11803398874989*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
+    const double basisvalue4 = 5.1234753829798*psitilde_a_2*scalings_y_2*psitilde_bs_2_0*scalings_z_2*psitilde_cs_20_0;
+    const double basisvalue5 = 3.96862696659689*psitilde_a_1*scalings_y_1*psitilde_bs_1_1*scalings_z_2*psitilde_cs_11_0;
+    const double basisvalue6 = 2.29128784747792*psitilde_a_0*scalings_y_0*psitilde_bs_0_2*scalings_z_2*psitilde_cs_02_0;
+    const double basisvalue7 = 3.24037034920393*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_1;
+    const double basisvalue8 = 1.87082869338697*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_1;
+    const double basisvalue9 = 1.3228756555323*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_2;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[10][10] = \
+    {{-0.0577350269189626, -0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, 0.0503952630678969, 0.0290957186981323, 0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
+    {-0.0577350269189625, 0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, -0.050395263067897, 0.0290957186981323, -0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
+    {-0.0577350269189625, 0, 0.0702728368926306, -0.0248451997499977, 0, 0, 0.0872871560943969, 0, -0.0475131096733199, 0.0167984210226323},
+    {-0.0577350269189626, 0, 0, 0.074535599249993, 0, 0, 0, 0, 0, 0.100790526135794},
+    {0.23094010767585, 0, 0.140545673785261, 0.0993807989999906, 0, 0, 0, 0, 0.1187827741833, -0.0671936840905293},
+    {0.230940107675851, 0.121716123890037, -0.0702728368926306, 0.0993807989999907, 0, 0, 0, 0.102868899974728, -0.0593913870916499, -0.0671936840905293},
+    {0.23094010767585, 0.121716123890037, 0.0702728368926307, -0.0993807989999907, 0, 0.100790526135794, -0.087287156094397, -0.0205737799949456, -0.01187827741833, 0.0167984210226323},
+    {0.23094010767585, -0.121716123890037, -0.0702728368926307, 0.0993807989999906, 0, 0, 0, -0.102868899974728, -0.0593913870916499, -0.0671936840905293},
+    {0.23094010767585, -0.121716123890037, 0.0702728368926306, -0.0993807989999906, 0, -0.100790526135794, -0.0872871560943969, 0.0205737799949456, -0.01187827741833, 0.0167984210226323},
+    {0.23094010767585, 0, -0.140545673785261, -0.0993807989999906, -0.130120009726471, 0, 0.0290957186981323, 0, 0.02375655483666, 0.0167984210226323}};
+    
+    // Interesting (new) part
+    // Tables of derivatives of the polynomial base (transpose)
+    static const double dmats0[10][10] = \
+    {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    {6.32455532033676, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    {0, 11.2249721603218, 0, 0, 0, 0, 0, 0, 0, 0},
+    {4.58257569495584, 0, 8.36660026534076, -1.18321595661992, 0, 0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    {3.74165738677394, 0, 0, 8.69482604771366, 0, 0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
+    
+    static const double dmats1[10][10] = \
+    {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    {3.16227766016838, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    {5.47722557505166, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    {2.95803989154981, 5.61248608016091, -1.08012344973464, -0.763762615825974, 0, 0, 0, 0, 0, 0},
+    {2.29128784747792, 7.24568837309472, 4.18330013267038, -0.591607978309962, 0, 0, 0, 0, 0, 0},
+    {-2.64575131106459, 0, 9.66091783079296, 0.683130051063974, 0, 0, 0, 0, 0, 0},
+    {1.87082869338697, 0, 0, 4.34741302385683, 0, 0, 0, 0, 0, 0},
+    {3.24037034920393, 0, 0, 7.52994023880668, 0, 0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
+    
+    static const double dmats2[10][10] = \
+    {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    {3.16227766016838, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    {1.82574185835055, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    {5.16397779494322, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    {2.95803989154981, 5.61248608016091, -1.08012344973464, -0.763762615825974, 0, 0, 0, 0, 0, 0},
+    {2.29128784747792, 1.44913767461894, 4.18330013267038, -0.591607978309962, 0, 0, 0, 0, 0, 0},
+    {1.32287565553229, 0, 3.86436713231718, -0.341565025531986, 0, 0, 0, 0, 0, 0},
+    {1.87082869338697, 7.09929573971954, 0, 4.34741302385683, 0, 0, 0, 0, 0, 0},
+    {1.08012344973464, 0, 7.09929573971954, 2.50998007960223, 0, 0, 0, 0, 0, 0},
+    {-3.81881307912987, 0, 0, 8.87411967464942, 0, 0, 0, 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;
+    double coeff0_6 = 0;
+    double coeff0_7 = 0;
+    double coeff0_8 = 0;
+    double coeff0_9 = 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;
+    double new_coeff0_6 = 0;
+    double new_coeff0_7 = 0;
+    double new_coeff0_8 = 0;
+    double new_coeff0_9 = 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];
+      new_coeff0_6 = coefficients0[dof][6];
+      new_coeff0_7 = coefficients0[dof][7];
+      new_coeff0_8 = coefficients0[dof][8];
+      new_coeff0_9 = coefficients0[dof][9];
+    
+      // 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;
+        coeff0_6 = new_coeff0_6;
+        coeff0_7 = new_coeff0_7;
+        coeff0_8 = new_coeff0_8;
+        coeff0_9 = new_coeff0_9;
+    
+        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] + coeff0_6*dmats0[6][0] + coeff0_7*dmats0[7][0] + coeff0_8*dmats0[8][0] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][1] + coeff0_7*dmats0[7][1] + coeff0_8*dmats0[8][1] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][2] + coeff0_7*dmats0[7][2] + coeff0_8*dmats0[8][2] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][3] + coeff0_7*dmats0[7][3] + coeff0_8*dmats0[8][3] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][4] + coeff0_7*dmats0[7][4] + coeff0_8*dmats0[8][4] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][5] + coeff0_7*dmats0[7][5] + coeff0_8*dmats0[8][5] + coeff0_9*dmats0[9][5];
+          new_coeff0_6 = coeff0_0*dmats0[0][6] + coeff0_1*dmats0[1][6] + coeff0_2*dmats0[2][6] + coeff0_3*dmats0[3][6] + coeff0_4*dmats0[4][6] + coeff0_5*dmats0[5][6] + coeff0_6*dmats0[6][6] + coeff0_7*dmats0[7][6] + coeff0_8*dmats0[8][6] + coeff0_9*dmats0[9][6];
+          new_coeff0_7 = coeff0_0*dmats0[0][7] + coeff0_1*dmats0[1][7] + coeff0_2*dmats0[2][7] + coeff0_3*dmats0[3][7] + coeff0_4*dmats0[4][7] + coeff0_5*dmats0[5][7] + coeff0_6*dmats0[6][7] + coeff0_7*dmats0[7][7] + coeff0_8*dmats0[8][7] + coeff0_9*dmats0[9][7];
+          new_coeff0_8 = coeff0_0*dmats0[0][8] + coeff0_1*dmats0[1][8] + coeff0_2*dmats0[2][8] + coeff0_3*dmats0[3][8] + coeff0_4*dmats0[4][8] + coeff0_5*dmats0[5][8] + coeff0_6*dmats0[6][8] + coeff0_7*dmats0[7][8] + coeff0_8*dmats0[8][8] + coeff0_9*dmats0[9][8];
+          new_coeff0_9 = coeff0_0*dmats0[0][9] + coeff0_1*dmats0[1][9] + coeff0_2*dmats0[2][9] + coeff0_3*dmats0[3][9] + coeff0_4*dmats0[4][9] + coeff0_5*dmats0[5][9] + coeff0_6*dmats0[6][9] + coeff0_7*dmats0[7][9] + coeff0_8*dmats0[8][9] + coeff0_9*dmats0[9][9];
+        }
+        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] + coeff0_6*dmats1[6][0] + coeff0_7*dmats1[7][0] + coeff0_8*dmats1[8][0] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][1] + coeff0_7*dmats1[7][1] + coeff0_8*dmats1[8][1] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][2] + coeff0_7*dmats1[7][2] + coeff0_8*dmats1[8][2] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][3] + coeff0_7*dmats1[7][3] + coeff0_8*dmats1[8][3] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][4] + coeff0_7*dmats1[7][4] + coeff0_8*dmats1[8][4] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][5] + coeff0_7*dmats1[7][5] + coeff0_8*dmats1[8][5] + coeff0_9*dmats1[9][5];
+          new_coeff0_6 = coeff0_0*dmats1[0][6] + coeff0_1*dmats1[1][6] + coeff0_2*dmats1[2][6] + coeff0_3*dmats1[3][6] + coeff0_4*dmats1[4][6] + coeff0_5*dmats1[5][6] + coeff0_6*dmats1[6][6] + coeff0_7*dmats1[7][6] + coeff0_8*dmats1[8][6] + coeff0_9*dmats1[9][6];
+          new_coeff0_7 = coeff0_0*dmats1[0][7] + coeff0_1*dmats1[1][7] + coeff0_2*dmats1[2][7] + coeff0_3*dmats1[3][7] + coeff0_4*dmats1[4][7] + coeff0_5*dmats1[5][7] + coeff0_6*dmats1[6][7] + coeff0_7*dmats1[7][7] + coeff0_8*dmats1[8][7] + coeff0_9*dmats1[9][7];
+          new_coeff0_8 = coeff0_0*dmats1[0][8] + coeff0_1*dmats1[1][8] + coeff0_2*dmats1[2][8] + coeff0_3*dmats1[3][8] + coeff0_4*dmats1[4][8] + coeff0_5*dmats1[5][8] + coeff0_6*dmats1[6][8] + coeff0_7*dmats1[7][8] + coeff0_8*dmats1[8][8] + coeff0_9*dmats1[9][8];
+          new_coeff0_9 = coeff0_0*dmats1[0][9] + coeff0_1*dmats1[1][9] + coeff0_2*dmats1[2][9] + coeff0_3*dmats1[3][9] + coeff0_4*dmats1[4][9] + coeff0_5*dmats1[5][9] + coeff0_6*dmats1[6][9] + coeff0_7*dmats1[7][9] + coeff0_8*dmats1[8][9] + coeff0_9*dmats1[9][9];
+        }
+        if(combinations[deriv_num][j] == 2)
+        {
+          new_coeff0_0 = coeff0_0*dmats2[0][0] + coeff0_1*dmats2[1][0] + coeff0_2*dmats2[2][0] + coeff0_3*dmats2[3][0] + coeff0_4*dmats2[4][0] + coeff0_5*dmats2[5][0] + coeff0_6*dmats2[6][0] + coeff0_7*dmats2[7][0] + coeff0_8*dmats2[8][0] + coeff0_9*dmats2[9][0];
+          new_coeff0_1 = coeff0_0*dmats2[0][1] + coeff0_1*dmats2[1][1] + coeff0_2*dmats2[2][1] + coeff0_3*dmats2[3][1] + coeff0_4*dmats2[4][1] + coeff0_5*dmats2[5][1] + coeff0_6*dmats2[6][1] + coeff0_7*dmats2[7][1] + coeff0_8*dmats2[8][1] + coeff0_9*dmats2[9][1];
+          new_coeff0_2 = coeff0_0*dmats2[0][2] + coeff0_1*dmats2[1][2] + coeff0_2*dmats2[2][2] + coeff0_3*dmats2[3][2] + coeff0_4*dmats2[4][2] + coeff0_5*dmats2[5][2] + coeff0_6*dmats2[6][2] + coeff0_7*dmats2[7][2] + coeff0_8*dmats2[8][2] + coeff0_9*dmats2[9][2];
+          new_coeff0_3 = coeff0_0*dmats2[0][3] + coeff0_1*dmats2[1][3] + coeff0_2*dmats2[2][3] + coeff0_3*dmats2[3][3] + coeff0_4*dmats2[4][3] + coeff0_5*dmats2[5][3] + coeff0_6*dmats2[6][3] + coeff0_7*dmats2[7][3] + coeff0_8*dmats2[8][3] + coeff0_9*dmats2[9][3];
+          new_coeff0_4 = coeff0_0*dmats2[0][4] + coeff0_1*dmats2[1][4] + coeff0_2*dmats2[2][4] + coeff0_3*dmats2[3][4] + coeff0_4*dmats2[4][4] + coeff0_5*dmats2[5][4] + coeff0_6*dmats2[6][4] + coeff0_7*dmats2[7][4] + coeff0_8*dmats2[8][4] + coeff0_9*dmats2[9][4];
+          new_coeff0_5 = coeff0_0*dmats2[0][5] + coeff0_1*dmats2[1][5] + coeff0_2*dmats2[2][5] + coeff0_3*dmats2[3][5] + coeff0_4*dmats2[4][5] + coeff0_5*dmats2[5][5] + coeff0_6*dmats2[6][5] + coeff0_7*dmats2[7][5] + coeff0_8*dmats2[8][5] + coeff0_9*dmats2[9][5];
+          new_coeff0_6 = coeff0_0*dmats2[0][6] + coeff0_1*dmats2[1][6] + coeff0_2*dmats2[2][6] + coeff0_3*dmats2[3][6] + coeff0_4*dmats2[4][6] + coeff0_5*dmats2[5][6] + coeff0_6*dmats2[6][6] + coeff0_7*dmats2[7][6] + coeff0_8*dmats2[8][6] + coeff0_9*dmats2[9][6];
+          new_coeff0_7 = coeff0_0*dmats2[0][7] + coeff0_1*dmats2[1][7] + coeff0_2*dmats2[2][7] + coeff0_3*dmats2[3][7] + coeff0_4*dmats2[4][7] + coeff0_5*dmats2[5][7] + coeff0_6*dmats2[6][7] + coeff0_7*dmats2[7][7] + coeff0_8*dmats2[8][7] + coeff0_9*dmats2[9][7];
+          new_coeff0_8 = coeff0_0*dmats2[0][8] + coeff0_1*dmats2[1][8] + coeff0_2*dmats2[2][8] + coeff0_3*dmats2[3][8] + coeff0_4*dmats2[4][8] + coeff0_5*dmats2[5][8] + coeff0_6*dmats2[6][8] + coeff0_7*dmats2[7][8] + coeff0_8*dmats2[8][8] + coeff0_9*dmats2[9][8];
+          new_coeff0_9 = coeff0_0*dmats2[0][9] + coeff0_1*dmats2[1][9] + coeff0_2*dmats2[2][9] + coeff0_3*dmats2[3][9] + coeff0_4*dmats2[4][9] + coeff0_5*dmats2[5][9] + coeff0_6*dmats2[6][9] + coeff0_7*dmats2[7][9] + coeff0_8*dmats2[8][9] + coeff0_9*dmats2[9][9];
+        }
+    
+      }
+      // 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 + new_coeff0_6*basisvalue6 + new_coeff0_7*basisvalue7 + new_coeff0_8*basisvalue8 + new_coeff0_9*basisvalue9;
+    }
+    
+    // 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 solitarywave3d_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 solitarywave3d_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[10][1][3] = {{{0, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 0, 1}}, {{0, 0.5, 0.5}}, {{0.5, 0, 0.5}}, {{0.5, 0.5, 0}}, {{0, 0, 0.5}}, {{0, 0.5, 0}}, {{0.5, 0, 0}}};
+    static const double W[10][1] = {{1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}};
+    static const double D[10][1][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] - X[i][0][2];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    const double w3 = X[i][0][2];
+    
+    // Compute affine mapping y = F(X)
+    double y[3];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0] + w3*x[3][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1] + w3*x[3][1];
+    y[2] = w0*x[0][2] + w1*x[1][2] + w2*x[2][2] + w3*x[3][2];
+    
+    // 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 solitarywave3d_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 solitarywave3d_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];
+    vertex_values[3] = dof_values[3];
+}
+
+/// Return the number of sub elements (for a mixed element)
+unsigned int solitarywave3d_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* solitarywave3d_1_finite_element_0_0::create_sub_element(unsigned int i) const
+{
+    return new solitarywave3d_1_finite_element_0_0();
+}
+
+
+/// Constructor
+solitarywave3d_1_finite_element_0_1::solitarywave3d_1_finite_element_0_1() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+solitarywave3d_1_finite_element_0_1::~solitarywave3d_1_finite_element_0_1()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* solitarywave3d_1_finite_element_0_1::signature() const
+{
+    return "FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)";
+}
+
+/// Return the cell shape
+ufc::shape solitarywave3d_1_finite_element_0_1::cell_shape() const
+{
+    return ufc::tetrahedron;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int solitarywave3d_1_finite_element_0_1::space_dimension() const
+{
+    return 10;
+}
+
+/// Return the rank of the value space
+unsigned int solitarywave3d_1_finite_element_0_1::value_rank() const
+{
+    return 0;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int solitarywave3d_1_finite_element_0_1::value_dimension(unsigned int i) const
+{
+    return 1;
+}
+
+/// Evaluate basis function i at given point in cell
+void solitarywave3d_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_02 = element_coordinates[3][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];
+    const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
+    const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
+    const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
+    const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
+    
+    // Compute sub determinants
+    const double d00 = J_11*J_22 - J_12*J_21;
+    const double d01 = J_12*J_20 - J_10*J_22;
+    const double d02 = J_10*J_21 - J_11*J_20;
+    
+    const double d10 = J_02*J_21 - J_01*J_22;
+    const double d11 = J_00*J_22 - J_02*J_20;
+    const double d12 = J_01*J_20 - J_00*J_21;
+    
+    const double d20 = J_01*J_12 - J_02*J_11;
+    const double d21 = J_02*J_10 - J_00*J_12;
+    const double d22 = J_00*J_11 - J_01*J_10;
+    
+    // Compute determinant of Jacobian
+    double detJ = J_00*d00 + J_10*d10 + J_20*d20;
+    
+    // Compute inverse of Jacobian
+    
+    // Compute constants
+    const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
+                    + d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
+                    + d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
+    
+    const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
+                    + d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
+                    + d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
+    
+    const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
+                    + d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
+                    + d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
+    
+    // Get coordinates and map to the UFC reference element
+    double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
+    double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
+    double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
+    
+    // Map coordinates to the reference cube
+    if (std::abs(y + z - 1.0) < 1e-14)
+      x = 1.0;
+    else
+      x = -2.0 * x/(y + z - 1.0) - 1.0;
+    if (std::abs(z - 1.0) < 1e-14)
+      y = -1.0;
+    else
+      y = 2.0 * y/(1.0 - z) - 1.0;
+    z = 2.0 * z - 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);
+    const double scalings_z_0 = 1;
+    const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
+    const double scalings_z_2 = scalings_z_1*(0.5 - 0.5*z);
+    
+    // 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 psitilde_cs
+    const double psitilde_cs_00_0 = 1;
+    const double psitilde_cs_00_1 = 2*z + 1;
+    const double psitilde_cs_00_2 = 0.3125*psitilde_cs_00_1 + 1.875*z*psitilde_cs_00_1 - 0.5625*psitilde_cs_00_0;
+    const double psitilde_cs_01_0 = 1;
+    const double psitilde_cs_01_1 = 3*z + 2;
+    const double psitilde_cs_02_0 = 1;
+    const double psitilde_cs_10_0 = 1;
+    const double psitilde_cs_10_1 = 3*z + 2;
+    const double psitilde_cs_11_0 = 1;
+    const double psitilde_cs_20_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.866025403784439*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
+    const double basisvalue1 = 2.73861278752583*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
+    const double basisvalue2 = 1.58113883008419*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
+    const double basisvalue3 = 1.11803398874989*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
+    const double basisvalue4 = 5.1234753829798*psitilde_a_2*scalings_y_2*psitilde_bs_2_0*scalings_z_2*psitilde_cs_20_0;
+    const double basisvalue5 = 3.96862696659689*psitilde_a_1*scalings_y_1*psitilde_bs_1_1*scalings_z_2*psitilde_cs_11_0;
+    const double basisvalue6 = 2.29128784747792*psitilde_a_0*scalings_y_0*psitilde_bs_0_2*scalings_z_2*psitilde_cs_02_0;
+    const double basisvalue7 = 3.24037034920393*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_1;
+    const double basisvalue8 = 1.87082869338697*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_1;
+    const double basisvalue9 = 1.3228756555323*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_2;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[10][10] = \
+    {{-0.0577350269189626, -0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, 0.0503952630678969, 0.0290957186981323, 0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
+    {-0.0577350269189625, 0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, -0.050395263067897, 0.0290957186981323, -0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
+    {-0.0577350269189625, 0, 0.0702728368926306, -0.0248451997499977, 0, 0, 0.0872871560943969, 0, -0.0475131096733199, 0.0167984210226323},
+    {-0.0577350269189626, 0, 0, 0.074535599249993, 0, 0, 0, 0, 0, 0.100790526135794},
+    {0.23094010767585, 0, 0.140545673785261, 0.0993807989999906, 0, 0, 0, 0, 0.1187827741833, -0.0671936840905293},
+    {0.230940107675851, 0.121716123890037, -0.0702728368926306, 0.0993807989999907, 0, 0, 0, 0.102868899974728, -0.0593913870916499, -0.0671936840905293},
+    {0.23094010767585, 0.121716123890037, 0.0702728368926307, -0.0993807989999907, 0, 0.100790526135794, -0.087287156094397, -0.0205737799949456, -0.01187827741833, 0.0167984210226323},
+    {0.23094010767585, -0.121716123890037, -0.0702728368926307, 0.0993807989999906, 0, 0, 0, -0.102868899974728, -0.0593913870916499, -0.0671936840905293},
+    {0.23094010767585, -0.121716123890037, 0.0702728368926306, -0.0993807989999906, 0, -0.100790526135794, -0.0872871560943969, 0.0205737799949456, -0.01187827741833, 0.0167984210226323},
+    {0.23094010767585, 0, -0.140545673785261, -0.0993807989999906, -0.130120009726471, 0, 0.0290957186981323, 0, 0.02375655483666, 0.0167984210226323}};
+    
+    // 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];
+    const double coeff0_6 = coefficients0[dof][6];
+    const double coeff0_7 = coefficients0[dof][7];
+    const double coeff0_8 = coefficients0[dof][8];
+    const double coeff0_9 = coefficients0[dof][9];
+    
+    // Compute value(s)
+    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5 + coeff0_6*basisvalue6 + coeff0_7*basisvalue7 + coeff0_8*basisvalue8 + coeff0_9*basisvalue9;
+}
+
+/// Evaluate all basis functions at given point in cell
+void solitarywave3d_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 solitarywave3d_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_02 = element_coordinates[3][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];
+    const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
+    const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
+    const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
+    const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
+    
+    // Compute sub determinants
+    const double d00 = J_11*J_22 - J_12*J_21;
+    const double d01 = J_12*J_20 - J_10*J_22;
+    const double d02 = J_10*J_21 - J_11*J_20;
+    
+    const double d10 = J_02*J_21 - J_01*J_22;
+    const double d11 = J_00*J_22 - J_02*J_20;
+    const double d12 = J_01*J_20 - J_00*J_21;
+    
+    const double d20 = J_01*J_12 - J_02*J_11;
+    const double d21 = J_02*J_10 - J_00*J_12;
+    const double d22 = J_00*J_11 - J_01*J_10;
+    
+    // Compute determinant of Jacobian
+    double detJ = J_00*d00 + J_10*d10 + J_20*d20;
+    
+    // Compute inverse of Jacobian
+    
+    // Compute constants
+    const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
+                    + d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
+                    + d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
+    
+    const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
+                    + d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
+                    + d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
+    
+    const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
+                    + d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
+                    + d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
+    
+    // Get coordinates and map to the UFC reference element
+    double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
+    double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
+    double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
+    
+    // Map coordinates to the reference cube
+    if (std::abs(y + z - 1.0) < 1e-14)
+      x = 1.0;
+    else
+      x = -2.0 * x/(y + z - 1.0) - 1.0;
+    if (std::abs(z - 1.0) < 1e-14)
+      y = -1.0;
+    else
+      y = 2.0 * y/(1.0 - z) - 1.0;
+    z = 2.0 * z - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 3;
+    
+    
+    // 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 > 2)
+            combinations[row][col] = 0;
+          else
+          {
+            combinations[row][col] += 1;
+            break;
+          }
+        }
+      }
+    }
+    
+    // Compute inverse of Jacobian
+    const double Jinv[3][3] ={{d00 / detJ, d10 / detJ, d20 / detJ}, {d01 / detJ, d11 / detJ, d21 / detJ}, {d02 / detJ, d12 / detJ, d22 / 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);
+    const double scalings_z_0 = 1;
+    const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
+    const double scalings_z_2 = scalings_z_1*(0.5 - 0.5*z);
+    
+    // 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 psitilde_cs
+    const double psitilde_cs_00_0 = 1;
+    const double psitilde_cs_00_1 = 2*z + 1;
+    const double psitilde_cs_00_2 = 0.3125*psitilde_cs_00_1 + 1.875*z*psitilde_cs_00_1 - 0.5625*psitilde_cs_00_0;
+    const double psitilde_cs_01_0 = 1;
+    const double psitilde_cs_01_1 = 3*z + 2;
+    const double psitilde_cs_02_0 = 1;
+    const double psitilde_cs_10_0 = 1;
+    const double psitilde_cs_10_1 = 3*z + 2;
+    const double psitilde_cs_11_0 = 1;
+    const double psitilde_cs_20_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.866025403784439*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
+    const double basisvalue1 = 2.73861278752583*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
+    const double basisvalue2 = 1.58113883008419*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
+    const double basisvalue3 = 1.11803398874989*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
+    const double basisvalue4 = 5.1234753829798*psitilde_a_2*scalings_y_2*psitilde_bs_2_0*scalings_z_2*psitilde_cs_20_0;
+    const double basisvalue5 = 3.96862696659689*psitilde_a_1*scalings_y_1*psitilde_bs_1_1*scalings_z_2*psitilde_cs_11_0;
+    const double basisvalue6 = 2.29128784747792*psitilde_a_0*scalings_y_0*psitilde_bs_0_2*scalings_z_2*psitilde_cs_02_0;
+    const double basisvalue7 = 3.24037034920393*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_1;
+    const double basisvalue8 = 1.87082869338697*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_1;
+    const double basisvalue9 = 1.3228756555323*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_2;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[10][10] = \
+    {{-0.0577350269189626, -0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, 0.0503952630678969, 0.0290957186981323, 0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
+    {-0.0577350269189625, 0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, -0.050395263067897, 0.0290957186981323, -0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
+    {-0.0577350269189625, 0, 0.0702728368926306, -0.0248451997499977, 0, 0, 0.0872871560943969, 0, -0.0475131096733199, 0.0167984210226323},
+    {-0.0577350269189626, 0, 0, 0.074535599249993, 0, 0, 0, 0, 0, 0.100790526135794},
+    {0.23094010767585, 0, 0.140545673785261, 0.0993807989999906, 0, 0, 0, 0, 0.1187827741833, -0.0671936840905293},
+    {0.230940107675851, 0.121716123890037, -0.0702728368926306, 0.0993807989999907, 0, 0, 0, 0.102868899974728, -0.0593913870916499, -0.0671936840905293},
+    {0.23094010767585, 0.121716123890037, 0.0702728368926307, -0.0993807989999907, 0, 0.100790526135794, -0.087287156094397, -0.0205737799949456, -0.01187827741833, 0.0167984210226323},
+    {0.23094010767585, -0.121716123890037, -0.0702728368926307, 0.0993807989999906, 0, 0, 0, -0.102868899974728, -0.0593913870916499, -0.0671936840905293},
+    {0.23094010767585, -0.121716123890037, 0.0702728368926306, -0.0993807989999906, 0, -0.100790526135794, -0.0872871560943969, 0.0205737799949456, -0.01187827741833, 0.0167984210226323},
+    {0.23094010767585, 0, -0.140545673785261, -0.0993807989999906, -0.130120009726471, 0, 0.0290957186981323, 0, 0.02375655483666, 0.0167984210226323}};
+    
+    // Interesting (new) part
+    // Tables of derivatives of the polynomial base (transpose)
+    static const double dmats0[10][10] = \
+    {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    {6.32455532033676, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    {0, 11.2249721603218, 0, 0, 0, 0, 0, 0, 0, 0},
+    {4.58257569495584, 0, 8.36660026534076, -1.18321595661992, 0, 0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    {3.74165738677394, 0, 0, 8.69482604771366, 0, 0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
+    
+    static const double dmats1[10][10] = \
+    {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    {3.16227766016838, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    {5.47722557505166, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    {2.95803989154981, 5.61248608016091, -1.08012344973464, -0.763762615825974, 0, 0, 0, 0, 0, 0},
+    {2.29128784747792, 7.24568837309472, 4.18330013267038, -0.591607978309962, 0, 0, 0, 0, 0, 0},
+    {-2.64575131106459, 0, 9.66091783079296, 0.683130051063974, 0, 0, 0, 0, 0, 0},
+    {1.87082869338697, 0, 0, 4.34741302385683, 0, 0, 0, 0, 0, 0},
+    {3.24037034920393, 0, 0, 7.52994023880668, 0, 0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
+    
+    static const double dmats2[10][10] = \
+    {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    {3.16227766016838, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    {1.82574185835055, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    {5.16397779494322, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    {2.95803989154981, 5.61248608016091, -1.08012344973464, -0.763762615825974, 0, 0, 0, 0, 0, 0},
+    {2.29128784747792, 1.44913767461894, 4.18330013267038, -0.591607978309962, 0, 0, 0, 0, 0, 0},
+    {1.32287565553229, 0, 3.86436713231718, -0.341565025531986, 0, 0, 0, 0, 0, 0},
+    {1.87082869338697, 7.09929573971954, 0, 4.34741302385683, 0, 0, 0, 0, 0, 0},
+    {1.08012344973464, 0, 7.09929573971954, 2.50998007960223, 0, 0, 0, 0, 0, 0},
+    {-3.81881307912987, 0, 0, 8.87411967464942, 0, 0, 0, 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;
+    double coeff0_6 = 0;
+    double coeff0_7 = 0;
+    double coeff0_8 = 0;
+    double coeff0_9 = 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;
+    double new_coeff0_6 = 0;
+    double new_coeff0_7 = 0;
+    double new_coeff0_8 = 0;
+    double new_coeff0_9 = 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];
+      new_coeff0_6 = coefficients0[dof][6];
+      new_coeff0_7 = coefficients0[dof][7];
+      new_coeff0_8 = coefficients0[dof][8];
+      new_coeff0_9 = coefficients0[dof][9];
+    
+      // 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;
+        coeff0_6 = new_coeff0_6;
+        coeff0_7 = new_coeff0_7;
+        coeff0_8 = new_coeff0_8;
+        coeff0_9 = new_coeff0_9;
+    
+        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] + coeff0_6*dmats0[6][0] + coeff0_7*dmats0[7][0] + coeff0_8*dmats0[8][0] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][1] + coeff0_7*dmats0[7][1] + coeff0_8*dmats0[8][1] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][2] + coeff0_7*dmats0[7][2] + coeff0_8*dmats0[8][2] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][3] + coeff0_7*dmats0[7][3] + coeff0_8*dmats0[8][3] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][4] + coeff0_7*dmats0[7][4] + coeff0_8*dmats0[8][4] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][5] + coeff0_7*dmats0[7][5] + coeff0_8*dmats0[8][5] + coeff0_9*dmats0[9][5];
+          new_coeff0_6 = coeff0_0*dmats0[0][6] + coeff0_1*dmats0[1][6] + coeff0_2*dmats0[2][6] + coeff0_3*dmats0[3][6] + coeff0_4*dmats0[4][6] + coeff0_5*dmats0[5][6] + coeff0_6*dmats0[6][6] + coeff0_7*dmats0[7][6] + coeff0_8*dmats0[8][6] + coeff0_9*dmats0[9][6];
+          new_coeff0_7 = coeff0_0*dmats0[0][7] + coeff0_1*dmats0[1][7] + coeff0_2*dmats0[2][7] + coeff0_3*dmats0[3][7] + coeff0_4*dmats0[4][7] + coeff0_5*dmats0[5][7] + coeff0_6*dmats0[6][7] + coeff0_7*dmats0[7][7] + coeff0_8*dmats0[8][7] + coeff0_9*dmats0[9][7];
+          new_coeff0_8 = coeff0_0*dmats0[0][8] + coeff0_1*dmats0[1][8] + coeff0_2*dmats0[2][8] + coeff0_3*dmats0[3][8] + coeff0_4*dmats0[4][8] + coeff0_5*dmats0[5][8] + coeff0_6*dmats0[6][8] + coeff0_7*dmats0[7][8] + coeff0_8*dmats0[8][8] + coeff0_9*dmats0[9][8];
+          new_coeff0_9 = coeff0_0*dmats0[0][9] + coeff0_1*dmats0[1][9] + coeff0_2*dmats0[2][9] + coeff0_3*dmats0[3][9] + coeff0_4*dmats0[4][9] + coeff0_5*dmats0[5][9] + coeff0_6*dmats0[6][9] + coeff0_7*dmats0[7][9] + coeff0_8*dmats0[8][9] + coeff0_9*dmats0[9][9];
+        }
+        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] + coeff0_6*dmats1[6][0] + coeff0_7*dmats1[7][0] + coeff0_8*dmats1[8][0] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][1] + coeff0_7*dmats1[7][1] + coeff0_8*dmats1[8][1] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][2] + coeff0_7*dmats1[7][2] + coeff0_8*dmats1[8][2] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][3] + coeff0_7*dmats1[7][3] + coeff0_8*dmats1[8][3] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][4] + coeff0_7*dmats1[7][4] + coeff0_8*dmats1[8][4] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][5] + coeff0_7*dmats1[7][5] + coeff0_8*dmats1[8][5] + coeff0_9*dmats1[9][5];
+          new_coeff0_6 = coeff0_0*dmats1[0][6] + coeff0_1*dmats1[1][6] + coeff0_2*dmats1[2][6] + coeff0_3*dmats1[3][6] + coeff0_4*dmats1[4][6] + coeff0_5*dmats1[5][6] + coeff0_6*dmats1[6][6] + coeff0_7*dmats1[7][6] + coeff0_8*dmats1[8][6] + coeff0_9*dmats1[9][6];
+          new_coeff0_7 = coeff0_0*dmats1[0][7] + coeff0_1*dmats1[1][7] + coeff0_2*dmats1[2][7] + coeff0_3*dmats1[3][7] + coeff0_4*dmats1[4][7] + coeff0_5*dmats1[5][7] + coeff0_6*dmats1[6][7] + coeff0_7*dmats1[7][7] + coeff0_8*dmats1[8][7] + coeff0_9*dmats1[9][7];
+          new_coeff0_8 = coeff0_0*dmats1[0][8] + coeff0_1*dmats1[1][8] + coeff0_2*dmats1[2][8] + coeff0_3*dmats1[3][8] + coeff0_4*dmats1[4][8] + coeff0_5*dmats1[5][8] + coeff0_6*dmats1[6][8] + coeff0_7*dmats1[7][8] + coeff0_8*dmats1[8][8] + coeff0_9*dmats1[9][8];
+          new_coeff0_9 = coeff0_0*dmats1[0][9] + coeff0_1*dmats1[1][9] + coeff0_2*dmats1[2][9] + coeff0_3*dmats1[3][9] + coeff0_4*dmats1[4][9] + coeff0_5*dmats1[5][9] + coeff0_6*dmats1[6][9] + coeff0_7*dmats1[7][9] + coeff0_8*dmats1[8][9] + coeff0_9*dmats1[9][9];
+        }
+        if(combinations[deriv_num][j] == 2)
+        {
+          new_coeff0_0 = coeff0_0*dmats2[0][0] + coeff0_1*dmats2[1][0] + coeff0_2*dmats2[2][0] + coeff0_3*dmats2[3][0] + coeff0_4*dmats2[4][0] + coeff0_5*dmats2[5][0] + coeff0_6*dmats2[6][0] + coeff0_7*dmats2[7][0] + coeff0_8*dmats2[8][0] + coeff0_9*dmats2[9][0];
+          new_coeff0_1 = coeff0_0*dmats2[0][1] + coeff0_1*dmats2[1][1] + coeff0_2*dmats2[2][1] + coeff0_3*dmats2[3][1] + coeff0_4*dmats2[4][1] + coeff0_5*dmats2[5][1] + coeff0_6*dmats2[6][1] + coeff0_7*dmats2[7][1] + coeff0_8*dmats2[8][1] + coeff0_9*dmats2[9][1];
+          new_coeff0_2 = coeff0_0*dmats2[0][2] + coeff0_1*dmats2[1][2] + coeff0_2*dmats2[2][2] + coeff0_3*dmats2[3][2] + coeff0_4*dmats2[4][2] + coeff0_5*dmats2[5][2] + coeff0_6*dmats2[6][2] + coeff0_7*dmats2[7][2] + coeff0_8*dmats2[8][2] + coeff0_9*dmats2[9][2];
+          new_coeff0_3 = coeff0_0*dmats2[0][3] + coeff0_1*dmats2[1][3] + coeff0_2*dmats2[2][3] + coeff0_3*dmats2[3][3] + coeff0_4*dmats2[4][3] + coeff0_5*dmats2[5][3] + coeff0_6*dmats2[6][3] + coeff0_7*dmats2[7][3] + coeff0_8*dmats2[8][3] + coeff0_9*dmats2[9][3];
+          new_coeff0_4 = coeff0_0*dmats2[0][4] + coeff0_1*dmats2[1][4] + coeff0_2*dmats2[2][4] + coeff0_3*dmats2[3][4] + coeff0_4*dmats2[4][4] + coeff0_5*dmats2[5][4] + coeff0_6*dmats2[6][4] + coeff0_7*dmats2[7][4] + coeff0_8*dmats2[8][4] + coeff0_9*dmats2[9][4];
+          new_coeff0_5 = coeff0_0*dmats2[0][5] + coeff0_1*dmats2[1][5] + coeff0_2*dmats2[2][5] + coeff0_3*dmats2[3][5] + coeff0_4*dmats2[4][5] + coeff0_5*dmats2[5][5] + coeff0_6*dmats2[6][5] + coeff0_7*dmats2[7][5] + coeff0_8*dmats2[8][5] + coeff0_9*dmats2[9][5];
+          new_coeff0_6 = coeff0_0*dmats2[0][6] + coeff0_1*dmats2[1][6] + coeff0_2*dmats2[2][6] + coeff0_3*dmats2[3][6] + coeff0_4*dmats2[4][6] + coeff0_5*dmats2[5][6] + coeff0_6*dmats2[6][6] + coeff0_7*dmats2[7][6] + coeff0_8*dmats2[8][6] + coeff0_9*dmats2[9][6];
+          new_coeff0_7 = coeff0_0*dmats2[0][7] + coeff0_1*dmats2[1][7] + coeff0_2*dmats2[2][7] + coeff0_3*dmats2[3][7] + coeff0_4*dmats2[4][7] + coeff0_5*dmats2[5][7] + coeff0_6*dmats2[6][7] + coeff0_7*dmats2[7][7] + coeff0_8*dmats2[8][7] + coeff0_9*dmats2[9][7];
+          new_coeff0_8 = coeff0_0*dmats2[0][8] + coeff0_1*dmats2[1][8] + coeff0_2*dmats2[2][8] + coeff0_3*dmats2[3][8] + coeff0_4*dmats2[4][8] + coeff0_5*dmats2[5][8] + coeff0_6*dmats2[6][8] + coeff0_7*dmats2[7][8] + coeff0_8*dmats2[8][8] + coeff0_9*dmats2[9][8];
+          new_coeff0_9 = coeff0_0*dmats2[0][9] + coeff0_1*dmats2[1][9] + coeff0_2*dmats2[2][9] + coeff0_3*dmats2[3][9] + coeff0_4*dmats2[4][9] + coeff0_5*dmats2[5][9] + coeff0_6*dmats2[6][9] + coeff0_7*dmats2[7][9] + coeff0_8*dmats2[8][9] + coeff0_9*dmats2[9][9];
+        }
+    
+      }
+      // 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 + new_coeff0_6*basisvalue6 + new_coeff0_7*basisvalue7 + new_coeff0_8*basisvalue8 + new_coeff0_9*basisvalue9;
+    }
+    
+    // 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 solitarywave3d_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 solitarywave3d_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[10][1][3] = {{{0, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 0, 1}}, {{0, 0.5, 0.5}}, {{0.5, 0, 0.5}}, {{0.5, 0.5, 0}}, {{0, 0, 0.5}}, {{0, 0.5, 0}}, {{0.5, 0, 0}}};
+    static const double W[10][1] = {{1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}};
+    static const double D[10][1][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] - X[i][0][2];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    const double w3 = X[i][0][2];
+    
+    // Compute affine mapping y = F(X)
+    double y[3];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0] + w3*x[3][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1] + w3*x[3][1];
+    y[2] = w0*x[0][2] + w1*x[1][2] + w2*x[2][2] + w3*x[3][2];
+    
+    // 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 solitarywave3d_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 solitarywave3d_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];
+    vertex_values[3] = dof_values[3];
+}
+
+/// Return the number of sub elements (for a mixed element)
+unsigned int solitarywave3d_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* solitarywave3d_1_finite_element_0_1::create_sub_element(unsigned int i) const
+{
+    return new solitarywave3d_1_finite_element_0_1();
+}
+
+
+/// Constructor
+solitarywave3d_1_finite_element_0::solitarywave3d_1_finite_element_0() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+solitarywave3d_1_finite_element_0::~solitarywave3d_1_finite_element_0()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* solitarywave3d_1_finite_element_0::signature() const
+{
+    return "MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) })";
+}
+
+/// Return the cell shape
+ufc::shape solitarywave3d_1_finite_element_0::cell_shape() const
+{
+    return ufc::tetrahedron;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int solitarywave3d_1_finite_element_0::space_dimension() const
+{
+    return 20;
+}
+
+/// Return the rank of the value space
+unsigned int solitarywave3d_1_finite_element_0::value_rank() const
+{
+    return 1;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int solitarywave3d_1_finite_element_0::value_dimension(unsigned int i) const
+{
+    return 2;
+}
+
+/// Evaluate basis function i at given point in cell
+void solitarywave3d_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_02 = element_coordinates[3][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];
+    const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
+    const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
+    const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
+    const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
+    
+    // Compute sub determinants
+    const double d00 = J_11*J_22 - J_12*J_21;
+    const double d01 = J_12*J_20 - J_10*J_22;
+    const double d02 = J_10*J_21 - J_11*J_20;
+    
+    const double d10 = J_02*J_21 - J_01*J_22;
+    const double d11 = J_00*J_22 - J_02*J_20;
+    const double d12 = J_01*J_20 - J_00*J_21;
+    
+    const double d20 = J_01*J_12 - J_02*J_11;
+    const double d21 = J_02*J_10 - J_00*J_12;
+    const double d22 = J_00*J_11 - J_01*J_10;
+    
+    // Compute determinant of Jacobian
+    double detJ = J_00*d00 + J_10*d10 + J_20*d20;
+    
+    // Compute inverse of Jacobian
+    
+    // Compute constants
+    const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
+                    + d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
+                    + d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
+    
+    const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
+                    + d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
+                    + d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
+    
+    const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
+                    + d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
+                    + d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
+    
+    // Get coordinates and map to the UFC reference element
+    double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
+    double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
+    double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
+    
+    // Map coordinates to the reference cube
+    if (std::abs(y + z - 1.0) < 1e-14)
+      x = 1.0;
+    else
+      x = -2.0 * x/(y + z - 1.0) - 1.0;
+    if (std::abs(z - 1.0) < 1e-14)
+      y = -1.0;
+    else
+      y = 2.0 * y/(1.0 - z) - 1.0;
+    z = 2.0 * z - 1.0;
+    
+    // Reset values
+    values[0] = 0;
+    values[1] = 0;
+    
+    if (0 <= i && i <= 9)
+    {
+      // 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);
+      const double scalings_z_0 = 1;
+      const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
+      const double scalings_z_2 = scalings_z_1*(0.5 - 0.5*z);
+    
+      // 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 psitilde_cs
+      const double psitilde_cs_00_0 = 1;
+      const double psitilde_cs_00_1 = 2*z + 1;
+      const double psitilde_cs_00_2 = 0.3125*psitilde_cs_00_1 + 1.875*z*psitilde_cs_00_1 - 0.5625*psitilde_cs_00_0;
+      const double psitilde_cs_01_0 = 1;
+      const double psitilde_cs_01_1 = 3*z + 2;
+      const double psitilde_cs_02_0 = 1;
+      const double psitilde_cs_10_0 = 1;
+      const double psitilde_cs_10_1 = 3*z + 2;
+      const double psitilde_cs_11_0 = 1;
+      const double psitilde_cs_20_0 = 1;
+    
+      // Compute basisvalues
+      const double basisvalue0 = 0.866025403784439*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
+      const double basisvalue1 = 2.73861278752583*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
+      const double basisvalue2 = 1.58113883008419*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
+      const double basisvalue3 = 1.11803398874989*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
+      const double basisvalue4 = 5.1234753829798*psitilde_a_2*scalings_y_2*psitilde_bs_2_0*scalings_z_2*psitilde_cs_20_0;
+      const double basisvalue5 = 3.96862696659689*psitilde_a_1*scalings_y_1*psitilde_bs_1_1*scalings_z_2*psitilde_cs_11_0;
+      const double basisvalue6 = 2.29128784747792*psitilde_a_0*scalings_y_0*psitilde_bs_0_2*scalings_z_2*psitilde_cs_02_0;
+      const double basisvalue7 = 3.24037034920393*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_1;
+      const double basisvalue8 = 1.87082869338697*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_1;
+      const double basisvalue9 = 1.3228756555323*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_2;
+    
+      // Table(s) of coefficients
+      static const double coefficients0[10][10] =   \
+      {{-0.0577350269189626, -0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, 0.0503952630678969, 0.0290957186981323, 0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
+      {-0.0577350269189625, 0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, -0.050395263067897, 0.0290957186981323, -0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
+      {-0.0577350269189625, 0, 0.0702728368926306, -0.0248451997499977, 0, 0, 0.0872871560943969, 0, -0.0475131096733199, 0.0167984210226323},
+      {-0.0577350269189626, 0, 0, 0.074535599249993, 0, 0, 0, 0, 0, 0.100790526135794},
+      {0.23094010767585, 0, 0.140545673785261, 0.0993807989999906, 0, 0, 0, 0, 0.1187827741833, -0.0671936840905293},
+      {0.230940107675851, 0.121716123890037, -0.0702728368926306, 0.0993807989999907, 0, 0, 0, 0.102868899974728, -0.0593913870916499, -0.0671936840905293},
+      {0.23094010767585, 0.121716123890037, 0.0702728368926307, -0.0993807989999907, 0, 0.100790526135794, -0.087287156094397, -0.0205737799949456, -0.01187827741833, 0.0167984210226323},
+      {0.23094010767585, -0.121716123890037, -0.0702728368926307, 0.0993807989999906, 0, 0, 0, -0.102868899974728, -0.0593913870916499, -0.0671936840905293},
+      {0.23094010767585, -0.121716123890037, 0.0702728368926306, -0.0993807989999906, 0, -0.100790526135794, -0.0872871560943969, 0.0205737799949456, -0.01187827741833, 0.0167984210226323},
+      {0.23094010767585, 0, -0.140545673785261, -0.0993807989999906, -0.130120009726471, 0, 0.0290957186981323, 0, 0.02375655483666, 0.0167984210226323}};
+    
+      // 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];
+      const double coeff0_6 =   coefficients0[dof][6];
+      const double coeff0_7 =   coefficients0[dof][7];
+      const double coeff0_8 =   coefficients0[dof][8];
+      const double coeff0_9 =   coefficients0[dof][9];
+    
+      // Compute value(s)
+      values[0] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5 + coeff0_6*basisvalue6 + coeff0_7*basisvalue7 + coeff0_8*basisvalue8 + coeff0_9*basisvalue9;
+    }
+    
+    if (10 <= i && i <= 19)
+    {
+      // Map degree of freedom to element degree of freedom
+      const unsigned int dof = i - 10;
+    
+      // 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);
+      const double scalings_z_0 = 1;
+      const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
+      const double scalings_z_2 = scalings_z_1*(0.5 - 0.5*z);
+    
+      // 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 psitilde_cs
+      const double psitilde_cs_00_0 = 1;
+      const double psitilde_cs_00_1 = 2*z + 1;
+      const double psitilde_cs_00_2 = 0.3125*psitilde_cs_00_1 + 1.875*z*psitilde_cs_00_1 - 0.5625*psitilde_cs_00_0;
+      const double psitilde_cs_01_0 = 1;
+      const double psitilde_cs_01_1 = 3*z + 2;
+      const double psitilde_cs_02_0 = 1;
+      const double psitilde_cs_10_0 = 1;
+      const double psitilde_cs_10_1 = 3*z + 2;
+      const double psitilde_cs_11_0 = 1;
+      const double psitilde_cs_20_0 = 1;
+    
+      // Compute basisvalues
+      const double basisvalue0 = 0.866025403784439*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
+      const double basisvalue1 = 2.73861278752583*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
+      const double basisvalue2 = 1.58113883008419*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
+      const double basisvalue3 = 1.11803398874989*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
+      const double basisvalue4 = 5.1234753829798*psitilde_a_2*scalings_y_2*psitilde_bs_2_0*scalings_z_2*psitilde_cs_20_0;
+      const double basisvalue5 = 3.96862696659689*psitilde_a_1*scalings_y_1*psitilde_bs_1_1*scalings_z_2*psitilde_cs_11_0;
+      const double basisvalue6 = 2.29128784747792*psitilde_a_0*scalings_y_0*psitilde_bs_0_2*scalings_z_2*psitilde_cs_02_0;
+      const double basisvalue7 = 3.24037034920393*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_1;
+      const double basisvalue8 = 1.87082869338697*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_1;
+      const double basisvalue9 = 1.3228756555323*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_2;
+    
+      // Table(s) of coefficients
+      static const double coefficients0[10][10] =   \
+      {{-0.0577350269189626, -0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, 0.0503952630678969, 0.0290957186981323, 0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
+      {-0.0577350269189625, 0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, -0.050395263067897, 0.0290957186981323, -0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
+      {-0.0577350269189625, 0, 0.0702728368926306, -0.0248451997499977, 0, 0, 0.0872871560943969, 0, -0.0475131096733199, 0.0167984210226323},
+      {-0.0577350269189626, 0, 0, 0.074535599249993, 0, 0, 0, 0, 0, 0.100790526135794},
+      {0.23094010767585, 0, 0.140545673785261, 0.0993807989999906, 0, 0, 0, 0, 0.1187827741833, -0.0671936840905293},
+      {0.230940107675851, 0.121716123890037, -0.0702728368926306, 0.0993807989999907, 0, 0, 0, 0.102868899974728, -0.0593913870916499, -0.0671936840905293},
+      {0.23094010767585, 0.121716123890037, 0.0702728368926307, -0.0993807989999907, 0, 0.100790526135794, -0.087287156094397, -0.0205737799949456, -0.01187827741833, 0.0167984210226323},
+      {0.23094010767585, -0.121716123890037, -0.0702728368926307, 0.0993807989999906, 0, 0, 0, -0.102868899974728, -0.0593913870916499, -0.0671936840905293},
+      {0.23094010767585, -0.121716123890037, 0.0702728368926306, -0.0993807989999906, 0, -0.100790526135794, -0.0872871560943969, 0.0205737799949456, -0.01187827741833, 0.0167984210226323},
+      {0.23094010767585, 0, -0.140545673785261, -0.0993807989999906, -0.130120009726471, 0, 0.0290957186981323, 0, 0.02375655483666, 0.0167984210226323}};
+    
+      // 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];
+      const double coeff0_6 =   coefficients0[dof][6];
+      const double coeff0_7 =   coefficients0[dof][7];
+      const double coeff0_8 =   coefficients0[dof][8];
+      const double coeff0_9 =   coefficients0[dof][9];
+    
+      // Compute value(s)
+      values[1] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5 + coeff0_6*basisvalue6 + coeff0_7*basisvalue7 + coeff0_8*basisvalue8 + coeff0_9*basisvalue9;
+    }
+    
+}
+
+/// Evaluate all basis functions at given point in cell
+void solitarywave3d_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 solitarywave3d_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_02 = element_coordinates[3][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];
+    const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
+    const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
+    const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
+    const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
+    
+    // Compute sub determinants
+    const double d00 = J_11*J_22 - J_12*J_21;
+    const double d01 = J_12*J_20 - J_10*J_22;
+    const double d02 = J_10*J_21 - J_11*J_20;
+    
+    const double d10 = J_02*J_21 - J_01*J_22;
+    const double d11 = J_00*J_22 - J_02*J_20;
+    const double d12 = J_01*J_20 - J_00*J_21;
+    
+    const double d20 = J_01*J_12 - J_02*J_11;
+    const double d21 = J_02*J_10 - J_00*J_12;
+    const double d22 = J_00*J_11 - J_01*J_10;
+    
+    // Compute determinant of Jacobian
+    double detJ = J_00*d00 + J_10*d10 + J_20*d20;
+    
+    // Compute inverse of Jacobian
+    
+    // Compute constants
+    const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
+                    + d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
+                    + d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
+    
+    const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
+                    + d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
+                    + d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
+    
+    const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
+                    + d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
+                    + d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
+    
+    // Get coordinates and map to the UFC reference element
+    double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
+    double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
+    double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
+    
+    // Map coordinates to the reference cube
+    if (std::abs(y + z - 1.0) < 1e-14)
+      x = 1.0;
+    else
+      x = -2.0 * x/(y + z - 1.0) - 1.0;
+    if (std::abs(z - 1.0) < 1e-14)
+      y = -1.0;
+    else
+      y = 2.0 * y/(1.0 - z) - 1.0;
+    z = 2.0 * z - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 3;
+    
+    
+    // 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 > 2)
+            combinations[row][col] = 0;
+          else
+          {
+            combinations[row][col] += 1;
+            break;
+          }
+        }
+      }
+    }
+    
+    // Compute inverse of Jacobian
+    const double Jinv[3][3] ={{d00 / detJ, d10 / detJ, d20 / detJ}, {d01 / detJ, d11 / detJ, d21 / detJ}, {d02 / detJ, d12 / detJ, d22 / 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 <= 9)
+    {
+      // 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);
+      const double scalings_z_0 = 1;
+      const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
+      const double scalings_z_2 = scalings_z_1*(0.5 - 0.5*z);
+    
+      // 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 psitilde_cs
+      const double psitilde_cs_00_0 = 1;
+      const double psitilde_cs_00_1 = 2*z + 1;
+      const double psitilde_cs_00_2 = 0.3125*psitilde_cs_00_1 + 1.875*z*psitilde_cs_00_1 - 0.5625*psitilde_cs_00_0;
+      const double psitilde_cs_01_0 = 1;
+      const double psitilde_cs_01_1 = 3*z + 2;
+      const double psitilde_cs_02_0 = 1;
+      const double psitilde_cs_10_0 = 1;
+      const double psitilde_cs_10_1 = 3*z + 2;
+      const double psitilde_cs_11_0 = 1;
+      const double psitilde_cs_20_0 = 1;
+    
+      // Compute basisvalues
+      const double basisvalue0 = 0.866025403784439*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
+      const double basisvalue1 = 2.73861278752583*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
+      const double basisvalue2 = 1.58113883008419*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
+      const double basisvalue3 = 1.11803398874989*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
+      const double basisvalue4 = 5.1234753829798*psitilde_a_2*scalings_y_2*psitilde_bs_2_0*scalings_z_2*psitilde_cs_20_0;
+      const double basisvalue5 = 3.96862696659689*psitilde_a_1*scalings_y_1*psitilde_bs_1_1*scalings_z_2*psitilde_cs_11_0;
+      const double basisvalue6 = 2.29128784747792*psitilde_a_0*scalings_y_0*psitilde_bs_0_2*scalings_z_2*psitilde_cs_02_0;
+      const double basisvalue7 = 3.24037034920393*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_1;
+      const double basisvalue8 = 1.87082869338697*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_1;
+      const double basisvalue9 = 1.3228756555323*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_2;
+    
+      // Table(s) of coefficients
+      static const double coefficients0[10][10] =   \
+      {{-0.0577350269189626, -0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, 0.0503952630678969, 0.0290957186981323, 0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
+      {-0.0577350269189625, 0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, -0.050395263067897, 0.0290957186981323, -0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
+      {-0.0577350269189625, 0, 0.0702728368926306, -0.0248451997499977, 0, 0, 0.0872871560943969, 0, -0.0475131096733199, 0.0167984210226323},
+      {-0.0577350269189626, 0, 0, 0.074535599249993, 0, 0, 0, 0, 0, 0.100790526135794},
+      {0.23094010767585, 0, 0.140545673785261, 0.0993807989999906, 0, 0, 0, 0, 0.1187827741833, -0.0671936840905293},
+      {0.230940107675851, 0.121716123890037, -0.0702728368926306, 0.0993807989999907, 0, 0, 0, 0.102868899974728, -0.0593913870916499, -0.0671936840905293},
+      {0.23094010767585, 0.121716123890037, 0.0702728368926307, -0.0993807989999907, 0, 0.100790526135794, -0.087287156094397, -0.0205737799949456, -0.01187827741833, 0.0167984210226323},
+      {0.23094010767585, -0.121716123890037, -0.0702728368926307, 0.0993807989999906, 0, 0, 0, -0.102868899974728, -0.0593913870916499, -0.0671936840905293},
+      {0.23094010767585, -0.121716123890037, 0.0702728368926306, -0.0993807989999906, 0, -0.100790526135794, -0.0872871560943969, 0.0205737799949456, -0.01187827741833, 0.0167984210226323},
+      {0.23094010767585, 0, -0.140545673785261, -0.0993807989999906, -0.130120009726471, 0, 0.0290957186981323, 0, 0.02375655483666, 0.0167984210226323}};
+    
+      // Interesting (new) part
+      // Tables of derivatives of the polynomial base (transpose)
+      static const double dmats0[10][10] =   \
+      {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+      {6.32455532033676, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+      {0, 11.2249721603218, 0, 0, 0, 0, 0, 0, 0, 0},
+      {4.58257569495584, 0, 8.36660026534076, -1.18321595661992, 0, 0, 0, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+      {3.74165738677394, 0, 0, 8.69482604771366, 0, 0, 0, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
+    
+      static const double dmats1[10][10] =   \
+      {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+      {3.16227766016838, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+      {5.47722557505166, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+      {2.95803989154981, 5.61248608016091, -1.08012344973464, -0.763762615825974, 0, 0, 0, 0, 0, 0},
+      {2.29128784747792, 7.24568837309472, 4.18330013267038, -0.591607978309962, 0, 0, 0, 0, 0, 0},
+      {-2.64575131106459, 0, 9.66091783079296, 0.683130051063974, 0, 0, 0, 0, 0, 0},
+      {1.87082869338697, 0, 0, 4.34741302385683, 0, 0, 0, 0, 0, 0},
+      {3.24037034920393, 0, 0, 7.52994023880668, 0, 0, 0, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
+    
+      static const double dmats2[10][10] =   \
+      {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+      {3.16227766016838, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+      {1.82574185835055, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+      {5.16397779494322, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+      {2.95803989154981, 5.61248608016091, -1.08012344973464, -0.763762615825974, 0, 0, 0, 0, 0, 0},
+      {2.29128784747792, 1.44913767461894, 4.18330013267038, -0.591607978309962, 0, 0, 0, 0, 0, 0},
+      {1.32287565553229, 0, 3.86436713231718, -0.341565025531986, 0, 0, 0, 0, 0, 0},
+      {1.87082869338697, 7.09929573971954, 0, 4.34741302385683, 0, 0, 0, 0, 0, 0},
+      {1.08012344973464, 0, 7.09929573971954, 2.50998007960223, 0, 0, 0, 0, 0, 0},
+      {-3.81881307912987, 0, 0, 8.87411967464942, 0, 0, 0, 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;
+      double coeff0_6 = 0;
+      double coeff0_7 = 0;
+      double coeff0_8 = 0;
+      double coeff0_9 = 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;
+      double new_coeff0_6 = 0;
+      double new_coeff0_7 = 0;
+      double new_coeff0_8 = 0;
+      double new_coeff0_9 = 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];
+        new_coeff0_6 = coefficients0[dof][6];
+        new_coeff0_7 = coefficients0[dof][7];
+        new_coeff0_8 = coefficients0[dof][8];
+        new_coeff0_9 = coefficients0[dof][9];
+    
+        // 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;
+          coeff0_6 = new_coeff0_6;
+          coeff0_7 = new_coeff0_7;
+          coeff0_8 = new_coeff0_8;
+          coeff0_9 = new_coeff0_9;
+    
+          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] + coeff0_6*dmats0[6][0] + coeff0_7*dmats0[7][0] + coeff0_8*dmats0[8][0] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][1] + coeff0_7*dmats0[7][1] + coeff0_8*dmats0[8][1] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][2] + coeff0_7*dmats0[7][2] + coeff0_8*dmats0[8][2] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][3] + coeff0_7*dmats0[7][3] + coeff0_8*dmats0[8][3] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][4] + coeff0_7*dmats0[7][4] + coeff0_8*dmats0[8][4] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][5] + coeff0_7*dmats0[7][5] + coeff0_8*dmats0[8][5] + coeff0_9*dmats0[9][5];
+            new_coeff0_6 = coeff0_0*dmats0[0][6] + coeff0_1*dmats0[1][6] + coeff0_2*dmats0[2][6] + coeff0_3*dmats0[3][6] + coeff0_4*dmats0[4][6] + coeff0_5*dmats0[5][6] + coeff0_6*dmats0[6][6] + coeff0_7*dmats0[7][6] + coeff0_8*dmats0[8][6] + coeff0_9*dmats0[9][6];
+            new_coeff0_7 = coeff0_0*dmats0[0][7] + coeff0_1*dmats0[1][7] + coeff0_2*dmats0[2][7] + coeff0_3*dmats0[3][7] + coeff0_4*dmats0[4][7] + coeff0_5*dmats0[5][7] + coeff0_6*dmats0[6][7] + coeff0_7*dmats0[7][7] + coeff0_8*dmats0[8][7] + coeff0_9*dmats0[9][7];
+            new_coeff0_8 = coeff0_0*dmats0[0][8] + coeff0_1*dmats0[1][8] + coeff0_2*dmats0[2][8] + coeff0_3*dmats0[3][8] + coeff0_4*dmats0[4][8] + coeff0_5*dmats0[5][8] + coeff0_6*dmats0[6][8] + coeff0_7*dmats0[7][8] + coeff0_8*dmats0[8][8] + coeff0_9*dmats0[9][8];
+            new_coeff0_9 = coeff0_0*dmats0[0][9] + coeff0_1*dmats0[1][9] + coeff0_2*dmats0[2][9] + coeff0_3*dmats0[3][9] + coeff0_4*dmats0[4][9] + coeff0_5*dmats0[5][9] + coeff0_6*dmats0[6][9] + coeff0_7*dmats0[7][9] + coeff0_8*dmats0[8][9] + coeff0_9*dmats0[9][9];
+          }
+          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] + coeff0_6*dmats1[6][0] + coeff0_7*dmats1[7][0] + coeff0_8*dmats1[8][0] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][1] + coeff0_7*dmats1[7][1] + coeff0_8*dmats1[8][1] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][2] + coeff0_7*dmats1[7][2] + coeff0_8*dmats1[8][2] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][3] + coeff0_7*dmats1[7][3] + coeff0_8*dmats1[8][3] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][4] + coeff0_7*dmats1[7][4] + coeff0_8*dmats1[8][4] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][5] + coeff0_7*dmats1[7][5] + coeff0_8*dmats1[8][5] + coeff0_9*dmats1[9][5];
+            new_coeff0_6 = coeff0_0*dmats1[0][6] + coeff0_1*dmats1[1][6] + coeff0_2*dmats1[2][6] + coeff0_3*dmats1[3][6] + coeff0_4*dmats1[4][6] + coeff0_5*dmats1[5][6] + coeff0_6*dmats1[6][6] + coeff0_7*dmats1[7][6] + coeff0_8*dmats1[8][6] + coeff0_9*dmats1[9][6];
+            new_coeff0_7 = coeff0_0*dmats1[0][7] + coeff0_1*dmats1[1][7] + coeff0_2*dmats1[2][7] + coeff0_3*dmats1[3][7] + coeff0_4*dmats1[4][7] + coeff0_5*dmats1[5][7] + coeff0_6*dmats1[6][7] + coeff0_7*dmats1[7][7] + coeff0_8*dmats1[8][7] + coeff0_9*dmats1[9][7];
+            new_coeff0_8 = coeff0_0*dmats1[0][8] + coeff0_1*dmats1[1][8] + coeff0_2*dmats1[2][8] + coeff0_3*dmats1[3][8] + coeff0_4*dmats1[4][8] + coeff0_5*dmats1[5][8] + coeff0_6*dmats1[6][8] + coeff0_7*dmats1[7][8] + coeff0_8*dmats1[8][8] + coeff0_9*dmats1[9][8];
+            new_coeff0_9 = coeff0_0*dmats1[0][9] + coeff0_1*dmats1[1][9] + coeff0_2*dmats1[2][9] + coeff0_3*dmats1[3][9] + coeff0_4*dmats1[4][9] + coeff0_5*dmats1[5][9] + coeff0_6*dmats1[6][9] + coeff0_7*dmats1[7][9] + coeff0_8*dmats1[8][9] + coeff0_9*dmats1[9][9];
+          }
+          if(combinations[deriv_num][j] == 2)
+          {
+            new_coeff0_0 = coeff0_0*dmats2[0][0] + coeff0_1*dmats2[1][0] + coeff0_2*dmats2[2][0] + coeff0_3*dmats2[3][0] + coeff0_4*dmats2[4][0] + coeff0_5*dmats2[5][0] + coeff0_6*dmats2[6][0] + coeff0_7*dmats2[7][0] + coeff0_8*dmats2[8][0] + coeff0_9*dmats2[9][0];
+            new_coeff0_1 = coeff0_0*dmats2[0][1] + coeff0_1*dmats2[1][1] + coeff0_2*dmats2[2][1] + coeff0_3*dmats2[3][1] + coeff0_4*dmats2[4][1] + coeff0_5*dmats2[5][1] + coeff0_6*dmats2[6][1] + coeff0_7*dmats2[7][1] + coeff0_8*dmats2[8][1] + coeff0_9*dmats2[9][1];
+            new_coeff0_2 = coeff0_0*dmats2[0][2] + coeff0_1*dmats2[1][2] + coeff0_2*dmats2[2][2] + coeff0_3*dmats2[3][2] + coeff0_4*dmats2[4][2] + coeff0_5*dmats2[5][2] + coeff0_6*dmats2[6][2] + coeff0_7*dmats2[7][2] + coeff0_8*dmats2[8][2] + coeff0_9*dmats2[9][2];
+            new_coeff0_3 = coeff0_0*dmats2[0][3] + coeff0_1*dmats2[1][3] + coeff0_2*dmats2[2][3] + coeff0_3*dmats2[3][3] + coeff0_4*dmats2[4][3] + coeff0_5*dmats2[5][3] + coeff0_6*dmats2[6][3] + coeff0_7*dmats2[7][3] + coeff0_8*dmats2[8][3] + coeff0_9*dmats2[9][3];
+            new_coeff0_4 = coeff0_0*dmats2[0][4] + coeff0_1*dmats2[1][4] + coeff0_2*dmats2[2][4] + coeff0_3*dmats2[3][4] + coeff0_4*dmats2[4][4] + coeff0_5*dmats2[5][4] + coeff0_6*dmats2[6][4] + coeff0_7*dmats2[7][4] + coeff0_8*dmats2[8][4] + coeff0_9*dmats2[9][4];
+            new_coeff0_5 = coeff0_0*dmats2[0][5] + coeff0_1*dmats2[1][5] + coeff0_2*dmats2[2][5] + coeff0_3*dmats2[3][5] + coeff0_4*dmats2[4][5] + coeff0_5*dmats2[5][5] + coeff0_6*dmats2[6][5] + coeff0_7*dmats2[7][5] + coeff0_8*dmats2[8][5] + coeff0_9*dmats2[9][5];
+            new_coeff0_6 = coeff0_0*dmats2[0][6] + coeff0_1*dmats2[1][6] + coeff0_2*dmats2[2][6] + coeff0_3*dmats2[3][6] + coeff0_4*dmats2[4][6] + coeff0_5*dmats2[5][6] + coeff0_6*dmats2[6][6] + coeff0_7*dmats2[7][6] + coeff0_8*dmats2[8][6] + coeff0_9*dmats2[9][6];
+            new_coeff0_7 = coeff0_0*dmats2[0][7] + coeff0_1*dmats2[1][7] + coeff0_2*dmats2[2][7] + coeff0_3*dmats2[3][7] + coeff0_4*dmats2[4][7] + coeff0_5*dmats2[5][7] + coeff0_6*dmats2[6][7] + coeff0_7*dmats2[7][7] + coeff0_8*dmats2[8][7] + coeff0_9*dmats2[9][7];
+            new_coeff0_8 = coeff0_0*dmats2[0][8] + coeff0_1*dmats2[1][8] + coeff0_2*dmats2[2][8] + coeff0_3*dmats2[3][8] + coeff0_4*dmats2[4][8] + coeff0_5*dmats2[5][8] + coeff0_6*dmats2[6][8] + coeff0_7*dmats2[7][8] + coeff0_8*dmats2[8][8] + coeff0_9*dmats2[9][8];
+            new_coeff0_9 = coeff0_0*dmats2[0][9] + coeff0_1*dmats2[1][9] + coeff0_2*dmats2[2][9] + coeff0_3*dmats2[3][9] + coeff0_4*dmats2[4][9] + coeff0_5*dmats2[5][9] + coeff0_6*dmats2[6][9] + coeff0_7*dmats2[7][9] + coeff0_8*dmats2[8][9] + coeff0_9*dmats2[9][9];
+          }
+    
+        }
+        // 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 + new_coeff0_6*basisvalue6 + new_coeff0_7*basisvalue7 + new_coeff0_8*basisvalue8 + new_coeff0_9*basisvalue9;
+      }
+    
+      // 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 (10 <= i && i <= 19)
+    {
+      // Map degree of freedom to element degree of freedom
+      const unsigned int dof = i - 10;
+    
+      // 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);
+      const double scalings_z_0 = 1;
+      const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
+      const double scalings_z_2 = scalings_z_1*(0.5 - 0.5*z);
+    
+      // 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 psitilde_cs
+      const double psitilde_cs_00_0 = 1;
+      const double psitilde_cs_00_1 = 2*z + 1;
+      const double psitilde_cs_00_2 = 0.3125*psitilde_cs_00_1 + 1.875*z*psitilde_cs_00_1 - 0.5625*psitilde_cs_00_0;
+      const double psitilde_cs_01_0 = 1;
+      const double psitilde_cs_01_1 = 3*z + 2;
+      const double psitilde_cs_02_0 = 1;
+      const double psitilde_cs_10_0 = 1;
+      const double psitilde_cs_10_1 = 3*z + 2;
+      const double psitilde_cs_11_0 = 1;
+      const double psitilde_cs_20_0 = 1;
+    
+      // Compute basisvalues
+      const double basisvalue0 = 0.866025403784439*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
+      const double basisvalue1 = 2.73861278752583*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
+      const double basisvalue2 = 1.58113883008419*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
+      const double basisvalue3 = 1.11803398874989*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
+      const double basisvalue4 = 5.1234753829798*psitilde_a_2*scalings_y_2*psitilde_bs_2_0*scalings_z_2*psitilde_cs_20_0;
+      const double basisvalue5 = 3.96862696659689*psitilde_a_1*scalings_y_1*psitilde_bs_1_1*scalings_z_2*psitilde_cs_11_0;
+      const double basisvalue6 = 2.29128784747792*psitilde_a_0*scalings_y_0*psitilde_bs_0_2*scalings_z_2*psitilde_cs_02_0;
+      const double basisvalue7 = 3.24037034920393*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_1;
+      const double basisvalue8 = 1.87082869338697*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_1;
+      const double basisvalue9 = 1.3228756555323*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_2;
+    
+      // Table(s) of coefficients
+      static const double coefficients0[10][10] =   \
+      {{-0.0577350269189626, -0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, 0.0503952630678969, 0.0290957186981323, 0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
+      {-0.0577350269189625, 0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, -0.050395263067897, 0.0290957186981323, -0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
+      {-0.0577350269189625, 0, 0.0702728368926306, -0.0248451997499977, 0, 0, 0.0872871560943969, 0, -0.0475131096733199, 0.0167984210226323},
+      {-0.0577350269189626, 0, 0, 0.074535599249993, 0, 0, 0, 0, 0, 0.100790526135794},
+      {0.23094010767585, 0, 0.140545673785261, 0.0993807989999906, 0, 0, 0, 0, 0.1187827741833, -0.0671936840905293},
+      {0.230940107675851, 0.121716123890037, -0.0702728368926306, 0.0993807989999907, 0, 0, 0, 0.102868899974728, -0.0593913870916499, -0.0671936840905293},
+      {0.23094010767585, 0.121716123890037, 0.0702728368926307, -0.0993807989999907, 0, 0.100790526135794, -0.087287156094397, -0.0205737799949456, -0.01187827741833, 0.0167984210226323},
+      {0.23094010767585, -0.121716123890037, -0.0702728368926307, 0.0993807989999906, 0, 0, 0, -0.102868899974728, -0.0593913870916499, -0.0671936840905293},
+      {0.23094010767585, -0.121716123890037, 0.0702728368926306, -0.0993807989999906, 0, -0.100790526135794, -0.0872871560943969, 0.0205737799949456, -0.01187827741833, 0.0167984210226323},
+      {0.23094010767585, 0, -0.140545673785261, -0.0993807989999906, -0.130120009726471, 0, 0.0290957186981323, 0, 0.02375655483666, 0.0167984210226323}};
+    
+      // Interesting (new) part
+      // Tables of derivatives of the polynomial base (transpose)
+      static const double dmats0[10][10] =   \
+      {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+      {6.32455532033676, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+      {0, 11.2249721603218, 0, 0, 0, 0, 0, 0, 0, 0},
+      {4.58257569495584, 0, 8.36660026534076, -1.18321595661992, 0, 0, 0, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+      {3.74165738677394, 0, 0, 8.69482604771366, 0, 0, 0, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
+    
+      static const double dmats1[10][10] =   \
+      {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+      {3.16227766016838, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+      {5.47722557505166, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+      {2.95803989154981, 5.61248608016091, -1.08012344973464, -0.763762615825974, 0, 0, 0, 0, 0, 0},
+      {2.29128784747792, 7.24568837309472, 4.18330013267038, -0.591607978309962, 0, 0, 0, 0, 0, 0},
+      {-2.64575131106459, 0, 9.66091783079296, 0.683130051063974, 0, 0, 0, 0, 0, 0},
+      {1.87082869338697, 0, 0, 4.34741302385683, 0, 0, 0, 0, 0, 0},
+      {3.24037034920393, 0, 0, 7.52994023880668, 0, 0, 0, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
+    
+      static const double dmats2[10][10] =   \
+      {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+      {3.16227766016838, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+      {1.82574185835055, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+      {5.16397779494322, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+      {2.95803989154981, 5.61248608016091, -1.08012344973464, -0.763762615825974, 0, 0, 0, 0, 0, 0},
+      {2.29128784747792, 1.44913767461894, 4.18330013267038, -0.591607978309962, 0, 0, 0, 0, 0, 0},
+      {1.32287565553229, 0, 3.86436713231718, -0.341565025531986, 0, 0, 0, 0, 0, 0},
+      {1.87082869338697, 7.09929573971954, 0, 4.34741302385683, 0, 0, 0, 0, 0, 0},
+      {1.08012344973464, 0, 7.09929573971954, 2.50998007960223, 0, 0, 0, 0, 0, 0},
+      {-3.81881307912987, 0, 0, 8.87411967464942, 0, 0, 0, 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;
+      double coeff0_6 = 0;
+      double coeff0_7 = 0;
+      double coeff0_8 = 0;
+      double coeff0_9 = 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;
+      double new_coeff0_6 = 0;
+      double new_coeff0_7 = 0;
+      double new_coeff0_8 = 0;
+      double new_coeff0_9 = 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];
+        new_coeff0_6 = coefficients0[dof][6];
+        new_coeff0_7 = coefficients0[dof][7];
+        new_coeff0_8 = coefficients0[dof][8];
+        new_coeff0_9 = coefficients0[dof][9];
+    
+        // 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;
+          coeff0_6 = new_coeff0_6;
+          coeff0_7 = new_coeff0_7;
+          coeff0_8 = new_coeff0_8;
+          coeff0_9 = new_coeff0_9;
+    
+          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] + coeff0_6*dmats0[6][0] + coeff0_7*dmats0[7][0] + coeff0_8*dmats0[8][0] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][1] + coeff0_7*dmats0[7][1] + coeff0_8*dmats0[8][1] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][2] + coeff0_7*dmats0[7][2] + coeff0_8*dmats0[8][2] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][3] + coeff0_7*dmats0[7][3] + coeff0_8*dmats0[8][3] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][4] + coeff0_7*dmats0[7][4] + coeff0_8*dmats0[8][4] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][5] + coeff0_7*dmats0[7][5] + coeff0_8*dmats0[8][5] + coeff0_9*dmats0[9][5];
+            new_coeff0_6 = coeff0_0*dmats0[0][6] + coeff0_1*dmats0[1][6] + coeff0_2*dmats0[2][6] + coeff0_3*dmats0[3][6] + coeff0_4*dmats0[4][6] + coeff0_5*dmats0[5][6] + coeff0_6*dmats0[6][6] + coeff0_7*dmats0[7][6] + coeff0_8*dmats0[8][6] + coeff0_9*dmats0[9][6];
+            new_coeff0_7 = coeff0_0*dmats0[0][7] + coeff0_1*dmats0[1][7] + coeff0_2*dmats0[2][7] + coeff0_3*dmats0[3][7] + coeff0_4*dmats0[4][7] + coeff0_5*dmats0[5][7] + coeff0_6*dmats0[6][7] + coeff0_7*dmats0[7][7] + coeff0_8*dmats0[8][7] + coeff0_9*dmats0[9][7];
+            new_coeff0_8 = coeff0_0*dmats0[0][8] + coeff0_1*dmats0[1][8] + coeff0_2*dmats0[2][8] + coeff0_3*dmats0[3][8] + coeff0_4*dmats0[4][8] + coeff0_5*dmats0[5][8] + coeff0_6*dmats0[6][8] + coeff0_7*dmats0[7][8] + coeff0_8*dmats0[8][8] + coeff0_9*dmats0[9][8];
+            new_coeff0_9 = coeff0_0*dmats0[0][9] + coeff0_1*dmats0[1][9] + coeff0_2*dmats0[2][9] + coeff0_3*dmats0[3][9] + coeff0_4*dmats0[4][9] + coeff0_5*dmats0[5][9] + coeff0_6*dmats0[6][9] + coeff0_7*dmats0[7][9] + coeff0_8*dmats0[8][9] + coeff0_9*dmats0[9][9];
+          }
+          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] + coeff0_6*dmats1[6][0] + coeff0_7*dmats1[7][0] + coeff0_8*dmats1[8][0] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][1] + coeff0_7*dmats1[7][1] + coeff0_8*dmats1[8][1] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][2] + coeff0_7*dmats1[7][2] + coeff0_8*dmats1[8][2] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][3] + coeff0_7*dmats1[7][3] + coeff0_8*dmats1[8][3] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][4] + coeff0_7*dmats1[7][4] + coeff0_8*dmats1[8][4] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][5] + coeff0_7*dmats1[7][5] + coeff0_8*dmats1[8][5] + coeff0_9*dmats1[9][5];
+            new_coeff0_6 = coeff0_0*dmats1[0][6] + coeff0_1*dmats1[1][6] + coeff0_2*dmats1[2][6] + coeff0_3*dmats1[3][6] + coeff0_4*dmats1[4][6] + coeff0_5*dmats1[5][6] + coeff0_6*dmats1[6][6] + coeff0_7*dmats1[7][6] + coeff0_8*dmats1[8][6] + coeff0_9*dmats1[9][6];
+            new_coeff0_7 = coeff0_0*dmats1[0][7] + coeff0_1*dmats1[1][7] + coeff0_2*dmats1[2][7] + coeff0_3*dmats1[3][7] + coeff0_4*dmats1[4][7] + coeff0_5*dmats1[5][7] + coeff0_6*dmats1[6][7] + coeff0_7*dmats1[7][7] + coeff0_8*dmats1[8][7] + coeff0_9*dmats1[9][7];
+            new_coeff0_8 = coeff0_0*dmats1[0][8] + coeff0_1*dmats1[1][8] + coeff0_2*dmats1[2][8] + coeff0_3*dmats1[3][8] + coeff0_4*dmats1[4][8] + coeff0_5*dmats1[5][8] + coeff0_6*dmats1[6][8] + coeff0_7*dmats1[7][8] + coeff0_8*dmats1[8][8] + coeff0_9*dmats1[9][8];
+            new_coeff0_9 = coeff0_0*dmats1[0][9] + coeff0_1*dmats1[1][9] + coeff0_2*dmats1[2][9] + coeff0_3*dmats1[3][9] + coeff0_4*dmats1[4][9] + coeff0_5*dmats1[5][9] + coeff0_6*dmats1[6][9] + coeff0_7*dmats1[7][9] + coeff0_8*dmats1[8][9] + coeff0_9*dmats1[9][9];
+          }
+          if(combinations[deriv_num][j] == 2)
+          {
+            new_coeff0_0 = coeff0_0*dmats2[0][0] + coeff0_1*dmats2[1][0] + coeff0_2*dmats2[2][0] + coeff0_3*dmats2[3][0] + coeff0_4*dmats2[4][0] + coeff0_5*dmats2[5][0] + coeff0_6*dmats2[6][0] + coeff0_7*dmats2[7][0] + coeff0_8*dmats2[8][0] + coeff0_9*dmats2[9][0];
+            new_coeff0_1 = coeff0_0*dmats2[0][1] + coeff0_1*dmats2[1][1] + coeff0_2*dmats2[2][1] + coeff0_3*dmats2[3][1] + coeff0_4*dmats2[4][1] + coeff0_5*dmats2[5][1] + coeff0_6*dmats2[6][1] + coeff0_7*dmats2[7][1] + coeff0_8*dmats2[8][1] + coeff0_9*dmats2[9][1];
+            new_coeff0_2 = coeff0_0*dmats2[0][2] + coeff0_1*dmats2[1][2] + coeff0_2*dmats2[2][2] + coeff0_3*dmats2[3][2] + coeff0_4*dmats2[4][2] + coeff0_5*dmats2[5][2] + coeff0_6*dmats2[6][2] + coeff0_7*dmats2[7][2] + coeff0_8*dmats2[8][2] + coeff0_9*dmats2[9][2];
+            new_coeff0_3 = coeff0_0*dmats2[0][3] + coeff0_1*dmats2[1][3] + coeff0_2*dmats2[2][3] + coeff0_3*dmats2[3][3] + coeff0_4*dmats2[4][3] + coeff0_5*dmats2[5][3] + coeff0_6*dmats2[6][3] + coeff0_7*dmats2[7][3] + coeff0_8*dmats2[8][3] + coeff0_9*dmats2[9][3];
+            new_coeff0_4 = coeff0_0*dmats2[0][4] + coeff0_1*dmats2[1][4] + coeff0_2*dmats2[2][4] + coeff0_3*dmats2[3][4] + coeff0_4*dmats2[4][4] + coeff0_5*dmats2[5][4] + coeff0_6*dmats2[6][4] + coeff0_7*dmats2[7][4] + coeff0_8*dmats2[8][4] + coeff0_9*dmats2[9][4];
+            new_coeff0_5 = coeff0_0*dmats2[0][5] + coeff0_1*dmats2[1][5] + coeff0_2*dmats2[2][5] + coeff0_3*dmats2[3][5] + coeff0_4*dmats2[4][5] + coeff0_5*dmats2[5][5] + coeff0_6*dmats2[6][5] + coeff0_7*dmats2[7][5] + coeff0_8*dmats2[8][5] + coeff0_9*dmats2[9][5];
+            new_coeff0_6 = coeff0_0*dmats2[0][6] + coeff0_1*dmats2[1][6] + coeff0_2*dmats2[2][6] + coeff0_3*dmats2[3][6] + coeff0_4*dmats2[4][6] + coeff0_5*dmats2[5][6] + coeff0_6*dmats2[6][6] + coeff0_7*dmats2[7][6] + coeff0_8*dmats2[8][6] + coeff0_9*dmats2[9][6];
+            new_coeff0_7 = coeff0_0*dmats2[0][7] + coeff0_1*dmats2[1][7] + coeff0_2*dmats2[2][7] + coeff0_3*dmats2[3][7] + coeff0_4*dmats2[4][7] + coeff0_5*dmats2[5][7] + coeff0_6*dmats2[6][7] + coeff0_7*dmats2[7][7] + coeff0_8*dmats2[8][7] + coeff0_9*dmats2[9][7];
+            new_coeff0_8 = coeff0_0*dmats2[0][8] + coeff0_1*dmats2[1][8] + coeff0_2*dmats2[2][8] + coeff0_3*dmats2[3][8] + coeff0_4*dmats2[4][8] + coeff0_5*dmats2[5][8] + coeff0_6*dmats2[6][8] + coeff0_7*dmats2[7][8] + coeff0_8*dmats2[8][8] + coeff0_9*dmats2[9][8];
+            new_coeff0_9 = coeff0_0*dmats2[0][9] + coeff0_1*dmats2[1][9] + coeff0_2*dmats2[2][9] + coeff0_3*dmats2[3][9] + coeff0_4*dmats2[4][9] + coeff0_5*dmats2[5][9] + coeff0_6*dmats2[6][9] + coeff0_7*dmats2[7][9] + coeff0_8*dmats2[8][9] + coeff0_9*dmats2[9][9];
+          }
+    
+        }
+        // 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 + new_coeff0_6*basisvalue6 + new_coeff0_7*basisvalue7 + new_coeff0_8*basisvalue8 + new_coeff0_9*basisvalue9;
+      }
+    
+      // 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 solitarywave3d_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 solitarywave3d_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[20][1][3] = {{{0, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 0, 1}}, {{0, 0.5, 0.5}}, {{0.5, 0, 0.5}}, {{0.5, 0.5, 0}}, {{0, 0, 0.5}}, {{0, 0.5, 0}}, {{0.5, 0, 0}}, {{0, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 0, 1}}, {{0, 0.5, 0.5}}, {{0.5, 0, 0.5}}, {{0.5, 0.5, 0}}, {{0, 0, 0.5}}, {{0, 0.5, 0}}, {{0.5, 0, 0}}};
+    static const double W[20][1] = {{1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}};
+    static const double D[20][1][2] = {{{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{0, 1}}, {{0, 1}}, {{0, 1}}, {{0, 1}}, {{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] - X[i][0][2];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    const double w3 = X[i][0][2];
+    
+    // Compute affine mapping y = F(X)
+    double y[3];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0] + w3*x[3][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1] + w3*x[3][1];
+    y[2] = w0*x[0][2] + w1*x[1][2] + w2*x[2][2] + w3*x[3][2];
+    
+    // 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 solitarywave3d_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 solitarywave3d_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];
+    vertex_values[6] = dof_values[3];
+    // Evaluate at vertices and use affine mapping
+    vertex_values[1] = dof_values[10];
+    vertex_values[3] = dof_values[11];
+    vertex_values[5] = dof_values[12];
+    vertex_values[7] = dof_values[13];
+}
+
+/// Return the number of sub elements (for a mixed element)
+unsigned int solitarywave3d_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* solitarywave3d_1_finite_element_0::create_sub_element(unsigned int i) const
+{
+    switch ( i )
+    {
+    case 0:
+      return new solitarywave3d_1_finite_element_0_0();
+      break;
+    case 1:
+      return new solitarywave3d_1_finite_element_0_1();
+      break;
+    }
+    return 0;
+}
+
+
+/// Constructor
+solitarywave3d_1_finite_element_1_0::solitarywave3d_1_finite_element_1_0() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+solitarywave3d_1_finite_element_1_0::~solitarywave3d_1_finite_element_1_0()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* solitarywave3d_1_finite_element_1_0::signature() const
+{
+    return "FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)";
+}
+
+/// Return the cell shape
+ufc::shape solitarywave3d_1_finite_element_1_0::cell_shape() const
+{
+    return ufc::tetrahedron;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int solitarywave3d_1_finite_element_1_0::space_dimension() const
+{
+    return 10;
+}
+
+/// Return the rank of the value space
+unsigned int solitarywave3d_1_finite_element_1_0::value_rank() const
+{
+    return 0;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int solitarywave3d_1_finite_element_1_0::value_dimension(unsigned int i) const
+{
+    return 1;
+}
+
+/// Evaluate basis function i at given point in cell
+void solitarywave3d_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_02 = element_coordinates[3][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];
+    const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
+    const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
+    const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
+    const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
+    
+    // Compute sub determinants
+    const double d00 = J_11*J_22 - J_12*J_21;
+    const double d01 = J_12*J_20 - J_10*J_22;
+    const double d02 = J_10*J_21 - J_11*J_20;
+    
+    const double d10 = J_02*J_21 - J_01*J_22;
+    const double d11 = J_00*J_22 - J_02*J_20;
+    const double d12 = J_01*J_20 - J_00*J_21;
+    
+    const double d20 = J_01*J_12 - J_02*J_11;
+    const double d21 = J_02*J_10 - J_00*J_12;
+    const double d22 = J_00*J_11 - J_01*J_10;
+    
+    // Compute determinant of Jacobian
+    double detJ = J_00*d00 + J_10*d10 + J_20*d20;
+    
+    // Compute inverse of Jacobian
+    
+    // Compute constants
+    const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
+                    + d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
+                    + d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
+    
+    const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
+                    + d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
+                    + d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
+    
+    const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
+                    + d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
+                    + d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
+    
+    // Get coordinates and map to the UFC reference element
+    double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
+    double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
+    double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
+    
+    // Map coordinates to the reference cube
+    if (std::abs(y + z - 1.0) < 1e-14)
+      x = 1.0;
+    else
+      x = -2.0 * x/(y + z - 1.0) - 1.0;
+    if (std::abs(z - 1.0) < 1e-14)
+      y = -1.0;
+    else
+      y = 2.0 * y/(1.0 - z) - 1.0;
+    z = 2.0 * z - 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);
+    const double scalings_z_0 = 1;
+    const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
+    const double scalings_z_2 = scalings_z_1*(0.5 - 0.5*z);
+    
+    // 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 psitilde_cs
+    const double psitilde_cs_00_0 = 1;
+    const double psitilde_cs_00_1 = 2*z + 1;
+    const double psitilde_cs_00_2 = 0.3125*psitilde_cs_00_1 + 1.875*z*psitilde_cs_00_1 - 0.5625*psitilde_cs_00_0;
+    const double psitilde_cs_01_0 = 1;
+    const double psitilde_cs_01_1 = 3*z + 2;
+    const double psitilde_cs_02_0 = 1;
+    const double psitilde_cs_10_0 = 1;
+    const double psitilde_cs_10_1 = 3*z + 2;
+    const double psitilde_cs_11_0 = 1;
+    const double psitilde_cs_20_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.866025403784439*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
+    const double basisvalue1 = 2.73861278752583*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
+    const double basisvalue2 = 1.58113883008419*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
+    const double basisvalue3 = 1.11803398874989*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
+    const double basisvalue4 = 5.1234753829798*psitilde_a_2*scalings_y_2*psitilde_bs_2_0*scalings_z_2*psitilde_cs_20_0;
+    const double basisvalue5 = 3.96862696659689*psitilde_a_1*scalings_y_1*psitilde_bs_1_1*scalings_z_2*psitilde_cs_11_0;
+    const double basisvalue6 = 2.29128784747792*psitilde_a_0*scalings_y_0*psitilde_bs_0_2*scalings_z_2*psitilde_cs_02_0;
+    const double basisvalue7 = 3.24037034920393*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_1;
+    const double basisvalue8 = 1.87082869338697*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_1;
+    const double basisvalue9 = 1.3228756555323*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_2;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[10][10] = \
+    {{-0.0577350269189626, -0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, 0.0503952630678969, 0.0290957186981323, 0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
+    {-0.0577350269189625, 0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, -0.050395263067897, 0.0290957186981323, -0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
+    {-0.0577350269189625, 0, 0.0702728368926306, -0.0248451997499977, 0, 0, 0.0872871560943969, 0, -0.0475131096733199, 0.0167984210226323},
+    {-0.0577350269189626, 0, 0, 0.074535599249993, 0, 0, 0, 0, 0, 0.100790526135794},
+    {0.23094010767585, 0, 0.140545673785261, 0.0993807989999906, 0, 0, 0, 0, 0.1187827741833, -0.0671936840905293},
+    {0.230940107675851, 0.121716123890037, -0.0702728368926306, 0.0993807989999907, 0, 0, 0, 0.102868899974728, -0.0593913870916499, -0.0671936840905293},
+    {0.23094010767585, 0.121716123890037, 0.0702728368926307, -0.0993807989999907, 0, 0.100790526135794, -0.087287156094397, -0.0205737799949456, -0.01187827741833, 0.0167984210226323},
+    {0.23094010767585, -0.121716123890037, -0.0702728368926307, 0.0993807989999906, 0, 0, 0, -0.102868899974728, -0.0593913870916499, -0.0671936840905293},
+    {0.23094010767585, -0.121716123890037, 0.0702728368926306, -0.0993807989999906, 0, -0.100790526135794, -0.0872871560943969, 0.0205737799949456, -0.01187827741833, 0.0167984210226323},
+    {0.23094010767585, 0, -0.140545673785261, -0.0993807989999906, -0.130120009726471, 0, 0.0290957186981323, 0, 0.02375655483666, 0.0167984210226323}};
+    
+    // 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];
+    const double coeff0_6 = coefficients0[dof][6];
+    const double coeff0_7 = coefficients0[dof][7];
+    const double coeff0_8 = coefficients0[dof][8];
+    const double coeff0_9 = coefficients0[dof][9];
+    
+    // Compute value(s)
+    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5 + coeff0_6*basisvalue6 + coeff0_7*basisvalue7 + coeff0_8*basisvalue8 + coeff0_9*basisvalue9;
+}
+
+/// Evaluate all basis functions at given point in cell
+void solitarywave3d_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 solitarywave3d_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_02 = element_coordinates[3][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];
+    const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
+    const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
+    const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
+    const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
+    
+    // Compute sub determinants
+    const double d00 = J_11*J_22 - J_12*J_21;
+    const double d01 = J_12*J_20 - J_10*J_22;
+    const double d02 = J_10*J_21 - J_11*J_20;
+    
+    const double d10 = J_02*J_21 - J_01*J_22;
+    const double d11 = J_00*J_22 - J_02*J_20;
+    const double d12 = J_01*J_20 - J_00*J_21;
+    
+    const double d20 = J_01*J_12 - J_02*J_11;
+    const double d21 = J_02*J_10 - J_00*J_12;
+    const double d22 = J_00*J_11 - J_01*J_10;
+    
+    // Compute determinant of Jacobian
+    double detJ = J_00*d00 + J_10*d10 + J_20*d20;
+    
+    // Compute inverse of Jacobian
+    
+    // Compute constants
+    const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
+                    + d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
+                    + d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
+    
+    const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
+                    + d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
+                    + d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
+    
+    const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
+                    + d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
+                    + d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
+    
+    // Get coordinates and map to the UFC reference element
+    double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
+    double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
+    double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
+    
+    // Map coordinates to the reference cube
+    if (std::abs(y + z - 1.0) < 1e-14)
+      x = 1.0;
+    else
+      x = -2.0 * x/(y + z - 1.0) - 1.0;
+    if (std::abs(z - 1.0) < 1e-14)
+      y = -1.0;
+    else
+      y = 2.0 * y/(1.0 - z) - 1.0;
+    z = 2.0 * z - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 3;
+    
+    
+    // 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 > 2)
+            combinations[row][col] = 0;
+          else
+          {
+            combinations[row][col] += 1;
+            break;
+          }
+        }
+      }
+    }
+    
+    // Compute inverse of Jacobian
+    const double Jinv[3][3] ={{d00 / detJ, d10 / detJ, d20 / detJ}, {d01 / detJ, d11 / detJ, d21 / detJ}, {d02 / detJ, d12 / detJ, d22 / 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);
+    const double scalings_z_0 = 1;
+    const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
+    const double scalings_z_2 = scalings_z_1*(0.5 - 0.5*z);
+    
+    // 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 psitilde_cs
+    const double psitilde_cs_00_0 = 1;
+    const double psitilde_cs_00_1 = 2*z + 1;
+    const double psitilde_cs_00_2 = 0.3125*psitilde_cs_00_1 + 1.875*z*psitilde_cs_00_1 - 0.5625*psitilde_cs_00_0;
+    const double psitilde_cs_01_0 = 1;
+    const double psitilde_cs_01_1 = 3*z + 2;
+    const double psitilde_cs_02_0 = 1;
+    const double psitilde_cs_10_0 = 1;
+    const double psitilde_cs_10_1 = 3*z + 2;
+    const double psitilde_cs_11_0 = 1;
+    const double psitilde_cs_20_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.866025403784439*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
+    const double basisvalue1 = 2.73861278752583*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
+    const double basisvalue2 = 1.58113883008419*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
+    const double basisvalue3 = 1.11803398874989*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
+    const double basisvalue4 = 5.1234753829798*psitilde_a_2*scalings_y_2*psitilde_bs_2_0*scalings_z_2*psitilde_cs_20_0;
+    const double basisvalue5 = 3.96862696659689*psitilde_a_1*scalings_y_1*psitilde_bs_1_1*scalings_z_2*psitilde_cs_11_0;
+    const double basisvalue6 = 2.29128784747792*psitilde_a_0*scalings_y_0*psitilde_bs_0_2*scalings_z_2*psitilde_cs_02_0;
+    const double basisvalue7 = 3.24037034920393*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_1;
+    const double basisvalue8 = 1.87082869338697*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_1;
+    const double basisvalue9 = 1.3228756555323*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_2;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[10][10] = \
+    {{-0.0577350269189626, -0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, 0.0503952630678969, 0.0290957186981323, 0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
+    {-0.0577350269189625, 0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, -0.050395263067897, 0.0290957186981323, -0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
+    {-0.0577350269189625, 0, 0.0702728368926306, -0.0248451997499977, 0, 0, 0.0872871560943969, 0, -0.0475131096733199, 0.0167984210226323},
+    {-0.0577350269189626, 0, 0, 0.074535599249993, 0, 0, 0, 0, 0, 0.100790526135794},
+    {0.23094010767585, 0, 0.140545673785261, 0.0993807989999906, 0, 0, 0, 0, 0.1187827741833, -0.0671936840905293},
+    {0.230940107675851, 0.121716123890037, -0.0702728368926306, 0.0993807989999907, 0, 0, 0, 0.102868899974728, -0.0593913870916499, -0.0671936840905293},
+    {0.23094010767585, 0.121716123890037, 0.0702728368926307, -0.0993807989999907, 0, 0.100790526135794, -0.087287156094397, -0.0205737799949456, -0.01187827741833, 0.0167984210226323},
+    {0.23094010767585, -0.121716123890037, -0.0702728368926307, 0.0993807989999906, 0, 0, 0, -0.102868899974728, -0.0593913870916499, -0.0671936840905293},
+    {0.23094010767585, -0.121716123890037, 0.0702728368926306, -0.0993807989999906, 0, -0.100790526135794, -0.0872871560943969, 0.0205737799949456, -0.01187827741833, 0.0167984210226323},
+    {0.23094010767585, 0, -0.140545673785261, -0.0993807989999906, -0.130120009726471, 0, 0.0290957186981323, 0, 0.02375655483666, 0.0167984210226323}};
+    
+    // Interesting (new) part
+    // Tables of derivatives of the polynomial base (transpose)
+    static const double dmats0[10][10] = \
+    {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    {6.32455532033676, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    {0, 11.2249721603218, 0, 0, 0, 0, 0, 0, 0, 0},
+    {4.58257569495584, 0, 8.36660026534076, -1.18321595661992, 0, 0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    {3.74165738677394, 0, 0, 8.69482604771366, 0, 0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
+    
+    static const double dmats1[10][10] = \
+    {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    {3.16227766016838, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    {5.47722557505166, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    {2.95803989154981, 5.61248608016091, -1.08012344973464, -0.763762615825974, 0, 0, 0, 0, 0, 0},
+    {2.29128784747792, 7.24568837309472, 4.18330013267038, -0.591607978309962, 0, 0, 0, 0, 0, 0},
+    {-2.64575131106459, 0, 9.66091783079296, 0.683130051063974, 0, 0, 0, 0, 0, 0},
+    {1.87082869338697, 0, 0, 4.34741302385683, 0, 0, 0, 0, 0, 0},
+    {3.24037034920393, 0, 0, 7.52994023880668, 0, 0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
+    
+    static const double dmats2[10][10] = \
+    {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    {3.16227766016838, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    {1.82574185835055, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    {5.16397779494322, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    {2.95803989154981, 5.61248608016091, -1.08012344973464, -0.763762615825974, 0, 0, 0, 0, 0, 0},
+    {2.29128784747792, 1.44913767461894, 4.18330013267038, -0.591607978309962, 0, 0, 0, 0, 0, 0},
+    {1.32287565553229, 0, 3.86436713231718, -0.341565025531986, 0, 0, 0, 0, 0, 0},
+    {1.87082869338697, 7.09929573971954, 0, 4.34741302385683, 0, 0, 0, 0, 0, 0},
+    {1.08012344973464, 0, 7.09929573971954, 2.50998007960223, 0, 0, 0, 0, 0, 0},
+    {-3.81881307912987, 0, 0, 8.87411967464942, 0, 0, 0, 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;
+    double coeff0_6 = 0;
+    double coeff0_7 = 0;
+    double coeff0_8 = 0;
+    double coeff0_9 = 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;
+    double new_coeff0_6 = 0;
+    double new_coeff0_7 = 0;
+    double new_coeff0_8 = 0;
+    double new_coeff0_9 = 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];
+      new_coeff0_6 = coefficients0[dof][6];
+      new_coeff0_7 = coefficients0[dof][7];
+      new_coeff0_8 = coefficients0[dof][8];
+      new_coeff0_9 = coefficients0[dof][9];
+    
+      // 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;
+        coeff0_6 = new_coeff0_6;
+        coeff0_7 = new_coeff0_7;
+        coeff0_8 = new_coeff0_8;
+        coeff0_9 = new_coeff0_9;
+    
+        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] + coeff0_6*dmats0[6][0] + coeff0_7*dmats0[7][0] + coeff0_8*dmats0[8][0] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][1] + coeff0_7*dmats0[7][1] + coeff0_8*dmats0[8][1] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][2] + coeff0_7*dmats0[7][2] + coeff0_8*dmats0[8][2] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][3] + coeff0_7*dmats0[7][3] + coeff0_8*dmats0[8][3] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][4] + coeff0_7*dmats0[7][4] + coeff0_8*dmats0[8][4] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][5] + coeff0_7*dmats0[7][5] + coeff0_8*dmats0[8][5] + coeff0_9*dmats0[9][5];
+          new_coeff0_6 = coeff0_0*dmats0[0][6] + coeff0_1*dmats0[1][6] + coeff0_2*dmats0[2][6] + coeff0_3*dmats0[3][6] + coeff0_4*dmats0[4][6] + coeff0_5*dmats0[5][6] + coeff0_6*dmats0[6][6] + coeff0_7*dmats0[7][6] + coeff0_8*dmats0[8][6] + coeff0_9*dmats0[9][6];
+          new_coeff0_7 = coeff0_0*dmats0[0][7] + coeff0_1*dmats0[1][7] + coeff0_2*dmats0[2][7] + coeff0_3*dmats0[3][7] + coeff0_4*dmats0[4][7] + coeff0_5*dmats0[5][7] + coeff0_6*dmats0[6][7] + coeff0_7*dmats0[7][7] + coeff0_8*dmats0[8][7] + coeff0_9*dmats0[9][7];
+          new_coeff0_8 = coeff0_0*dmats0[0][8] + coeff0_1*dmats0[1][8] + coeff0_2*dmats0[2][8] + coeff0_3*dmats0[3][8] + coeff0_4*dmats0[4][8] + coeff0_5*dmats0[5][8] + coeff0_6*dmats0[6][8] + coeff0_7*dmats0[7][8] + coeff0_8*dmats0[8][8] + coeff0_9*dmats0[9][8];
+          new_coeff0_9 = coeff0_0*dmats0[0][9] + coeff0_1*dmats0[1][9] + coeff0_2*dmats0[2][9] + coeff0_3*dmats0[3][9] + coeff0_4*dmats0[4][9] + coeff0_5*dmats0[5][9] + coeff0_6*dmats0[6][9] + coeff0_7*dmats0[7][9] + coeff0_8*dmats0[8][9] + coeff0_9*dmats0[9][9];
+        }
+        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] + coeff0_6*dmats1[6][0] + coeff0_7*dmats1[7][0] + coeff0_8*dmats1[8][0] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][1] + coeff0_7*dmats1[7][1] + coeff0_8*dmats1[8][1] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][2] + coeff0_7*dmats1[7][2] + coeff0_8*dmats1[8][2] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][3] + coeff0_7*dmats1[7][3] + coeff0_8*dmats1[8][3] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][4] + coeff0_7*dmats1[7][4] + coeff0_8*dmats1[8][4] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][5] + coeff0_7*dmats1[7][5] + coeff0_8*dmats1[8][5] + coeff0_9*dmats1[9][5];
+          new_coeff0_6 = coeff0_0*dmats1[0][6] + coeff0_1*dmats1[1][6] + coeff0_2*dmats1[2][6] + coeff0_3*dmats1[3][6] + coeff0_4*dmats1[4][6] + coeff0_5*dmats1[5][6] + coeff0_6*dmats1[6][6] + coeff0_7*dmats1[7][6] + coeff0_8*dmats1[8][6] + coeff0_9*dmats1[9][6];
+          new_coeff0_7 = coeff0_0*dmats1[0][7] + coeff0_1*dmats1[1][7] + coeff0_2*dmats1[2][7] + coeff0_3*dmats1[3][7] + coeff0_4*dmats1[4][7] + coeff0_5*dmats1[5][7] + coeff0_6*dmats1[6][7] + coeff0_7*dmats1[7][7] + coeff0_8*dmats1[8][7] + coeff0_9*dmats1[9][7];
+          new_coeff0_8 = coeff0_0*dmats1[0][8] + coeff0_1*dmats1[1][8] + coeff0_2*dmats1[2][8] + coeff0_3*dmats1[3][8] + coeff0_4*dmats1[4][8] + coeff0_5*dmats1[5][8] + coeff0_6*dmats1[6][8] + coeff0_7*dmats1[7][8] + coeff0_8*dmats1[8][8] + coeff0_9*dmats1[9][8];
+          new_coeff0_9 = coeff0_0*dmats1[0][9] + coeff0_1*dmats1[1][9] + coeff0_2*dmats1[2][9] + coeff0_3*dmats1[3][9] + coeff0_4*dmats1[4][9] + coeff0_5*dmats1[5][9] + coeff0_6*dmats1[6][9] + coeff0_7*dmats1[7][9] + coeff0_8*dmats1[8][9] + coeff0_9*dmats1[9][9];
+        }
+        if(combinations[deriv_num][j] == 2)
+        {
+          new_coeff0_0 = coeff0_0*dmats2[0][0] + coeff0_1*dmats2[1][0] + coeff0_2*dmats2[2][0] + coeff0_3*dmats2[3][0] + coeff0_4*dmats2[4][0] + coeff0_5*dmats2[5][0] + coeff0_6*dmats2[6][0] + coeff0_7*dmats2[7][0] + coeff0_8*dmats2[8][0] + coeff0_9*dmats2[9][0];
+          new_coeff0_1 = coeff0_0*dmats2[0][1] + coeff0_1*dmats2[1][1] + coeff0_2*dmats2[2][1] + coeff0_3*dmats2[3][1] + coeff0_4*dmats2[4][1] + coeff0_5*dmats2[5][1] + coeff0_6*dmats2[6][1] + coeff0_7*dmats2[7][1] + coeff0_8*dmats2[8][1] + coeff0_9*dmats2[9][1];
+          new_coeff0_2 = coeff0_0*dmats2[0][2] + coeff0_1*dmats2[1][2] + coeff0_2*dmats2[2][2] + coeff0_3*dmats2[3][2] + coeff0_4*dmats2[4][2] + coeff0_5*dmats2[5][2] + coeff0_6*dmats2[6][2] + coeff0_7*dmats2[7][2] + coeff0_8*dmats2[8][2] + coeff0_9*dmats2[9][2];
+          new_coeff0_3 = coeff0_0*dmats2[0][3] + coeff0_1*dmats2[1][3] + coeff0_2*dmats2[2][3] + coeff0_3*dmats2[3][3] + coeff0_4*dmats2[4][3] + coeff0_5*dmats2[5][3] + coeff0_6*dmats2[6][3] + coeff0_7*dmats2[7][3] + coeff0_8*dmats2[8][3] + coeff0_9*dmats2[9][3];
+          new_coeff0_4 = coeff0_0*dmats2[0][4] + coeff0_1*dmats2[1][4] + coeff0_2*dmats2[2][4] + coeff0_3*dmats2[3][4] + coeff0_4*dmats2[4][4] + coeff0_5*dmats2[5][4] + coeff0_6*dmats2[6][4] + coeff0_7*dmats2[7][4] + coeff0_8*dmats2[8][4] + coeff0_9*dmats2[9][4];
+          new_coeff0_5 = coeff0_0*dmats2[0][5] + coeff0_1*dmats2[1][5] + coeff0_2*dmats2[2][5] + coeff0_3*dmats2[3][5] + coeff0_4*dmats2[4][5] + coeff0_5*dmats2[5][5] + coeff0_6*dmats2[6][5] + coeff0_7*dmats2[7][5] + coeff0_8*dmats2[8][5] + coeff0_9*dmats2[9][5];
+          new_coeff0_6 = coeff0_0*dmats2[0][6] + coeff0_1*dmats2[1][6] + coeff0_2*dmats2[2][6] + coeff0_3*dmats2[3][6] + coeff0_4*dmats2[4][6] + coeff0_5*dmats2[5][6] + coeff0_6*dmats2[6][6] + coeff0_7*dmats2[7][6] + coeff0_8*dmats2[8][6] + coeff0_9*dmats2[9][6];
+          new_coeff0_7 = coeff0_0*dmats2[0][7] + coeff0_1*dmats2[1][7] + coeff0_2*dmats2[2][7] + coeff0_3*dmats2[3][7] + coeff0_4*dmats2[4][7] + coeff0_5*dmats2[5][7] + coeff0_6*dmats2[6][7] + coeff0_7*dmats2[7][7] + coeff0_8*dmats2[8][7] + coeff0_9*dmats2[9][7];
+          new_coeff0_8 = coeff0_0*dmats2[0][8] + coeff0_1*dmats2[1][8] + coeff0_2*dmats2[2][8] + coeff0_3*dmats2[3][8] + coeff0_4*dmats2[4][8] + coeff0_5*dmats2[5][8] + coeff0_6*dmats2[6][8] + coeff0_7*dmats2[7][8] + coeff0_8*dmats2[8][8] + coeff0_9*dmats2[9][8];
+          new_coeff0_9 = coeff0_0*dmats2[0][9] + coeff0_1*dmats2[1][9] + coeff0_2*dmats2[2][9] + coeff0_3*dmats2[3][9] + coeff0_4*dmats2[4][9] + coeff0_5*dmats2[5][9] + coeff0_6*dmats2[6][9] + coeff0_7*dmats2[7][9] + coeff0_8*dmats2[8][9] + coeff0_9*dmats2[9][9];
+        }
+    
+      }
+      // 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 + new_coeff0_6*basisvalue6 + new_coeff0_7*basisvalue7 + new_coeff0_8*basisvalue8 + new_coeff0_9*basisvalue9;
+    }
+    
+    // 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 solitarywave3d_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 solitarywave3d_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[10][1][3] = {{{0, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 0, 1}}, {{0, 0.5, 0.5}}, {{0.5, 0, 0.5}}, {{0.5, 0.5, 0}}, {{0, 0, 0.5}}, {{0, 0.5, 0}}, {{0.5, 0, 0}}};
+    static const double W[10][1] = {{1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}};
+    static const double D[10][1][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] - X[i][0][2];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    const double w3 = X[i][0][2];
+    
+    // Compute affine mapping y = F(X)
+    double y[3];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0] + w3*x[3][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1] + w3*x[3][1];
+    y[2] = w0*x[0][2] + w1*x[1][2] + w2*x[2][2] + w3*x[3][2];
+    
+    // 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 solitarywave3d_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 solitarywave3d_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];
+    vertex_values[3] = dof_values[3];
+}
+
+/// Return the number of sub elements (for a mixed element)
+unsigned int solitarywave3d_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* solitarywave3d_1_finite_element_1_0::create_sub_element(unsigned int i) const
+{
+    return new solitarywave3d_1_finite_element_1_0();
+}
+
+
+/// Constructor
+solitarywave3d_1_finite_element_1_1::solitarywave3d_1_finite_element_1_1() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+solitarywave3d_1_finite_element_1_1::~solitarywave3d_1_finite_element_1_1()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* solitarywave3d_1_finite_element_1_1::signature() const
+{
+    return "FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)";
+}
+
+/// Return the cell shape
+ufc::shape solitarywave3d_1_finite_element_1_1::cell_shape() const
+{
+    return ufc::tetrahedron;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int solitarywave3d_1_finite_element_1_1::space_dimension() const
+{
+    return 10;
+}
+
+/// Return the rank of the value space
+unsigned int solitarywave3d_1_finite_element_1_1::value_rank() const
+{
+    return 0;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int solitarywave3d_1_finite_element_1_1::value_dimension(unsigned int i) const
+{
+    return 1;
+}
+
+/// Evaluate basis function i at given point in cell
+void solitarywave3d_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_02 = element_coordinates[3][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];
+    const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
+    const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
+    const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
+    const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
+    
+    // Compute sub determinants
+    const double d00 = J_11*J_22 - J_12*J_21;
+    const double d01 = J_12*J_20 - J_10*J_22;
+    const double d02 = J_10*J_21 - J_11*J_20;
+    
+    const double d10 = J_02*J_21 - J_01*J_22;
+    const double d11 = J_00*J_22 - J_02*J_20;
+    const double d12 = J_01*J_20 - J_00*J_21;
+    
+    const double d20 = J_01*J_12 - J_02*J_11;
+    const double d21 = J_02*J_10 - J_00*J_12;
+    const double d22 = J_00*J_11 - J_01*J_10;
+    
+    // Compute determinant of Jacobian
+    double detJ = J_00*d00 + J_10*d10 + J_20*d20;
+    
+    // Compute inverse of Jacobian
+    
+    // Compute constants
+    const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
+                    + d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
+                    + d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
+    
+    const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
+                    + d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
+                    + d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
+    
+    const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
+                    + d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
+                    + d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
+    
+    // Get coordinates and map to the UFC reference element
+    double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
+    double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
+    double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
+    
+    // Map coordinates to the reference cube
+    if (std::abs(y + z - 1.0) < 1e-14)
+      x = 1.0;
+    else
+      x = -2.0 * x/(y + z - 1.0) - 1.0;
+    if (std::abs(z - 1.0) < 1e-14)
+      y = -1.0;
+    else
+      y = 2.0 * y/(1.0 - z) - 1.0;
+    z = 2.0 * z - 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);
+    const double scalings_z_0 = 1;
+    const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
+    const double scalings_z_2 = scalings_z_1*(0.5 - 0.5*z);
+    
+    // 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 psitilde_cs
+    const double psitilde_cs_00_0 = 1;
+    const double psitilde_cs_00_1 = 2*z + 1;
+    const double psitilde_cs_00_2 = 0.3125*psitilde_cs_00_1 + 1.875*z*psitilde_cs_00_1 - 0.5625*psitilde_cs_00_0;
+    const double psitilde_cs_01_0 = 1;
+    const double psitilde_cs_01_1 = 3*z + 2;
+    const double psitilde_cs_02_0 = 1;
+    const double psitilde_cs_10_0 = 1;
+    const double psitilde_cs_10_1 = 3*z + 2;
+    const double psitilde_cs_11_0 = 1;
+    const double psitilde_cs_20_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.866025403784439*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
+    const double basisvalue1 = 2.73861278752583*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
+    const double basisvalue2 = 1.58113883008419*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
+    const double basisvalue3 = 1.11803398874989*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
+    const double basisvalue4 = 5.1234753829798*psitilde_a_2*scalings_y_2*psitilde_bs_2_0*scalings_z_2*psitilde_cs_20_0;
+    const double basisvalue5 = 3.96862696659689*psitilde_a_1*scalings_y_1*psitilde_bs_1_1*scalings_z_2*psitilde_cs_11_0;
+    const double basisvalue6 = 2.29128784747792*psitilde_a_0*scalings_y_0*psitilde_bs_0_2*scalings_z_2*psitilde_cs_02_0;
+    const double basisvalue7 = 3.24037034920393*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_1;
+    const double basisvalue8 = 1.87082869338697*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_1;
+    const double basisvalue9 = 1.3228756555323*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_2;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[10][10] = \
+    {{-0.0577350269189626, -0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, 0.0503952630678969, 0.0290957186981323, 0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
+    {-0.0577350269189625, 0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, -0.050395263067897, 0.0290957186981323, -0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
+    {-0.0577350269189625, 0, 0.0702728368926306, -0.0248451997499977, 0, 0, 0.0872871560943969, 0, -0.0475131096733199, 0.0167984210226323},
+    {-0.0577350269189626, 0, 0, 0.074535599249993, 0, 0, 0, 0, 0, 0.100790526135794},
+    {0.23094010767585, 0, 0.140545673785261, 0.0993807989999906, 0, 0, 0, 0, 0.1187827741833, -0.0671936840905293},
+    {0.230940107675851, 0.121716123890037, -0.0702728368926306, 0.0993807989999907, 0, 0, 0, 0.102868899974728, -0.0593913870916499, -0.0671936840905293},
+    {0.23094010767585, 0.121716123890037, 0.0702728368926307, -0.0993807989999907, 0, 0.100790526135794, -0.087287156094397, -0.0205737799949456, -0.01187827741833, 0.0167984210226323},
+    {0.23094010767585, -0.121716123890037, -0.0702728368926307, 0.0993807989999906, 0, 0, 0, -0.102868899974728, -0.0593913870916499, -0.0671936840905293},
+    {0.23094010767585, -0.121716123890037, 0.0702728368926306, -0.0993807989999906, 0, -0.100790526135794, -0.0872871560943969, 0.0205737799949456, -0.01187827741833, 0.0167984210226323},
+    {0.23094010767585, 0, -0.140545673785261, -0.0993807989999906, -0.130120009726471, 0, 0.0290957186981323, 0, 0.02375655483666, 0.0167984210226323}};
+    
+    // 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];
+    const double coeff0_6 = coefficients0[dof][6];
+    const double coeff0_7 = coefficients0[dof][7];
+    const double coeff0_8 = coefficients0[dof][8];
+    const double coeff0_9 = coefficients0[dof][9];
+    
+    // Compute value(s)
+    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5 + coeff0_6*basisvalue6 + coeff0_7*basisvalue7 + coeff0_8*basisvalue8 + coeff0_9*basisvalue9;
+}
+
+/// Evaluate all basis functions at given point in cell
+void solitarywave3d_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 solitarywave3d_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_02 = element_coordinates[3][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];
+    const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
+    const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
+    const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
+    const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
+    
+    // Compute sub determinants
+    const double d00 = J_11*J_22 - J_12*J_21;
+    const double d01 = J_12*J_20 - J_10*J_22;
+    const double d02 = J_10*J_21 - J_11*J_20;
+    
+    const double d10 = J_02*J_21 - J_01*J_22;
+    const double d11 = J_00*J_22 - J_02*J_20;
+    const double d12 = J_01*J_20 - J_00*J_21;
+    
+    const double d20 = J_01*J_12 - J_02*J_11;
+    const double d21 = J_02*J_10 - J_00*J_12;
+    const double d22 = J_00*J_11 - J_01*J_10;
+    
+    // Compute determinant of Jacobian
+    double detJ = J_00*d00 + J_10*d10 + J_20*d20;
+    
+    // Compute inverse of Jacobian
+    
+    // Compute constants
+    const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
+                    + d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
+                    + d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
+    
+    const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
+                    + d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
+                    + d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
+    
+    const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
+                    + d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
+                    + d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
+    
+    // Get coordinates and map to the UFC reference element
+    double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
+    double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
+    double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
+    
+    // Map coordinates to the reference cube
+    if (std::abs(y + z - 1.0) < 1e-14)
+      x = 1.0;
+    else
+      x = -2.0 * x/(y + z - 1.0) - 1.0;
+    if (std::abs(z - 1.0) < 1e-14)
+      y = -1.0;
+    else
+      y = 2.0 * y/(1.0 - z) - 1.0;
+    z = 2.0 * z - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 3;
+    
+    
+    // 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 > 2)
+            combinations[row][col] = 0;
+          else
+          {
+            combinations[row][col] += 1;
+            break;
+          }
+        }
+      }
+    }
+    
+    // Compute inverse of Jacobian
+    const double Jinv[3][3] ={{d00 / detJ, d10 / detJ, d20 / detJ}, {d01 / detJ, d11 / detJ, d21 / detJ}, {d02 / detJ, d12 / detJ, d22 / 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);
+    const double scalings_z_0 = 1;
+    const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
+    const double scalings_z_2 = scalings_z_1*(0.5 - 0.5*z);
+    
+    // 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 psitilde_cs
+    const double psitilde_cs_00_0 = 1;
+    const double psitilde_cs_00_1 = 2*z + 1;
+    const double psitilde_cs_00_2 = 0.3125*psitilde_cs_00_1 + 1.875*z*psitilde_cs_00_1 - 0.5625*psitilde_cs_00_0;
+    const double psitilde_cs_01_0 = 1;
+    const double psitilde_cs_01_1 = 3*z + 2;
+    const double psitilde_cs_02_0 = 1;
+    const double psitilde_cs_10_0 = 1;
+    const double psitilde_cs_10_1 = 3*z + 2;
+    const double psitilde_cs_11_0 = 1;
+    const double psitilde_cs_20_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.866025403784439*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
+    const double basisvalue1 = 2.73861278752583*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
+    const double basisvalue2 = 1.58113883008419*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
+    const double basisvalue3 = 1.11803398874989*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
+    const double basisvalue4 = 5.1234753829798*psitilde_a_2*scalings_y_2*psitilde_bs_2_0*scalings_z_2*psitilde_cs_20_0;
+    const double basisvalue5 = 3.96862696659689*psitilde_a_1*scalings_y_1*psitilde_bs_1_1*scalings_z_2*psitilde_cs_11_0;
+    const double basisvalue6 = 2.29128784747792*psitilde_a_0*scalings_y_0*psitilde_bs_0_2*scalings_z_2*psitilde_cs_02_0;
+    const double basisvalue7 = 3.24037034920393*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_1;
+    const double basisvalue8 = 1.87082869338697*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_1;
+    const double basisvalue9 = 1.3228756555323*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_2;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[10][10] = \
+    {{-0.0577350269189626, -0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, 0.0503952630678969, 0.0290957186981323, 0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
+    {-0.0577350269189625, 0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, -0.050395263067897, 0.0290957186981323, -0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
+    {-0.0577350269189625, 0, 0.0702728368926306, -0.0248451997499977, 0, 0, 0.0872871560943969, 0, -0.0475131096733199, 0.0167984210226323},
+    {-0.0577350269189626, 0, 0, 0.074535599249993, 0, 0, 0, 0, 0, 0.100790526135794},
+    {0.23094010767585, 0, 0.140545673785261, 0.0993807989999906, 0, 0, 0, 0, 0.1187827741833, -0.0671936840905293},
+    {0.230940107675851, 0.121716123890037, -0.0702728368926306, 0.0993807989999907, 0, 0, 0, 0.102868899974728, -0.0593913870916499, -0.0671936840905293},
+    {0.23094010767585, 0.121716123890037, 0.0702728368926307, -0.0993807989999907, 0, 0.100790526135794, -0.087287156094397, -0.0205737799949456, -0.01187827741833, 0.0167984210226323},
+    {0.23094010767585, -0.121716123890037, -0.0702728368926307, 0.0993807989999906, 0, 0, 0, -0.102868899974728, -0.0593913870916499, -0.0671936840905293},
+    {0.23094010767585, -0.121716123890037, 0.0702728368926306, -0.0993807989999906, 0, -0.100790526135794, -0.0872871560943969, 0.0205737799949456, -0.01187827741833, 0.0167984210226323},
+    {0.23094010767585, 0, -0.140545673785261, -0.0993807989999906, -0.130120009726471, 0, 0.0290957186981323, 0, 0.02375655483666, 0.0167984210226323}};
+    
+    // Interesting (new) part
+    // Tables of derivatives of the polynomial base (transpose)
+    static const double dmats0[10][10] = \
+    {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    {6.32455532033676, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    {0, 11.2249721603218, 0, 0, 0, 0, 0, 0, 0, 0},
+    {4.58257569495584, 0, 8.36660026534076, -1.18321595661992, 0, 0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    {3.74165738677394, 0, 0, 8.69482604771366, 0, 0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
+    
+    static const double dmats1[10][10] = \
+    {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    {3.16227766016838, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    {5.47722557505166, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    {2.95803989154981, 5.61248608016091, -1.08012344973464, -0.763762615825974, 0, 0, 0, 0, 0, 0},
+    {2.29128784747792, 7.24568837309472, 4.18330013267038, -0.591607978309962, 0, 0, 0, 0, 0, 0},
+    {-2.64575131106459, 0, 9.66091783079296, 0.683130051063974, 0, 0, 0, 0, 0, 0},
+    {1.87082869338697, 0, 0, 4.34741302385683, 0, 0, 0, 0, 0, 0},
+    {3.24037034920393, 0, 0, 7.52994023880668, 0, 0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
+    
+    static const double dmats2[10][10] = \
+    {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    {3.16227766016838, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    {1.82574185835055, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    {5.16397779494322, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    {2.95803989154981, 5.61248608016091, -1.08012344973464, -0.763762615825974, 0, 0, 0, 0, 0, 0},
+    {2.29128784747792, 1.44913767461894, 4.18330013267038, -0.591607978309962, 0, 0, 0, 0, 0, 0},
+    {1.32287565553229, 0, 3.86436713231718, -0.341565025531986, 0, 0, 0, 0, 0, 0},
+    {1.87082869338697, 7.09929573971954, 0, 4.34741302385683, 0, 0, 0, 0, 0, 0},
+    {1.08012344973464, 0, 7.09929573971954, 2.50998007960223, 0, 0, 0, 0, 0, 0},
+    {-3.81881307912987, 0, 0, 8.87411967464942, 0, 0, 0, 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;
+    double coeff0_6 = 0;
+    double coeff0_7 = 0;
+    double coeff0_8 = 0;
+    double coeff0_9 = 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;
+    double new_coeff0_6 = 0;
+    double new_coeff0_7 = 0;
+    double new_coeff0_8 = 0;
+    double new_coeff0_9 = 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];
+      new_coeff0_6 = coefficients0[dof][6];
+      new_coeff0_7 = coefficients0[dof][7];
+      new_coeff0_8 = coefficients0[dof][8];
+      new_coeff0_9 = coefficients0[dof][9];
+    
+      // 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;
+        coeff0_6 = new_coeff0_6;
+        coeff0_7 = new_coeff0_7;
+        coeff0_8 = new_coeff0_8;
+        coeff0_9 = new_coeff0_9;
+    
+        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] + coeff0_6*dmats0[6][0] + coeff0_7*dmats0[7][0] + coeff0_8*dmats0[8][0] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][1] + coeff0_7*dmats0[7][1] + coeff0_8*dmats0[8][1] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][2] + coeff0_7*dmats0[7][2] + coeff0_8*dmats0[8][2] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][3] + coeff0_7*dmats0[7][3] + coeff0_8*dmats0[8][3] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][4] + coeff0_7*dmats0[7][4] + coeff0_8*dmats0[8][4] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][5] + coeff0_7*dmats0[7][5] + coeff0_8*dmats0[8][5] + coeff0_9*dmats0[9][5];
+          new_coeff0_6 = coeff0_0*dmats0[0][6] + coeff0_1*dmats0[1][6] + coeff0_2*dmats0[2][6] + coeff0_3*dmats0[3][6] + coeff0_4*dmats0[4][6] + coeff0_5*dmats0[5][6] + coeff0_6*dmats0[6][6] + coeff0_7*dmats0[7][6] + coeff0_8*dmats0[8][6] + coeff0_9*dmats0[9][6];
+          new_coeff0_7 = coeff0_0*dmats0[0][7] + coeff0_1*dmats0[1][7] + coeff0_2*dmats0[2][7] + coeff0_3*dmats0[3][7] + coeff0_4*dmats0[4][7] + coeff0_5*dmats0[5][7] + coeff0_6*dmats0[6][7] + coeff0_7*dmats0[7][7] + coeff0_8*dmats0[8][7] + coeff0_9*dmats0[9][7];
+          new_coeff0_8 = coeff0_0*dmats0[0][8] + coeff0_1*dmats0[1][8] + coeff0_2*dmats0[2][8] + coeff0_3*dmats0[3][8] + coeff0_4*dmats0[4][8] + coeff0_5*dmats0[5][8] + coeff0_6*dmats0[6][8] + coeff0_7*dmats0[7][8] + coeff0_8*dmats0[8][8] + coeff0_9*dmats0[9][8];
+          new_coeff0_9 = coeff0_0*dmats0[0][9] + coeff0_1*dmats0[1][9] + coeff0_2*dmats0[2][9] + coeff0_3*dmats0[3][9] + coeff0_4*dmats0[4][9] + coeff0_5*dmats0[5][9] + coeff0_6*dmats0[6][9] + coeff0_7*dmats0[7][9] + coeff0_8*dmats0[8][9] + coeff0_9*dmats0[9][9];
+        }
+        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] + coeff0_6*dmats1[6][0] + coeff0_7*dmats1[7][0] + coeff0_8*dmats1[8][0] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][1] + coeff0_7*dmats1[7][1] + coeff0_8*dmats1[8][1] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][2] + coeff0_7*dmats1[7][2] + coeff0_8*dmats1[8][2] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][3] + coeff0_7*dmats1[7][3] + coeff0_8*dmats1[8][3] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][4] + coeff0_7*dmats1[7][4] + coeff0_8*dmats1[8][4] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][5] + coeff0_7*dmats1[7][5] + coeff0_8*dmats1[8][5] + coeff0_9*dmats1[9][5];
+          new_coeff0_6 = coeff0_0*dmats1[0][6] + coeff0_1*dmats1[1][6] + coeff0_2*dmats1[2][6] + coeff0_3*dmats1[3][6] + coeff0_4*dmats1[4][6] + coeff0_5*dmats1[5][6] + coeff0_6*dmats1[6][6] + coeff0_7*dmats1[7][6] + coeff0_8*dmats1[8][6] + coeff0_9*dmats1[9][6];
+          new_coeff0_7 = coeff0_0*dmats1[0][7] + coeff0_1*dmats1[1][7] + coeff0_2*dmats1[2][7] + coeff0_3*dmats1[3][7] + coeff0_4*dmats1[4][7] + coeff0_5*dmats1[5][7] + coeff0_6*dmats1[6][7] + coeff0_7*dmats1[7][7] + coeff0_8*dmats1[8][7] + coeff0_9*dmats1[9][7];
+          new_coeff0_8 = coeff0_0*dmats1[0][8] + coeff0_1*dmats1[1][8] + coeff0_2*dmats1[2][8] + coeff0_3*dmats1[3][8] + coeff0_4*dmats1[4][8] + coeff0_5*dmats1[5][8] + coeff0_6*dmats1[6][8] + coeff0_7*dmats1[7][8] + coeff0_8*dmats1[8][8] + coeff0_9*dmats1[9][8];
+          new_coeff0_9 = coeff0_0*dmats1[0][9] + coeff0_1*dmats1[1][9] + coeff0_2*dmats1[2][9] + coeff0_3*dmats1[3][9] + coeff0_4*dmats1[4][9] + coeff0_5*dmats1[5][9] + coeff0_6*dmats1[6][9] + coeff0_7*dmats1[7][9] + coeff0_8*dmats1[8][9] + coeff0_9*dmats1[9][9];
+        }
+        if(combinations[deriv_num][j] == 2)
+        {
+          new_coeff0_0 = coeff0_0*dmats2[0][0] + coeff0_1*dmats2[1][0] + coeff0_2*dmats2[2][0] + coeff0_3*dmats2[3][0] + coeff0_4*dmats2[4][0] + coeff0_5*dmats2[5][0] + coeff0_6*dmats2[6][0] + coeff0_7*dmats2[7][0] + coeff0_8*dmats2[8][0] + coeff0_9*dmats2[9][0];
+          new_coeff0_1 = coeff0_0*dmats2[0][1] + coeff0_1*dmats2[1][1] + coeff0_2*dmats2[2][1] + coeff0_3*dmats2[3][1] + coeff0_4*dmats2[4][1] + coeff0_5*dmats2[5][1] + coeff0_6*dmats2[6][1] + coeff0_7*dmats2[7][1] + coeff0_8*dmats2[8][1] + coeff0_9*dmats2[9][1];
+          new_coeff0_2 = coeff0_0*dmats2[0][2] + coeff0_1*dmats2[1][2] + coeff0_2*dmats2[2][2] + coeff0_3*dmats2[3][2] + coeff0_4*dmats2[4][2] + coeff0_5*dmats2[5][2] + coeff0_6*dmats2[6][2] + coeff0_7*dmats2[7][2] + coeff0_8*dmats2[8][2] + coeff0_9*dmats2[9][2];
+          new_coeff0_3 = coeff0_0*dmats2[0][3] + coeff0_1*dmats2[1][3] + coeff0_2*dmats2[2][3] + coeff0_3*dmats2[3][3] + coeff0_4*dmats2[4][3] + coeff0_5*dmats2[5][3] + coeff0_6*dmats2[6][3] + coeff0_7*dmats2[7][3] + coeff0_8*dmats2[8][3] + coeff0_9*dmats2[9][3];
+          new_coeff0_4 = coeff0_0*dmats2[0][4] + coeff0_1*dmats2[1][4] + coeff0_2*dmats2[2][4] + coeff0_3*dmats2[3][4] + coeff0_4*dmats2[4][4] + coeff0_5*dmats2[5][4] + coeff0_6*dmats2[6][4] + coeff0_7*dmats2[7][4] + coeff0_8*dmats2[8][4] + coeff0_9*dmats2[9][4];
+          new_coeff0_5 = coeff0_0*dmats2[0][5] + coeff0_1*dmats2[1][5] + coeff0_2*dmats2[2][5] + coeff0_3*dmats2[3][5] + coeff0_4*dmats2[4][5] + coeff0_5*dmats2[5][5] + coeff0_6*dmats2[6][5] + coeff0_7*dmats2[7][5] + coeff0_8*dmats2[8][5] + coeff0_9*dmats2[9][5];
+          new_coeff0_6 = coeff0_0*dmats2[0][6] + coeff0_1*dmats2[1][6] + coeff0_2*dmats2[2][6] + coeff0_3*dmats2[3][6] + coeff0_4*dmats2[4][6] + coeff0_5*dmats2[5][6] + coeff0_6*dmats2[6][6] + coeff0_7*dmats2[7][6] + coeff0_8*dmats2[8][6] + coeff0_9*dmats2[9][6];
+          new_coeff0_7 = coeff0_0*dmats2[0][7] + coeff0_1*dmats2[1][7] + coeff0_2*dmats2[2][7] + coeff0_3*dmats2[3][7] + coeff0_4*dmats2[4][7] + coeff0_5*dmats2[5][7] + coeff0_6*dmats2[6][7] + coeff0_7*dmats2[7][7] + coeff0_8*dmats2[8][7] + coeff0_9*dmats2[9][7];
+          new_coeff0_8 = coeff0_0*dmats2[0][8] + coeff0_1*dmats2[1][8] + coeff0_2*dmats2[2][8] + coeff0_3*dmats2[3][8] + coeff0_4*dmats2[4][8] + coeff0_5*dmats2[5][8] + coeff0_6*dmats2[6][8] + coeff0_7*dmats2[7][8] + coeff0_8*dmats2[8][8] + coeff0_9*dmats2[9][8];
+          new_coeff0_9 = coeff0_0*dmats2[0][9] + coeff0_1*dmats2[1][9] + coeff0_2*dmats2[2][9] + coeff0_3*dmats2[3][9] + coeff0_4*dmats2[4][9] + coeff0_5*dmats2[5][9] + coeff0_6*dmats2[6][9] + coeff0_7*dmats2[7][9] + coeff0_8*dmats2[8][9] + coeff0_9*dmats2[9][9];
+        }
+    
+      }
+      // 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 + new_coeff0_6*basisvalue6 + new_coeff0_7*basisvalue7 + new_coeff0_8*basisvalue8 + new_coeff0_9*basisvalue9;
+    }
+    
+    // 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 solitarywave3d_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 solitarywave3d_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[10][1][3] = {{{0, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 0, 1}}, {{0, 0.5, 0.5}}, {{0.5, 0, 0.5}}, {{0.5, 0.5, 0}}, {{0, 0, 0.5}}, {{0, 0.5, 0}}, {{0.5, 0, 0}}};
+    static const double W[10][1] = {{1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}};
+    static const double D[10][1][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] - X[i][0][2];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    const double w3 = X[i][0][2];
+    
+    // Compute affine mapping y = F(X)
+    double y[3];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0] + w3*x[3][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1] + w3*x[3][1];
+    y[2] = w0*x[0][2] + w1*x[1][2] + w2*x[2][2] + w3*x[3][2];
+    
+    // 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 solitarywave3d_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 solitarywave3d_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];
+    vertex_values[3] = dof_values[3];
+}
+
+/// Return the number of sub elements (for a mixed element)
+unsigned int solitarywave3d_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* solitarywave3d_1_finite_element_1_1::create_sub_element(unsigned int i) const
+{
+    return new solitarywave3d_1_finite_element_1_1();
+}
+
+
+/// Constructor
+solitarywave3d_1_finite_element_1::solitarywave3d_1_finite_element_1() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+solitarywave3d_1_finite_element_1::~solitarywave3d_1_finite_element_1()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* solitarywave3d_1_finite_element_1::signature() const
+{
+    return "MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) })";
+}
+
+/// Return the cell shape
+ufc::shape solitarywave3d_1_finite_element_1::cell_shape() const
+{
+    return ufc::tetrahedron;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int solitarywave3d_1_finite_element_1::space_dimension() const
+{
+    return 20;
+}
+
+/// Return the rank of the value space
+unsigned int solitarywave3d_1_finite_element_1::value_rank() const
+{
+    return 1;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int solitarywave3d_1_finite_element_1::value_dimension(unsigned int i) const
+{
+    return 2;
+}
+
+/// Evaluate basis function i at given point in cell
+void solitarywave3d_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_02 = element_coordinates[3][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];
+    const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
+    const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
+    const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
+    const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
+    
+    // Compute sub determinants
+    const double d00 = J_11*J_22 - J_12*J_21;
+    const double d01 = J_12*J_20 - J_10*J_22;
+    const double d02 = J_10*J_21 - J_11*J_20;
+    
+    const double d10 = J_02*J_21 - J_01*J_22;
+    const double d11 = J_00*J_22 - J_02*J_20;
+    const double d12 = J_01*J_20 - J_00*J_21;
+    
+    const double d20 = J_01*J_12 - J_02*J_11;
+    const double d21 = J_02*J_10 - J_00*J_12;
+    const double d22 = J_00*J_11 - J_01*J_10;
+    
+    // Compute determinant of Jacobian
+    double detJ = J_00*d00 + J_10*d10 + J_20*d20;
+    
+    // Compute inverse of Jacobian
+    
+    // Compute constants
+    const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
+                    + d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
+                    + d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
+    
+    const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
+                    + d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
+                    + d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
+    
+    const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
+                    + d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
+                    + d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
+    
+    // Get coordinates and map to the UFC reference element
+    double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
+    double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
+    double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
+    
+    // Map coordinates to the reference cube
+    if (std::abs(y + z - 1.0) < 1e-14)
+      x = 1.0;
+    else
+      x = -2.0 * x/(y + z - 1.0) - 1.0;
+    if (std::abs(z - 1.0) < 1e-14)
+      y = -1.0;
+    else
+      y = 2.0 * y/(1.0 - z) - 1.0;
+    z = 2.0 * z - 1.0;
+    
+    // Reset values
+    values[0] = 0;
+    values[1] = 0;
+    
+    if (0 <= i && i <= 9)
+    {
+      // 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);
+      const double scalings_z_0 = 1;
+      const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
+      const double scalings_z_2 = scalings_z_1*(0.5 - 0.5*z);
+    
+      // 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 psitilde_cs
+      const double psitilde_cs_00_0 = 1;
+      const double psitilde_cs_00_1 = 2*z + 1;
+      const double psitilde_cs_00_2 = 0.3125*psitilde_cs_00_1 + 1.875*z*psitilde_cs_00_1 - 0.5625*psitilde_cs_00_0;
+      const double psitilde_cs_01_0 = 1;
+      const double psitilde_cs_01_1 = 3*z + 2;
+      const double psitilde_cs_02_0 = 1;
+      const double psitilde_cs_10_0 = 1;
+      const double psitilde_cs_10_1 = 3*z + 2;
+      const double psitilde_cs_11_0 = 1;
+      const double psitilde_cs_20_0 = 1;
+    
+      // Compute basisvalues
+      const double basisvalue0 = 0.866025403784439*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
+      const double basisvalue1 = 2.73861278752583*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
+      const double basisvalue2 = 1.58113883008419*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
+      const double basisvalue3 = 1.11803398874989*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
+      const double basisvalue4 = 5.1234753829798*psitilde_a_2*scalings_y_2*psitilde_bs_2_0*scalings_z_2*psitilde_cs_20_0;
+      const double basisvalue5 = 3.96862696659689*psitilde_a_1*scalings_y_1*psitilde_bs_1_1*scalings_z_2*psitilde_cs_11_0;
+      const double basisvalue6 = 2.29128784747792*psitilde_a_0*scalings_y_0*psitilde_bs_0_2*scalings_z_2*psitilde_cs_02_0;
+      const double basisvalue7 = 3.24037034920393*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_1;
+      const double basisvalue8 = 1.87082869338697*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_1;
+      const double basisvalue9 = 1.3228756555323*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_2;
+    
+      // Table(s) of coefficients
+      static const double coefficients0[10][10] =   \
+      {{-0.0577350269189626, -0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, 0.0503952630678969, 0.0290957186981323, 0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
+      {-0.0577350269189625, 0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, -0.050395263067897, 0.0290957186981323, -0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
+      {-0.0577350269189625, 0, 0.0702728368926306, -0.0248451997499977, 0, 0, 0.0872871560943969, 0, -0.0475131096733199, 0.0167984210226323},
+      {-0.0577350269189626, 0, 0, 0.074535599249993, 0, 0, 0, 0, 0, 0.100790526135794},
+      {0.23094010767585, 0, 0.140545673785261, 0.0993807989999906, 0, 0, 0, 0, 0.1187827741833, -0.0671936840905293},
+      {0.230940107675851, 0.121716123890037, -0.0702728368926306, 0.0993807989999907, 0, 0, 0, 0.102868899974728, -0.0593913870916499, -0.0671936840905293},
+      {0.23094010767585, 0.121716123890037, 0.0702728368926307, -0.0993807989999907, 0, 0.100790526135794, -0.087287156094397, -0.0205737799949456, -0.01187827741833, 0.0167984210226323},
+      {0.23094010767585, -0.121716123890037, -0.0702728368926307, 0.0993807989999906, 0, 0, 0, -0.102868899974728, -0.0593913870916499, -0.0671936840905293},
+      {0.23094010767585, -0.121716123890037, 0.0702728368926306, -0.0993807989999906, 0, -0.100790526135794, -0.0872871560943969, 0.0205737799949456, -0.01187827741833, 0.0167984210226323},
+      {0.23094010767585, 0, -0.140545673785261, -0.0993807989999906, -0.130120009726471, 0, 0.0290957186981323, 0, 0.02375655483666, 0.0167984210226323}};
+    
+      // 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];
+      const double coeff0_6 =   coefficients0[dof][6];
+      const double coeff0_7 =   coefficients0[dof][7];
+      const double coeff0_8 =   coefficients0[dof][8];
+      const double coeff0_9 =   coefficients0[dof][9];
+    
+      // Compute value(s)
+      values[0] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5 + coeff0_6*basisvalue6 + coeff0_7*basisvalue7 + coeff0_8*basisvalue8 + coeff0_9*basisvalue9;
+    }
+    
+    if (10 <= i && i <= 19)
+    {
+      // Map degree of freedom to element degree of freedom
+      const unsigned int dof = i - 10;
+    
+      // 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);
+      const double scalings_z_0 = 1;
+      const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
+      const double scalings_z_2 = scalings_z_1*(0.5 - 0.5*z);
+    
+      // 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 psitilde_cs
+      const double psitilde_cs_00_0 = 1;
+      const double psitilde_cs_00_1 = 2*z + 1;
+      const double psitilde_cs_00_2 = 0.3125*psitilde_cs_00_1 + 1.875*z*psitilde_cs_00_1 - 0.5625*psitilde_cs_00_0;
+      const double psitilde_cs_01_0 = 1;
+      const double psitilde_cs_01_1 = 3*z + 2;
+      const double psitilde_cs_02_0 = 1;
+      const double psitilde_cs_10_0 = 1;
+      const double psitilde_cs_10_1 = 3*z + 2;
+      const double psitilde_cs_11_0 = 1;
+      const double psitilde_cs_20_0 = 1;
+    
+      // Compute basisvalues
+      const double basisvalue0 = 0.866025403784439*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
+      const double basisvalue1 = 2.73861278752583*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
+      const double basisvalue2 = 1.58113883008419*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
+      const double basisvalue3 = 1.11803398874989*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
+      const double basisvalue4 = 5.1234753829798*psitilde_a_2*scalings_y_2*psitilde_bs_2_0*scalings_z_2*psitilde_cs_20_0;
+      const double basisvalue5 = 3.96862696659689*psitilde_a_1*scalings_y_1*psitilde_bs_1_1*scalings_z_2*psitilde_cs_11_0;
+      const double basisvalue6 = 2.29128784747792*psitilde_a_0*scalings_y_0*psitilde_bs_0_2*scalings_z_2*psitilde_cs_02_0;
+      const double basisvalue7 = 3.24037034920393*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_1;
+      const double basisvalue8 = 1.87082869338697*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_1;
+      const double basisvalue9 = 1.3228756555323*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_2;
+    
+      // Table(s) of coefficients
+      static const double coefficients0[10][10] =   \
+      {{-0.0577350269189626, -0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, 0.0503952630678969, 0.0290957186981323, 0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
+      {-0.0577350269189625, 0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, -0.050395263067897, 0.0290957186981323, -0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
+      {-0.0577350269189625, 0, 0.0702728368926306, -0.0248451997499977, 0, 0, 0.0872871560943969, 0, -0.0475131096733199, 0.0167984210226323},
+      {-0.0577350269189626, 0, 0, 0.074535599249993, 0, 0, 0, 0, 0, 0.100790526135794},
+      {0.23094010767585, 0, 0.140545673785261, 0.0993807989999906, 0, 0, 0, 0, 0.1187827741833, -0.0671936840905293},
+      {0.230940107675851, 0.121716123890037, -0.0702728368926306, 0.0993807989999907, 0, 0, 0, 0.102868899974728, -0.0593913870916499, -0.0671936840905293},
+      {0.23094010767585, 0.121716123890037, 0.0702728368926307, -0.0993807989999907, 0, 0.100790526135794, -0.087287156094397, -0.0205737799949456, -0.01187827741833, 0.0167984210226323},
+      {0.23094010767585, -0.121716123890037, -0.0702728368926307, 0.0993807989999906, 0, 0, 0, -0.102868899974728, -0.0593913870916499, -0.0671936840905293},
+      {0.23094010767585, -0.121716123890037, 0.0702728368926306, -0.0993807989999906, 0, -0.100790526135794, -0.0872871560943969, 0.0205737799949456, -0.01187827741833, 0.0167984210226323},
+      {0.23094010767585, 0, -0.140545673785261, -0.0993807989999906, -0.130120009726471, 0, 0.0290957186981323, 0, 0.02375655483666, 0.0167984210226323}};
+    
+      // 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];
+      const double coeff0_6 =   coefficients0[dof][6];
+      const double coeff0_7 =   coefficients0[dof][7];
+      const double coeff0_8 =   coefficients0[dof][8];
+      const double coeff0_9 =   coefficients0[dof][9];
+    
+      // Compute value(s)
+      values[1] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5 + coeff0_6*basisvalue6 + coeff0_7*basisvalue7 + coeff0_8*basisvalue8 + coeff0_9*basisvalue9;
+    }
+    
+}
+
+/// Evaluate all basis functions at given point in cell
+void solitarywave3d_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 solitarywave3d_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_02 = element_coordinates[3][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];
+    const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
+    const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
+    const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
+    const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
+    
+    // Compute sub determinants
+    const double d00 = J_11*J_22 - J_12*J_21;
+    const double d01 = J_12*J_20 - J_10*J_22;
+    const double d02 = J_10*J_21 - J_11*J_20;
+    
+    const double d10 = J_02*J_21 - J_01*J_22;
+    const double d11 = J_00*J_22 - J_02*J_20;
+    const double d12 = J_01*J_20 - J_00*J_21;
+    
+    const double d20 = J_01*J_12 - J_02*J_11;
+    const double d21 = J_02*J_10 - J_00*J_12;
+    const double d22 = J_00*J_11 - J_01*J_10;
+    
+    // Compute determinant of Jacobian
+    double detJ = J_00*d00 + J_10*d10 + J_20*d20;
+    
+    // Compute inverse of Jacobian
+    
+    // Compute constants
+    const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
+                    + d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
+                    + d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
+    
+    const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
+                    + d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
+                    + d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
+    
+    const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
+                    + d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
+                    + d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
+    
+    // Get coordinates and map to the UFC reference element
+    double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
+    double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
+    double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
+    
+    // Map coordinates to the reference cube
+    if (std::abs(y + z - 1.0) < 1e-14)
+      x = 1.0;
+    else
+      x = -2.0 * x/(y + z - 1.0) - 1.0;
+    if (std::abs(z - 1.0) < 1e-14)
+      y = -1.0;
+    else
+      y = 2.0 * y/(1.0 - z) - 1.0;
+    z = 2.0 * z - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 3;
+    
+    
+    // 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 > 2)
+            combinations[row][col] = 0;
+          else
+          {
+            combinations[row][col] += 1;
+            break;
+          }
+        }
+      }
+    }
+    
+    // Compute inverse of Jacobian
+    const double Jinv[3][3] ={{d00 / detJ, d10 / detJ, d20 / detJ}, {d01 / detJ, d11 / detJ, d21 / detJ}, {d02 / detJ, d12 / detJ, d22 / 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 <= 9)
+    {
+      // 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);
+      const double scalings_z_0 = 1;
+      const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
+      const double scalings_z_2 = scalings_z_1*(0.5 - 0.5*z);
+    
+      // 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 psitilde_cs
+      const double psitilde_cs_00_0 = 1;
+      const double psitilde_cs_00_1 = 2*z + 1;
+      const double psitilde_cs_00_2 = 0.3125*psitilde_cs_00_1 + 1.875*z*psitilde_cs_00_1 - 0.5625*psitilde_cs_00_0;
+      const double psitilde_cs_01_0 = 1;
+      const double psitilde_cs_01_1 = 3*z + 2;
+      const double psitilde_cs_02_0 = 1;
+      const double psitilde_cs_10_0 = 1;
+      const double psitilde_cs_10_1 = 3*z + 2;
+      const double psitilde_cs_11_0 = 1;
+      const double psitilde_cs_20_0 = 1;
+    
+      // Compute basisvalues
+      const double basisvalue0 = 0.866025403784439*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
+      const double basisvalue1 = 2.73861278752583*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
+      const double basisvalue2 = 1.58113883008419*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
+      const double basisvalue3 = 1.11803398874989*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
+      const double basisvalue4 = 5.1234753829798*psitilde_a_2*scalings_y_2*psitilde_bs_2_0*scalings_z_2*psitilde_cs_20_0;
+      const double basisvalue5 = 3.96862696659689*psitilde_a_1*scalings_y_1*psitilde_bs_1_1*scalings_z_2*psitilde_cs_11_0;
+      const double basisvalue6 = 2.29128784747792*psitilde_a_0*scalings_y_0*psitilde_bs_0_2*scalings_z_2*psitilde_cs_02_0;
+      const double basisvalue7 = 3.24037034920393*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_1;
+      const double basisvalue8 = 1.87082869338697*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_1;
+      const double basisvalue9 = 1.3228756555323*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_2;
+    
+      // Table(s) of coefficients
+      static const double coefficients0[10][10] =   \
+      {{-0.0577350269189626, -0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, 0.0503952630678969, 0.0290957186981323, 0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
+      {-0.0577350269189625, 0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, -0.050395263067897, 0.0290957186981323, -0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
+      {-0.0577350269189625, 0, 0.0702728368926306, -0.0248451997499977, 0, 0, 0.0872871560943969, 0, -0.0475131096733199, 0.0167984210226323},
+      {-0.0577350269189626, 0, 0, 0.074535599249993, 0, 0, 0, 0, 0, 0.100790526135794},
+      {0.23094010767585, 0, 0.140545673785261, 0.0993807989999906, 0, 0, 0, 0, 0.1187827741833, -0.0671936840905293},
+      {0.230940107675851, 0.121716123890037, -0.0702728368926306, 0.0993807989999907, 0, 0, 0, 0.102868899974728, -0.0593913870916499, -0.0671936840905293},
+      {0.23094010767585, 0.121716123890037, 0.0702728368926307, -0.0993807989999907, 0, 0.100790526135794, -0.087287156094397, -0.0205737799949456, -0.01187827741833, 0.0167984210226323},
+      {0.23094010767585, -0.121716123890037, -0.0702728368926307, 0.0993807989999906, 0, 0, 0, -0.102868899974728, -0.0593913870916499, -0.0671936840905293},
+      {0.23094010767585, -0.121716123890037, 0.0702728368926306, -0.0993807989999906, 0, -0.100790526135794, -0.0872871560943969, 0.0205737799949456, -0.01187827741833, 0.0167984210226323},
+      {0.23094010767585, 0, -0.140545673785261, -0.0993807989999906, -0.130120009726471, 0, 0.0290957186981323, 0, 0.02375655483666, 0.0167984210226323}};
+    
+      // Interesting (new) part
+      // Tables of derivatives of the polynomial base (transpose)
+      static const double dmats0[10][10] =   \
+      {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+      {6.32455532033676, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+      {0, 11.2249721603218, 0, 0, 0, 0, 0, 0, 0, 0},
+      {4.58257569495584, 0, 8.36660026534076, -1.18321595661992, 0, 0, 0, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+      {3.74165738677394, 0, 0, 8.69482604771366, 0, 0, 0, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
+    
+      static const double dmats1[10][10] =   \
+      {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+      {3.16227766016838, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+      {5.47722557505166, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+      {2.95803989154981, 5.61248608016091, -1.08012344973464, -0.763762615825974, 0, 0, 0, 0, 0, 0},
+      {2.29128784747792, 7.24568837309472, 4.18330013267038, -0.591607978309962, 0, 0, 0, 0, 0, 0},
+      {-2.64575131106459, 0, 9.66091783079296, 0.683130051063974, 0, 0, 0, 0, 0, 0},
+      {1.87082869338697, 0, 0, 4.34741302385683, 0, 0, 0, 0, 0, 0},
+      {3.24037034920393, 0, 0, 7.52994023880668, 0, 0, 0, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
+    
+      static const double dmats2[10][10] =   \
+      {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+      {3.16227766016838, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+      {1.82574185835055, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+      {5.16397779494322, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+      {2.95803989154981, 5.61248608016091, -1.08012344973464, -0.763762615825974, 0, 0, 0, 0, 0, 0},
+      {2.29128784747792, 1.44913767461894, 4.18330013267038, -0.591607978309962, 0, 0, 0, 0, 0, 0},
+      {1.32287565553229, 0, 3.86436713231718, -0.341565025531986, 0, 0, 0, 0, 0, 0},
+      {1.87082869338697, 7.09929573971954, 0, 4.34741302385683, 0, 0, 0, 0, 0, 0},
+      {1.08012344973464, 0, 7.09929573971954, 2.50998007960223, 0, 0, 0, 0, 0, 0},
+      {-3.81881307912987, 0, 0, 8.87411967464942, 0, 0, 0, 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;
+      double coeff0_6 = 0;
+      double coeff0_7 = 0;
+      double coeff0_8 = 0;
+      double coeff0_9 = 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;
+      double new_coeff0_6 = 0;
+      double new_coeff0_7 = 0;
+      double new_coeff0_8 = 0;
+      double new_coeff0_9 = 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];
+        new_coeff0_6 = coefficients0[dof][6];
+        new_coeff0_7 = coefficients0[dof][7];
+        new_coeff0_8 = coefficients0[dof][8];
+        new_coeff0_9 = coefficients0[dof][9];
+    
+        // 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;
+          coeff0_6 = new_coeff0_6;
+          coeff0_7 = new_coeff0_7;
+          coeff0_8 = new_coeff0_8;
+          coeff0_9 = new_coeff0_9;
+    
+          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] + coeff0_6*dmats0[6][0] + coeff0_7*dmats0[7][0] + coeff0_8*dmats0[8][0] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][1] + coeff0_7*dmats0[7][1] + coeff0_8*dmats0[8][1] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][2] + coeff0_7*dmats0[7][2] + coeff0_8*dmats0[8][2] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][3] + coeff0_7*dmats0[7][3] + coeff0_8*dmats0[8][3] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][4] + coeff0_7*dmats0[7][4] + coeff0_8*dmats0[8][4] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][5] + coeff0_7*dmats0[7][5] + coeff0_8*dmats0[8][5] + coeff0_9*dmats0[9][5];
+            new_coeff0_6 = coeff0_0*dmats0[0][6] + coeff0_1*dmats0[1][6] + coeff0_2*dmats0[2][6] + coeff0_3*dmats0[3][6] + coeff0_4*dmats0[4][6] + coeff0_5*dmats0[5][6] + coeff0_6*dmats0[6][6] + coeff0_7*dmats0[7][6] + coeff0_8*dmats0[8][6] + coeff0_9*dmats0[9][6];
+            new_coeff0_7 = coeff0_0*dmats0[0][7] + coeff0_1*dmats0[1][7] + coeff0_2*dmats0[2][7] + coeff0_3*dmats0[3][7] + coeff0_4*dmats0[4][7] + coeff0_5*dmats0[5][7] + coeff0_6*dmats0[6][7] + coeff0_7*dmats0[7][7] + coeff0_8*dmats0[8][7] + coeff0_9*dmats0[9][7];
+            new_coeff0_8 = coeff0_0*dmats0[0][8] + coeff0_1*dmats0[1][8] + coeff0_2*dmats0[2][8] + coeff0_3*dmats0[3][8] + coeff0_4*dmats0[4][8] + coeff0_5*dmats0[5][8] + coeff0_6*dmats0[6][8] + coeff0_7*dmats0[7][8] + coeff0_8*dmats0[8][8] + coeff0_9*dmats0[9][8];
+            new_coeff0_9 = coeff0_0*dmats0[0][9] + coeff0_1*dmats0[1][9] + coeff0_2*dmats0[2][9] + coeff0_3*dmats0[3][9] + coeff0_4*dmats0[4][9] + coeff0_5*dmats0[5][9] + coeff0_6*dmats0[6][9] + coeff0_7*dmats0[7][9] + coeff0_8*dmats0[8][9] + coeff0_9*dmats0[9][9];
+          }
+          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] + coeff0_6*dmats1[6][0] + coeff0_7*dmats1[7][0] + coeff0_8*dmats1[8][0] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][1] + coeff0_7*dmats1[7][1] + coeff0_8*dmats1[8][1] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][2] + coeff0_7*dmats1[7][2] + coeff0_8*dmats1[8][2] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][3] + coeff0_7*dmats1[7][3] + coeff0_8*dmats1[8][3] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][4] + coeff0_7*dmats1[7][4] + coeff0_8*dmats1[8][4] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][5] + coeff0_7*dmats1[7][5] + coeff0_8*dmats1[8][5] + coeff0_9*dmats1[9][5];
+            new_coeff0_6 = coeff0_0*dmats1[0][6] + coeff0_1*dmats1[1][6] + coeff0_2*dmats1[2][6] + coeff0_3*dmats1[3][6] + coeff0_4*dmats1[4][6] + coeff0_5*dmats1[5][6] + coeff0_6*dmats1[6][6] + coeff0_7*dmats1[7][6] + coeff0_8*dmats1[8][6] + coeff0_9*dmats1[9][6];
+            new_coeff0_7 = coeff0_0*dmats1[0][7] + coeff0_1*dmats1[1][7] + coeff0_2*dmats1[2][7] + coeff0_3*dmats1[3][7] + coeff0_4*dmats1[4][7] + coeff0_5*dmats1[5][7] + coeff0_6*dmats1[6][7] + coeff0_7*dmats1[7][7] + coeff0_8*dmats1[8][7] + coeff0_9*dmats1[9][7];
+            new_coeff0_8 = coeff0_0*dmats1[0][8] + coeff0_1*dmats1[1][8] + coeff0_2*dmats1[2][8] + coeff0_3*dmats1[3][8] + coeff0_4*dmats1[4][8] + coeff0_5*dmats1[5][8] + coeff0_6*dmats1[6][8] + coeff0_7*dmats1[7][8] + coeff0_8*dmats1[8][8] + coeff0_9*dmats1[9][8];
+            new_coeff0_9 = coeff0_0*dmats1[0][9] + coeff0_1*dmats1[1][9] + coeff0_2*dmats1[2][9] + coeff0_3*dmats1[3][9] + coeff0_4*dmats1[4][9] + coeff0_5*dmats1[5][9] + coeff0_6*dmats1[6][9] + coeff0_7*dmats1[7][9] + coeff0_8*dmats1[8][9] + coeff0_9*dmats1[9][9];
+          }
+          if(combinations[deriv_num][j] == 2)
+          {
+            new_coeff0_0 = coeff0_0*dmats2[0][0] + coeff0_1*dmats2[1][0] + coeff0_2*dmats2[2][0] + coeff0_3*dmats2[3][0] + coeff0_4*dmats2[4][0] + coeff0_5*dmats2[5][0] + coeff0_6*dmats2[6][0] + coeff0_7*dmats2[7][0] + coeff0_8*dmats2[8][0] + coeff0_9*dmats2[9][0];
+            new_coeff0_1 = coeff0_0*dmats2[0][1] + coeff0_1*dmats2[1][1] + coeff0_2*dmats2[2][1] + coeff0_3*dmats2[3][1] + coeff0_4*dmats2[4][1] + coeff0_5*dmats2[5][1] + coeff0_6*dmats2[6][1] + coeff0_7*dmats2[7][1] + coeff0_8*dmats2[8][1] + coeff0_9*dmats2[9][1];
+            new_coeff0_2 = coeff0_0*dmats2[0][2] + coeff0_1*dmats2[1][2] + coeff0_2*dmats2[2][2] + coeff0_3*dmats2[3][2] + coeff0_4*dmats2[4][2] + coeff0_5*dmats2[5][2] + coeff0_6*dmats2[6][2] + coeff0_7*dmats2[7][2] + coeff0_8*dmats2[8][2] + coeff0_9*dmats2[9][2];
+            new_coeff0_3 = coeff0_0*dmats2[0][3] + coeff0_1*dmats2[1][3] + coeff0_2*dmats2[2][3] + coeff0_3*dmats2[3][3] + coeff0_4*dmats2[4][3] + coeff0_5*dmats2[5][3] + coeff0_6*dmats2[6][3] + coeff0_7*dmats2[7][3] + coeff0_8*dmats2[8][3] + coeff0_9*dmats2[9][3];
+            new_coeff0_4 = coeff0_0*dmats2[0][4] + coeff0_1*dmats2[1][4] + coeff0_2*dmats2[2][4] + coeff0_3*dmats2[3][4] + coeff0_4*dmats2[4][4] + coeff0_5*dmats2[5][4] + coeff0_6*dmats2[6][4] + coeff0_7*dmats2[7][4] + coeff0_8*dmats2[8][4] + coeff0_9*dmats2[9][4];
+            new_coeff0_5 = coeff0_0*dmats2[0][5] + coeff0_1*dmats2[1][5] + coeff0_2*dmats2[2][5] + coeff0_3*dmats2[3][5] + coeff0_4*dmats2[4][5] + coeff0_5*dmats2[5][5] + coeff0_6*dmats2[6][5] + coeff0_7*dmats2[7][5] + coeff0_8*dmats2[8][5] + coeff0_9*dmats2[9][5];
+            new_coeff0_6 = coeff0_0*dmats2[0][6] + coeff0_1*dmats2[1][6] + coeff0_2*dmats2[2][6] + coeff0_3*dmats2[3][6] + coeff0_4*dmats2[4][6] + coeff0_5*dmats2[5][6] + coeff0_6*dmats2[6][6] + coeff0_7*dmats2[7][6] + coeff0_8*dmats2[8][6] + coeff0_9*dmats2[9][6];
+            new_coeff0_7 = coeff0_0*dmats2[0][7] + coeff0_1*dmats2[1][7] + coeff0_2*dmats2[2][7] + coeff0_3*dmats2[3][7] + coeff0_4*dmats2[4][7] + coeff0_5*dmats2[5][7] + coeff0_6*dmats2[6][7] + coeff0_7*dmats2[7][7] + coeff0_8*dmats2[8][7] + coeff0_9*dmats2[9][7];
+            new_coeff0_8 = coeff0_0*dmats2[0][8] + coeff0_1*dmats2[1][8] + coeff0_2*dmats2[2][8] + coeff0_3*dmats2[3][8] + coeff0_4*dmats2[4][8] + coeff0_5*dmats2[5][8] + coeff0_6*dmats2[6][8] + coeff0_7*dmats2[7][8] + coeff0_8*dmats2[8][8] + coeff0_9*dmats2[9][8];
+            new_coeff0_9 = coeff0_0*dmats2[0][9] + coeff0_1*dmats2[1][9] + coeff0_2*dmats2[2][9] + coeff0_3*dmats2[3][9] + coeff0_4*dmats2[4][9] + coeff0_5*dmats2[5][9] + coeff0_6*dmats2[6][9] + coeff0_7*dmats2[7][9] + coeff0_8*dmats2[8][9] + coeff0_9*dmats2[9][9];
+          }
+    
+        }
+        // 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 + new_coeff0_6*basisvalue6 + new_coeff0_7*basisvalue7 + new_coeff0_8*basisvalue8 + new_coeff0_9*basisvalue9;
+      }
+    
+      // 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 (10 <= i && i <= 19)
+    {
+      // Map degree of freedom to element degree of freedom
+      const unsigned int dof = i - 10;
+    
+      // 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);
+      const double scalings_z_0 = 1;
+      const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
+      const double scalings_z_2 = scalings_z_1*(0.5 - 0.5*z);
+    
+      // 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 psitilde_cs
+      const double psitilde_cs_00_0 = 1;
+      const double psitilde_cs_00_1 = 2*z + 1;
+      const double psitilde_cs_00_2 = 0.3125*psitilde_cs_00_1 + 1.875*z*psitilde_cs_00_1 - 0.5625*psitilde_cs_00_0;
+      const double psitilde_cs_01_0 = 1;
+      const double psitilde_cs_01_1 = 3*z + 2;
+      const double psitilde_cs_02_0 = 1;
+      const double psitilde_cs_10_0 = 1;
+      const double psitilde_cs_10_1 = 3*z + 2;
+      const double psitilde_cs_11_0 = 1;
+      const double psitilde_cs_20_0 = 1;
+    
+      // Compute basisvalues
+      const double basisvalue0 = 0.866025403784439*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
+      const double basisvalue1 = 2.73861278752583*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
+      const double basisvalue2 = 1.58113883008419*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
+      const double basisvalue3 = 1.11803398874989*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
+      const double basisvalue4 = 5.1234753829798*psitilde_a_2*scalings_y_2*psitilde_bs_2_0*scalings_z_2*psitilde_cs_20_0;
+      const double basisvalue5 = 3.96862696659689*psitilde_a_1*scalings_y_1*psitilde_bs_1_1*scalings_z_2*psitilde_cs_11_0;
+      const double basisvalue6 = 2.29128784747792*psitilde_a_0*scalings_y_0*psitilde_bs_0_2*scalings_z_2*psitilde_cs_02_0;
+      const double basisvalue7 = 3.24037034920393*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_1;
+      const double basisvalue8 = 1.87082869338697*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_1;
+      const double basisvalue9 = 1.3228756555323*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_2;
+    
+      // Table(s) of coefficients
+      static const double coefficients0[10][10] =   \
+      {{-0.0577350269189626, -0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, 0.0503952630678969, 0.0290957186981323, 0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
+      {-0.0577350269189625, 0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, -0.050395263067897, 0.0290957186981323, -0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
+      {-0.0577350269189625, 0, 0.0702728368926306, -0.0248451997499977, 0, 0, 0.0872871560943969, 0, -0.0475131096733199, 0.0167984210226323},
+      {-0.0577350269189626, 0, 0, 0.074535599249993, 0, 0, 0, 0, 0, 0.100790526135794},
+      {0.23094010767585, 0, 0.140545673785261, 0.0993807989999906, 0, 0, 0, 0, 0.1187827741833, -0.0671936840905293},
+      {0.230940107675851, 0.121716123890037, -0.0702728368926306, 0.0993807989999907, 0, 0, 0, 0.102868899974728, -0.0593913870916499, -0.0671936840905293},
+      {0.23094010767585, 0.121716123890037, 0.0702728368926307, -0.0993807989999907, 0, 0.100790526135794, -0.087287156094397, -0.0205737799949456, -0.01187827741833, 0.0167984210226323},
+      {0.23094010767585, -0.121716123890037, -0.0702728368926307, 0.0993807989999906, 0, 0, 0, -0.102868899974728, -0.0593913870916499, -0.0671936840905293},
+      {0.23094010767585, -0.121716123890037, 0.0702728368926306, -0.0993807989999906, 0, -0.100790526135794, -0.0872871560943969, 0.0205737799949456, -0.01187827741833, 0.0167984210226323},
+      {0.23094010767585, 0, -0.140545673785261, -0.0993807989999906, -0.130120009726471, 0, 0.0290957186981323, 0, 0.02375655483666, 0.0167984210226323}};
+    
+      // Interesting (new) part
+      // Tables of derivatives of the polynomial base (transpose)
+      static const double dmats0[10][10] =   \
+      {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+      {6.32455532033676, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+      {0, 11.2249721603218, 0, 0, 0, 0, 0, 0, 0, 0},
+      {4.58257569495584, 0, 8.36660026534076, -1.18321595661992, 0, 0, 0, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+      {3.74165738677394, 0, 0, 8.69482604771366, 0, 0, 0, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
+    
+      static const double dmats1[10][10] =   \
+      {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+      {3.16227766016838, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+      {5.47722557505166, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+      {2.95803989154981, 5.61248608016091, -1.08012344973464, -0.763762615825974, 0, 0, 0, 0, 0, 0},
+      {2.29128784747792, 7.24568837309472, 4.18330013267038, -0.591607978309962, 0, 0, 0, 0, 0, 0},
+      {-2.64575131106459, 0, 9.66091783079296, 0.683130051063974, 0, 0, 0, 0, 0, 0},
+      {1.87082869338697, 0, 0, 4.34741302385683, 0, 0, 0, 0, 0, 0},
+      {3.24037034920393, 0, 0, 7.52994023880668, 0, 0, 0, 0, 0, 0},
+      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
+    
+      static const double dmats2[10][10] =   \
+      {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+      {3.16227766016838, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+      {1.82574185835055, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+      {5.16397779494322, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+      {2.95803989154981, 5.61248608016091, -1.08012344973464, -0.763762615825974, 0, 0, 0, 0, 0, 0},
+      {2.29128784747792, 1.44913767461894, 4.18330013267038, -0.591607978309962, 0, 0, 0, 0, 0, 0},
+      {1.32287565553229, 0, 3.86436713231718, -0.341565025531986, 0, 0, 0, 0, 0, 0},
+      {1.87082869338697, 7.09929573971954, 0, 4.34741302385683, 0, 0, 0, 0, 0, 0},
+      {1.08012344973464, 0, 7.09929573971954, 2.50998007960223, 0, 0, 0, 0, 0, 0},
+      {-3.81881307912987, 0, 0, 8.87411967464942, 0, 0, 0, 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;
+      double coeff0_6 = 0;
+      double coeff0_7 = 0;
+      double coeff0_8 = 0;
+      double coeff0_9 = 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;
+      double new_coeff0_6 = 0;
+      double new_coeff0_7 = 0;
+      double new_coeff0_8 = 0;
+      double new_coeff0_9 = 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];
+        new_coeff0_6 = coefficients0[dof][6];
+        new_coeff0_7 = coefficients0[dof][7];
+        new_coeff0_8 = coefficients0[dof][8];
+        new_coeff0_9 = coefficients0[dof][9];
+    
+        // 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;
+          coeff0_6 = new_coeff0_6;
+          coeff0_7 = new_coeff0_7;
+          coeff0_8 = new_coeff0_8;
+          coeff0_9 = new_coeff0_9;
+    
+          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] + coeff0_6*dmats0[6][0] + coeff0_7*dmats0[7][0] + coeff0_8*dmats0[8][0] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][1] + coeff0_7*dmats0[7][1] + coeff0_8*dmats0[8][1] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][2] + coeff0_7*dmats0[7][2] + coeff0_8*dmats0[8][2] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][3] + coeff0_7*dmats0[7][3] + coeff0_8*dmats0[8][3] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][4] + coeff0_7*dmats0[7][4] + coeff0_8*dmats0[8][4] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][5] + coeff0_7*dmats0[7][5] + coeff0_8*dmats0[8][5] + coeff0_9*dmats0[9][5];
+            new_coeff0_6 = coeff0_0*dmats0[0][6] + coeff0_1*dmats0[1][6] + coeff0_2*dmats0[2][6] + coeff0_3*dmats0[3][6] + coeff0_4*dmats0[4][6] + coeff0_5*dmats0[5][6] + coeff0_6*dmats0[6][6] + coeff0_7*dmats0[7][6] + coeff0_8*dmats0[8][6] + coeff0_9*dmats0[9][6];
+            new_coeff0_7 = coeff0_0*dmats0[0][7] + coeff0_1*dmats0[1][7] + coeff0_2*dmats0[2][7] + coeff0_3*dmats0[3][7] + coeff0_4*dmats0[4][7] + coeff0_5*dmats0[5][7] + coeff0_6*dmats0[6][7] + coeff0_7*dmats0[7][7] + coeff0_8*dmats0[8][7] + coeff0_9*dmats0[9][7];
+            new_coeff0_8 = coeff0_0*dmats0[0][8] + coeff0_1*dmats0[1][8] + coeff0_2*dmats0[2][8] + coeff0_3*dmats0[3][8] + coeff0_4*dmats0[4][8] + coeff0_5*dmats0[5][8] + coeff0_6*dmats0[6][8] + coeff0_7*dmats0[7][8] + coeff0_8*dmats0[8][8] + coeff0_9*dmats0[9][8];
+            new_coeff0_9 = coeff0_0*dmats0[0][9] + coeff0_1*dmats0[1][9] + coeff0_2*dmats0[2][9] + coeff0_3*dmats0[3][9] + coeff0_4*dmats0[4][9] + coeff0_5*dmats0[5][9] + coeff0_6*dmats0[6][9] + coeff0_7*dmats0[7][9] + coeff0_8*dmats0[8][9] + coeff0_9*dmats0[9][9];
+          }
+          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] + coeff0_6*dmats1[6][0] + coeff0_7*dmats1[7][0] + coeff0_8*dmats1[8][0] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][1] + coeff0_7*dmats1[7][1] + coeff0_8*dmats1[8][1] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][2] + coeff0_7*dmats1[7][2] + coeff0_8*dmats1[8][2] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][3] + coeff0_7*dmats1[7][3] + coeff0_8*dmats1[8][3] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][4] + coeff0_7*dmats1[7][4] + coeff0_8*dmats1[8][4] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][5] + coeff0_7*dmats1[7][5] + coeff0_8*dmats1[8][5] + coeff0_9*dmats1[9][5];
+            new_coeff0_6 = coeff0_0*dmats1[0][6] + coeff0_1*dmats1[1][6] + coeff0_2*dmats1[2][6] + coeff0_3*dmats1[3][6] + coeff0_4*dmats1[4][6] + coeff0_5*dmats1[5][6] + coeff0_6*dmats1[6][6] + coeff0_7*dmats1[7][6] + coeff0_8*dmats1[8][6] + coeff0_9*dmats1[9][6];
+            new_coeff0_7 = coeff0_0*dmats1[0][7] + coeff0_1*dmats1[1][7] + coeff0_2*dmats1[2][7] + coeff0_3*dmats1[3][7] + coeff0_4*dmats1[4][7] + coeff0_5*dmats1[5][7] + coeff0_6*dmats1[6][7] + coeff0_7*dmats1[7][7] + coeff0_8*dmats1[8][7] + coeff0_9*dmats1[9][7];
+            new_coeff0_8 = coeff0_0*dmats1[0][8] + coeff0_1*dmats1[1][8] + coeff0_2*dmats1[2][8] + coeff0_3*dmats1[3][8] + coeff0_4*dmats1[4][8] + coeff0_5*dmats1[5][8] + coeff0_6*dmats1[6][8] + coeff0_7*dmats1[7][8] + coeff0_8*dmats1[8][8] + coeff0_9*dmats1[9][8];
+            new_coeff0_9 = coeff0_0*dmats1[0][9] + coeff0_1*dmats1[1][9] + coeff0_2*dmats1[2][9] + coeff0_3*dmats1[3][9] + coeff0_4*dmats1[4][9] + coeff0_5*dmats1[5][9] + coeff0_6*dmats1[6][9] + coeff0_7*dmats1[7][9] + coeff0_8*dmats1[8][9] + coeff0_9*dmats1[9][9];
+          }
+          if(combinations[deriv_num][j] == 2)
+          {
+            new_coeff0_0 = coeff0_0*dmats2[0][0] + coeff0_1*dmats2[1][0] + coeff0_2*dmats2[2][0] + coeff0_3*dmats2[3][0] + coeff0_4*dmats2[4][0] + coeff0_5*dmats2[5][0] + coeff0_6*dmats2[6][0] + coeff0_7*dmats2[7][0] + coeff0_8*dmats2[8][0] + coeff0_9*dmats2[9][0];
+            new_coeff0_1 = coeff0_0*dmats2[0][1] + coeff0_1*dmats2[1][1] + coeff0_2*dmats2[2][1] + coeff0_3*dmats2[3][1] + coeff0_4*dmats2[4][1] + coeff0_5*dmats2[5][1] + coeff0_6*dmats2[6][1] + coeff0_7*dmats2[7][1] + coeff0_8*dmats2[8][1] + coeff0_9*dmats2[9][1];
+            new_coeff0_2 = coeff0_0*dmats2[0][2] + coeff0_1*dmats2[1][2] + coeff0_2*dmats2[2][2] + coeff0_3*dmats2[3][2] + coeff0_4*dmats2[4][2] + coeff0_5*dmats2[5][2] + coeff0_6*dmats2[6][2] + coeff0_7*dmats2[7][2] + coeff0_8*dmats2[8][2] + coeff0_9*dmats2[9][2];
+            new_coeff0_3 = coeff0_0*dmats2[0][3] + coeff0_1*dmats2[1][3] + coeff0_2*dmats2[2][3] + coeff0_3*dmats2[3][3] + coeff0_4*dmats2[4][3] + coeff0_5*dmats2[5][3] + coeff0_6*dmats2[6][3] + coeff0_7*dmats2[7][3] + coeff0_8*dmats2[8][3] + coeff0_9*dmats2[9][3];
+            new_coeff0_4 = coeff0_0*dmats2[0][4] + coeff0_1*dmats2[1][4] + coeff0_2*dmats2[2][4] + coeff0_3*dmats2[3][4] + coeff0_4*dmats2[4][4] + coeff0_5*dmats2[5][4] + coeff0_6*dmats2[6][4] + coeff0_7*dmats2[7][4] + coeff0_8*dmats2[8][4] + coeff0_9*dmats2[9][4];
+            new_coeff0_5 = coeff0_0*dmats2[0][5] + coeff0_1*dmats2[1][5] + coeff0_2*dmats2[2][5] + coeff0_3*dmats2[3][5] + coeff0_4*dmats2[4][5] + coeff0_5*dmats2[5][5] + coeff0_6*dmats2[6][5] + coeff0_7*dmats2[7][5] + coeff0_8*dmats2[8][5] + coeff0_9*dmats2[9][5];
+            new_coeff0_6 = coeff0_0*dmats2[0][6] + coeff0_1*dmats2[1][6] + coeff0_2*dmats2[2][6] + coeff0_3*dmats2[3][6] + coeff0_4*dmats2[4][6] + coeff0_5*dmats2[5][6] + coeff0_6*dmats2[6][6] + coeff0_7*dmats2[7][6] + coeff0_8*dmats2[8][6] + coeff0_9*dmats2[9][6];
+            new_coeff0_7 = coeff0_0*dmats2[0][7] + coeff0_1*dmats2[1][7] + coeff0_2*dmats2[2][7] + coeff0_3*dmats2[3][7] + coeff0_4*dmats2[4][7] + coeff0_5*dmats2[5][7] + coeff0_6*dmats2[6][7] + coeff0_7*dmats2[7][7] + coeff0_8*dmats2[8][7] + coeff0_9*dmats2[9][7];
+            new_coeff0_8 = coeff0_0*dmats2[0][8] + coeff0_1*dmats2[1][8] + coeff0_2*dmats2[2][8] + coeff0_3*dmats2[3][8] + coeff0_4*dmats2[4][8] + coeff0_5*dmats2[5][8] + coeff0_6*dmats2[6][8] + coeff0_7*dmats2[7][8] + coeff0_8*dmats2[8][8] + coeff0_9*dmats2[9][8];
+            new_coeff0_9 = coeff0_0*dmats2[0][9] + coeff0_1*dmats2[1][9] + coeff0_2*dmats2[2][9] + coeff0_3*dmats2[3][9] + coeff0_4*dmats2[4][9] + coeff0_5*dmats2[5][9] + coeff0_6*dmats2[6][9] + coeff0_7*dmats2[7][9] + coeff0_8*dmats2[8][9] + coeff0_9*dmats2[9][9];
+          }
+    
+        }
+        // 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 + new_coeff0_6*basisvalue6 + new_coeff0_7*basisvalue7 + new_coeff0_8*basisvalue8 + new_coeff0_9*basisvalue9;
+      }
+    
+      // 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 solitarywave3d_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 solitarywave3d_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[20][1][3] = {{{0, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 0, 1}}, {{0, 0.5, 0.5}}, {{0.5, 0, 0.5}}, {{0.5, 0.5, 0}}, {{0, 0, 0.5}}, {{0, 0.5, 0}}, {{0.5, 0, 0}}, {{0, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 0, 1}}, {{0, 0.5, 0.5}}, {{0.5, 0, 0.5}}, {{0.5, 0.5, 0}}, {{0, 0, 0.5}}, {{0, 0.5, 0}}, {{0.5, 0, 0}}};
+    static const double W[20][1] = {{1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}};
+    static const double D[20][1][2] = {{{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{0, 1}}, {{0, 1}}, {{0, 1}}, {{0, 1}}, {{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] - X[i][0][2];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    const double w3 = X[i][0][2];
+    
+    // Compute affine mapping y = F(X)
+    double y[3];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0] + w3*x[3][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1] + w3*x[3][1];
+    y[2] = w0*x[0][2] + w1*x[1][2] + w2*x[2][2] + w3*x[3][2];
+    
+    // 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 solitarywave3d_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 solitarywave3d_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];
+    vertex_values[6] = dof_values[3];
+    // Evaluate at vertices and use affine mapping
+    vertex_values[1] = dof_values[10];
+    vertex_values[3] = dof_values[11];
+    vertex_values[5] = dof_values[12];
+    vertex_values[7] = dof_values[13];
+}
+
+/// Return the number of sub elements (for a mixed element)
+unsigned int solitarywave3d_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* solitarywave3d_1_finite_element_1::create_sub_element(unsigned int i) const
+{
+    switch ( i )
+    {
+    case 0:
+      return new solitarywave3d_1_finite_element_1_0();
+      break;
+    case 1:
+      return new solitarywave3d_1_finite_element_1_1();
+      break;
+    }
+    return 0;
+}
+
+
+/// Constructor
+solitarywave3d_1_finite_element_2::solitarywave3d_1_finite_element_2() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+solitarywave3d_1_finite_element_2::~solitarywave3d_1_finite_element_2()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* solitarywave3d_1_finite_element_2::signature() const
+{
+    return "FiniteElement('Discontinuous Lagrange', Cell('tetrahedron', 1, Space(3)), 0)";
+}
+
+/// Return the cell shape
+ufc::shape solitarywave3d_1_finite_element_2::cell_shape() const
+{
+    return ufc::tetrahedron;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int solitarywave3d_1_finite_element_2::space_dimension() const
+{
+    return 1;
+}
+
+/// Return the rank of the value space
+unsigned int solitarywave3d_1_finite_element_2::value_rank() const
+{
+    return 0;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int solitarywave3d_1_finite_element_2::value_dimension(unsigned int i) const
+{
+    return 1;
+}
+
+/// Evaluate basis function i at given point in cell
+void solitarywave3d_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_02 = element_coordinates[3][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];
+    const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
+    const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
+    const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
+    const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
+    
+    // Compute sub determinants
+    const double d00 = J_11*J_22 - J_12*J_21;
+    const double d01 = J_12*J_20 - J_10*J_22;
+    const double d02 = J_10*J_21 - J_11*J_20;
+    
+    const double d10 = J_02*J_21 - J_01*J_22;
+    const double d11 = J_00*J_22 - J_02*J_20;
+    const double d12 = J_01*J_20 - J_00*J_21;
+    
+    const double d20 = J_01*J_12 - J_02*J_11;
+    const double d21 = J_02*J_10 - J_00*J_12;
+    const double d22 = J_00*J_11 - J_01*J_10;
+    
+    // Compute determinant of Jacobian
+    double detJ = J_00*d00 + J_10*d10 + J_20*d20;
+    
+    // Compute inverse of Jacobian
+    
+    // Compute constants
+    const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
+                    + d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
+                    + d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
+    
+    const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
+                    + d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
+                    + d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
+    
+    const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
+                    + d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
+                    + d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
+    
+    // Get coordinates and map to the UFC reference element
+    double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
+    double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
+    double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
+    
+    // Map coordinates to the reference cube
+    if (std::abs(y + z - 1.0) < 1e-14)
+      x = 1.0;
+    else
+      x = -2.0 * x/(y + z - 1.0) - 1.0;
+    if (std::abs(z - 1.0) < 1e-14)
+      y = -1.0;
+    else
+      y = 2.0 * y/(1.0 - z) - 1.0;
+    z = 2.0 * z - 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_z_0 = 1;
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    
+    // Compute psitilde_cs
+    const double psitilde_cs_00_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.866025403784439*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[1][1] = \
+    {{1.15470053837925}};
+    
+    // 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 solitarywave3d_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 solitarywave3d_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_02 = element_coordinates[3][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];
+    const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
+    const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
+    const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
+    const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
+    
+    // Compute sub determinants
+    const double d00 = J_11*J_22 - J_12*J_21;
+    const double d01 = J_12*J_20 - J_10*J_22;
+    const double d02 = J_10*J_21 - J_11*J_20;
+    
+    const double d10 = J_02*J_21 - J_01*J_22;
+    const double d11 = J_00*J_22 - J_02*J_20;
+    const double d12 = J_01*J_20 - J_00*J_21;
+    
+    const double d20 = J_01*J_12 - J_02*J_11;
+    const double d21 = J_02*J_10 - J_00*J_12;
+    const double d22 = J_00*J_11 - J_01*J_10;
+    
+    // Compute determinant of Jacobian
+    double detJ = J_00*d00 + J_10*d10 + J_20*d20;
+    
+    // Compute inverse of Jacobian
+    
+    // Compute constants
+    const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
+                    + d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
+                    + d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
+    
+    const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
+                    + d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
+                    + d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
+    
+    const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
+                    + d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
+                    + d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
+    
+    // Get coordinates and map to the UFC reference element
+    double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
+    double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
+    double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
+    
+    // Map coordinates to the reference cube
+    if (std::abs(y + z - 1.0) < 1e-14)
+      x = 1.0;
+    else
+      x = -2.0 * x/(y + z - 1.0) - 1.0;
+    if (std::abs(z - 1.0) < 1e-14)
+      y = -1.0;
+    else
+      y = 2.0 * y/(1.0 - z) - 1.0;
+    z = 2.0 * z - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 3;
+    
+    
+    // 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 > 2)
+            combinations[row][col] = 0;
+          else
+          {
+            combinations[row][col] += 1;
+            break;
+          }
+        }
+      }
+    }
+    
+    // Compute inverse of Jacobian
+    const double Jinv[3][3] ={{d00 / detJ, d10 / detJ, d20 / detJ}, {d01 / detJ, d11 / detJ, d21 / detJ}, {d02 / detJ, d12 / detJ, d22 / 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_z_0 = 1;
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    
+    // Compute psitilde_cs
+    const double psitilde_cs_00_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.866025403784439*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[1][1] = \
+    {{1.15470053837925}};
+    
+    // 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}};
+    
+    static const double dmats2[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];
+        }
+        if(combinations[deriv_num][j] == 2)
+        {
+          new_coeff0_0 = coeff0_0*dmats2[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 solitarywave3d_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 solitarywave3d_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][3] = {{{0.25, 0.25, 0.25}}};
+    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] - X[i][0][2];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    const double w3 = X[i][0][2];
+    
+    // Compute affine mapping y = F(X)
+    double y[3];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0] + w3*x[3][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1] + w3*x[3][1];
+    y[2] = w0*x[0][2] + w1*x[1][2] + w2*x[2][2] + w3*x[3][2];
+    
+    // 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 solitarywave3d_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 solitarywave3d_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];
+    vertex_values[3] = dof_values[0];
+}
+
+/// Return the number of sub elements (for a mixed element)
+unsigned int solitarywave3d_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* solitarywave3d_1_finite_element_2::create_sub_element(unsigned int i) const
+{
+    return new solitarywave3d_1_finite_element_2();
+}
+
+
+/// Constructor
+solitarywave3d_1_finite_element_3::solitarywave3d_1_finite_element_3() : ufc::finite_element()
+{
+    // Do nothing
+}
+
+/// Destructor
+solitarywave3d_1_finite_element_3::~solitarywave3d_1_finite_element_3()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the finite element
+const char* solitarywave3d_1_finite_element_3::signature() const
+{
+    return "FiniteElement('Discontinuous Lagrange', Cell('tetrahedron', 1, Space(3)), 0)";
+}
+
+/// Return the cell shape
+ufc::shape solitarywave3d_1_finite_element_3::cell_shape() const
+{
+    return ufc::tetrahedron;
+}
+
+/// Return the dimension of the finite element function space
+unsigned int solitarywave3d_1_finite_element_3::space_dimension() const
+{
+    return 1;
+}
+
+/// Return the rank of the value space
+unsigned int solitarywave3d_1_finite_element_3::value_rank() const
+{
+    return 0;
+}
+
+/// Return the dimension of the value space for axis i
+unsigned int solitarywave3d_1_finite_element_3::value_dimension(unsigned int i) const
+{
+    return 1;
+}
+
+/// Evaluate basis function i at given point in cell
+void solitarywave3d_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_02 = element_coordinates[3][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];
+    const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
+    const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
+    const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
+    const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
+    
+    // Compute sub determinants
+    const double d00 = J_11*J_22 - J_12*J_21;
+    const double d01 = J_12*J_20 - J_10*J_22;
+    const double d02 = J_10*J_21 - J_11*J_20;
+    
+    const double d10 = J_02*J_21 - J_01*J_22;
+    const double d11 = J_00*J_22 - J_02*J_20;
+    const double d12 = J_01*J_20 - J_00*J_21;
+    
+    const double d20 = J_01*J_12 - J_02*J_11;
+    const double d21 = J_02*J_10 - J_00*J_12;
+    const double d22 = J_00*J_11 - J_01*J_10;
+    
+    // Compute determinant of Jacobian
+    double detJ = J_00*d00 + J_10*d10 + J_20*d20;
+    
+    // Compute inverse of Jacobian
+    
+    // Compute constants
+    const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
+                    + d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
+                    + d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
+    
+    const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
+                    + d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
+                    + d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
+    
+    const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
+                    + d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
+                    + d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
+    
+    // Get coordinates and map to the UFC reference element
+    double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
+    double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
+    double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
+    
+    // Map coordinates to the reference cube
+    if (std::abs(y + z - 1.0) < 1e-14)
+      x = 1.0;
+    else
+      x = -2.0 * x/(y + z - 1.0) - 1.0;
+    if (std::abs(z - 1.0) < 1e-14)
+      y = -1.0;
+    else
+      y = 2.0 * y/(1.0 - z) - 1.0;
+    z = 2.0 * z - 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_z_0 = 1;
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    
+    // Compute psitilde_cs
+    const double psitilde_cs_00_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.866025403784439*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[1][1] = \
+    {{1.15470053837925}};
+    
+    // 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 solitarywave3d_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 solitarywave3d_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_02 = element_coordinates[3][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];
+    const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
+    const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
+    const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
+    const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
+    
+    // Compute sub determinants
+    const double d00 = J_11*J_22 - J_12*J_21;
+    const double d01 = J_12*J_20 - J_10*J_22;
+    const double d02 = J_10*J_21 - J_11*J_20;
+    
+    const double d10 = J_02*J_21 - J_01*J_22;
+    const double d11 = J_00*J_22 - J_02*J_20;
+    const double d12 = J_01*J_20 - J_00*J_21;
+    
+    const double d20 = J_01*J_12 - J_02*J_11;
+    const double d21 = J_02*J_10 - J_00*J_12;
+    const double d22 = J_00*J_11 - J_01*J_10;
+    
+    // Compute determinant of Jacobian
+    double detJ = J_00*d00 + J_10*d10 + J_20*d20;
+    
+    // Compute inverse of Jacobian
+    
+    // Compute constants
+    const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
+                    + d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
+                    + d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
+    
+    const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
+                    + d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
+                    + d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
+    
+    const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
+                    + d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
+                    + d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
+    
+    // Get coordinates and map to the UFC reference element
+    double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
+    double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
+    double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
+    
+    // Map coordinates to the reference cube
+    if (std::abs(y + z - 1.0) < 1e-14)
+      x = 1.0;
+    else
+      x = -2.0 * x/(y + z - 1.0) - 1.0;
+    if (std::abs(z - 1.0) < 1e-14)
+      y = -1.0;
+    else
+      y = 2.0 * y/(1.0 - z) - 1.0;
+    z = 2.0 * z - 1.0;
+    
+    // Compute number of derivatives
+    unsigned int num_derivatives = 1;
+    
+    for (unsigned int j = 0; j < n; j++)
+      num_derivatives *= 3;
+    
+    
+    // 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 > 2)
+            combinations[row][col] = 0;
+          else
+          {
+            combinations[row][col] += 1;
+            break;
+          }
+        }
+      }
+    }
+    
+    // Compute inverse of Jacobian
+    const double Jinv[3][3] ={{d00 / detJ, d10 / detJ, d20 / detJ}, {d01 / detJ, d11 / detJ, d21 / detJ}, {d02 / detJ, d12 / detJ, d22 / 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_z_0 = 1;
+    
+    // Compute psitilde_a
+    const double psitilde_a_0 = 1;
+    
+    // Compute psitilde_bs
+    const double psitilde_bs_0_0 = 1;
+    
+    // Compute psitilde_cs
+    const double psitilde_cs_00_0 = 1;
+    
+    // Compute basisvalues
+    const double basisvalue0 = 0.866025403784439*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
+    
+    // Table(s) of coefficients
+    static const double coefficients0[1][1] = \
+    {{1.15470053837925}};
+    
+    // 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}};
+    
+    static const double dmats2[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];
+        }
+        if(combinations[deriv_num][j] == 2)
+        {
+          new_coeff0_0 = coeff0_0*dmats2[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 solitarywave3d_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 solitarywave3d_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][3] = {{{0.25, 0.25, 0.25}}};
+    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] - X[i][0][2];
+    const double w1 = X[i][0][0];
+    const double w2 = X[i][0][1];
+    const double w3 = X[i][0][2];
+    
+    // Compute affine mapping y = F(X)
+    double y[3];
+    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0] + w3*x[3][0];
+    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1] + w3*x[3][1];
+    y[2] = w0*x[0][2] + w1*x[1][2] + w2*x[2][2] + w3*x[3][2];
+    
+    // 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 solitarywave3d_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 solitarywave3d_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];
+    vertex_values[3] = dof_values[0];
+}
+
+/// Return the number of sub elements (for a mixed element)
+unsigned int solitarywave3d_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* solitarywave3d_1_finite_element_3::create_sub_element(unsigned int i) const
+{
+    return new solitarywave3d_1_finite_element_3();
+}
+
+/// Constructor
+solitarywave3d_1_dof_map_0_0::solitarywave3d_1_dof_map_0_0() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+solitarywave3d_1_dof_map_0_0::~solitarywave3d_1_dof_map_0_0()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* solitarywave3d_1_dof_map_0_0::signature() const
+{
+    return "FFC dof map for FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool solitarywave3d_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;
+    case 3:
+      return false;
+      break;
+    }
+    return false;
+}
+
+/// Initialize dof map for mesh (return true iff init_cell() is needed)
+bool solitarywave3d_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 solitarywave3d_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 solitarywave3d_1_dof_map_0_0::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int solitarywave3d_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 solitarywave3d_1_dof_map_0_0::local_dimension(const ufc::cell& c) const
+{
+    return 10;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int solitarywave3d_1_dof_map_0_0::max_local_dimension() const
+{
+    return 10;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int solitarywave3d_1_dof_map_0_0::geometric_dimension() const
+{
+    return 3;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int solitarywave3d_1_dof_map_0_0::num_facet_dofs() const
+{
+    return 6;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int solitarywave3d_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 solitarywave3d_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];
+    dofs[3] = c.entity_indices[0][3];
+    unsigned int offset = m.num_entities[0];
+    dofs[4] = offset + c.entity_indices[1][0];
+    dofs[5] = offset + c.entity_indices[1][1];
+    dofs[6] = offset + c.entity_indices[1][2];
+    dofs[7] = offset + c.entity_indices[1][3];
+    dofs[8] = offset + c.entity_indices[1][4];
+    dofs[9] = offset + c.entity_indices[1][5];
+}
+
+/// Tabulate the local-to-local mapping from facet dofs to cell dofs
+void solitarywave3d_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;
+      dofs[3] = 4;
+      dofs[4] = 5;
+      dofs[5] = 6;
+      break;
+    case 1:
+      dofs[0] = 0;
+      dofs[1] = 2;
+      dofs[2] = 3;
+      dofs[3] = 4;
+      dofs[4] = 7;
+      dofs[5] = 8;
+      break;
+    case 2:
+      dofs[0] = 0;
+      dofs[1] = 1;
+      dofs[2] = 3;
+      dofs[3] = 5;
+      dofs[4] = 7;
+      dofs[5] = 9;
+      break;
+    case 3:
+      dofs[0] = 0;
+      dofs[1] = 1;
+      dofs[2] = 2;
+      dofs[3] = 6;
+      dofs[4] = 8;
+      dofs[5] = 9;
+      break;
+    }
+}
+
+/// Tabulate the local-to-local mapping of dofs on entity (d, i)
+void solitarywave3d_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 solitarywave3d_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[0][2] = x[0][2];
+    coordinates[1][0] = x[1][0];
+    coordinates[1][1] = x[1][1];
+    coordinates[1][2] = x[1][2];
+    coordinates[2][0] = x[2][0];
+    coordinates[2][1] = x[2][1];
+    coordinates[2][2] = x[2][2];
+    coordinates[3][0] = x[3][0];
+    coordinates[3][1] = x[3][1];
+    coordinates[3][2] = x[3][2];
+    coordinates[4][0] = 0.5*x[2][0] + 0.5*x[3][0];
+    coordinates[4][1] = 0.5*x[2][1] + 0.5*x[3][1];
+    coordinates[4][2] = 0.5*x[2][2] + 0.5*x[3][2];
+    coordinates[5][0] = 0.5*x[1][0] + 0.5*x[3][0];
+    coordinates[5][1] = 0.5*x[1][1] + 0.5*x[3][1];
+    coordinates[5][2] = 0.5*x[1][2] + 0.5*x[3][2];
+    coordinates[6][0] = 0.5*x[1][0] + 0.5*x[2][0];
+    coordinates[6][1] = 0.5*x[1][1] + 0.5*x[2][1];
+    coordinates[6][2] = 0.5*x[1][2] + 0.5*x[2][2];
+    coordinates[7][0] = 0.5*x[0][0] + 0.5*x[3][0];
+    coordinates[7][1] = 0.5*x[0][1] + 0.5*x[3][1];
+    coordinates[7][2] = 0.5*x[0][2] + 0.5*x[3][2];
+    coordinates[8][0] = 0.5*x[0][0] + 0.5*x[2][0];
+    coordinates[8][1] = 0.5*x[0][1] + 0.5*x[2][1];
+    coordinates[8][2] = 0.5*x[0][2] + 0.5*x[2][2];
+    coordinates[9][0] = 0.5*x[0][0] + 0.5*x[1][0];
+    coordinates[9][1] = 0.5*x[0][1] + 0.5*x[1][1];
+    coordinates[9][2] = 0.5*x[0][2] + 0.5*x[1][2];
+}
+
+/// Return the number of sub dof maps (for a mixed element)
+unsigned int solitarywave3d_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* solitarywave3d_1_dof_map_0_0::create_sub_dof_map(unsigned int i) const
+{
+    return new solitarywave3d_1_dof_map_0_0();
+}
+
+
+/// Constructor
+solitarywave3d_1_dof_map_0_1::solitarywave3d_1_dof_map_0_1() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+solitarywave3d_1_dof_map_0_1::~solitarywave3d_1_dof_map_0_1()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* solitarywave3d_1_dof_map_0_1::signature() const
+{
+    return "FFC dof map for FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool solitarywave3d_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;
+    case 3:
+      return false;
+      break;
+    }
+    return false;
+}
+
+/// Initialize dof map for mesh (return true iff init_cell() is needed)
+bool solitarywave3d_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 solitarywave3d_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 solitarywave3d_1_dof_map_0_1::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int solitarywave3d_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 solitarywave3d_1_dof_map_0_1::local_dimension(const ufc::cell& c) const
+{
+    return 10;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int solitarywave3d_1_dof_map_0_1::max_local_dimension() const
+{
+    return 10;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int solitarywave3d_1_dof_map_0_1::geometric_dimension() const
+{
+    return 3;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int solitarywave3d_1_dof_map_0_1::num_facet_dofs() const
+{
+    return 6;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int solitarywave3d_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 solitarywave3d_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];
+    dofs[3] = c.entity_indices[0][3];
+    unsigned int offset = m.num_entities[0];
+    dofs[4] = offset + c.entity_indices[1][0];
+    dofs[5] = offset + c.entity_indices[1][1];
+    dofs[6] = offset + c.entity_indices[1][2];
+    dofs[7] = offset + c.entity_indices[1][3];
+    dofs[8] = offset + c.entity_indices[1][4];
+    dofs[9] = offset + c.entity_indices[1][5];
+}
+
+/// Tabulate the local-to-local mapping from facet dofs to cell dofs
+void solitarywave3d_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;
+      dofs[3] = 4;
+      dofs[4] = 5;
+      dofs[5] = 6;
+      break;
+    case 1:
+      dofs[0] = 0;
+      dofs[1] = 2;
+      dofs[2] = 3;
+      dofs[3] = 4;
+      dofs[4] = 7;
+      dofs[5] = 8;
+      break;
+    case 2:
+      dofs[0] = 0;
+      dofs[1] = 1;
+      dofs[2] = 3;
+      dofs[3] = 5;
+      dofs[4] = 7;
+      dofs[5] = 9;
+      break;
+    case 3:
+      dofs[0] = 0;
+      dofs[1] = 1;
+      dofs[2] = 2;
+      dofs[3] = 6;
+      dofs[4] = 8;
+      dofs[5] = 9;
+      break;
+    }
+}
+
+/// Tabulate the local-to-local mapping of dofs on entity (d, i)
+void solitarywave3d_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 solitarywave3d_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[0][2] = x[0][2];
+    coordinates[1][0] = x[1][0];
+    coordinates[1][1] = x[1][1];
+    coordinates[1][2] = x[1][2];
+    coordinates[2][0] = x[2][0];
+    coordinates[2][1] = x[2][1];
+    coordinates[2][2] = x[2][2];
+    coordinates[3][0] = x[3][0];
+    coordinates[3][1] = x[3][1];
+    coordinates[3][2] = x[3][2];
+    coordinates[4][0] = 0.5*x[2][0] + 0.5*x[3][0];
+    coordinates[4][1] = 0.5*x[2][1] + 0.5*x[3][1];
+    coordinates[4][2] = 0.5*x[2][2] + 0.5*x[3][2];
+    coordinates[5][0] = 0.5*x[1][0] + 0.5*x[3][0];
+    coordinates[5][1] = 0.5*x[1][1] + 0.5*x[3][1];
+    coordinates[5][2] = 0.5*x[1][2] + 0.5*x[3][2];
+    coordinates[6][0] = 0.5*x[1][0] + 0.5*x[2][0];
+    coordinates[6][1] = 0.5*x[1][1] + 0.5*x[2][1];
+    coordinates[6][2] = 0.5*x[1][2] + 0.5*x[2][2];
+    coordinates[7][0] = 0.5*x[0][0] + 0.5*x[3][0];
+    coordinates[7][1] = 0.5*x[0][1] + 0.5*x[3][1];
+    coordinates[7][2] = 0.5*x[0][2] + 0.5*x[3][2];
+    coordinates[8][0] = 0.5*x[0][0] + 0.5*x[2][0];
+    coordinates[8][1] = 0.5*x[0][1] + 0.5*x[2][1];
+    coordinates[8][2] = 0.5*x[0][2] + 0.5*x[2][2];
+    coordinates[9][0] = 0.5*x[0][0] + 0.5*x[1][0];
+    coordinates[9][1] = 0.5*x[0][1] + 0.5*x[1][1];
+    coordinates[9][2] = 0.5*x[0][2] + 0.5*x[1][2];
+}
+
+/// Return the number of sub dof maps (for a mixed element)
+unsigned int solitarywave3d_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* solitarywave3d_1_dof_map_0_1::create_sub_dof_map(unsigned int i) const
+{
+    return new solitarywave3d_1_dof_map_0_1();
+}
+
+
+/// Constructor
+solitarywave3d_1_dof_map_0::solitarywave3d_1_dof_map_0() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+solitarywave3d_1_dof_map_0::~solitarywave3d_1_dof_map_0()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* solitarywave3d_1_dof_map_0::signature() const
+{
+    return "FFC dof map for MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) })";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool solitarywave3d_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;
+    case 3:
+      return false;
+      break;
+    }
+    return false;
+}
+
+/// Initialize dof map for mesh (return true iff init_cell() is needed)
+bool solitarywave3d_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 solitarywave3d_1_dof_map_0::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void solitarywave3d_1_dof_map_0::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int solitarywave3d_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 solitarywave3d_1_dof_map_0::local_dimension(const ufc::cell& c) const
+{
+    return 20;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int solitarywave3d_1_dof_map_0::max_local_dimension() const
+{
+    return 20;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int solitarywave3d_1_dof_map_0::geometric_dimension() const
+{
+    return 3;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int solitarywave3d_1_dof_map_0::num_facet_dofs() const
+{
+    return 12;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int solitarywave3d_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 solitarywave3d_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];
+    dofs[3] = c.entity_indices[0][3];
+    unsigned int offset = m.num_entities[0];
+    dofs[4] = offset + c.entity_indices[1][0];
+    dofs[5] = offset + c.entity_indices[1][1];
+    dofs[6] = offset + c.entity_indices[1][2];
+    dofs[7] = offset + c.entity_indices[1][3];
+    dofs[8] = offset + c.entity_indices[1][4];
+    dofs[9] = offset + c.entity_indices[1][5];
+    offset = offset + m.num_entities[1];
+    dofs[10] = offset + c.entity_indices[0][0];
+    dofs[11] = offset + c.entity_indices[0][1];
+    dofs[12] = offset + c.entity_indices[0][2];
+    dofs[13] = offset + c.entity_indices[0][3];
+    offset = offset + m.num_entities[0];
+    dofs[14] = offset + c.entity_indices[1][0];
+    dofs[15] = offset + c.entity_indices[1][1];
+    dofs[16] = offset + c.entity_indices[1][2];
+    dofs[17] = offset + c.entity_indices[1][3];
+    dofs[18] = offset + c.entity_indices[1][4];
+    dofs[19] = offset + c.entity_indices[1][5];
+}
+
+/// Tabulate the local-to-local mapping from facet dofs to cell dofs
+void solitarywave3d_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] = 4;
+      dofs[4] = 5;
+      dofs[5] = 6;
+      dofs[6] = 11;
+      dofs[7] = 12;
+      dofs[8] = 13;
+      dofs[9] = 14;
+      dofs[10] = 15;
+      dofs[11] = 16;
+      break;
+    case 1:
+      dofs[0] = 0;
+      dofs[1] = 2;
+      dofs[2] = 3;
+      dofs[3] = 4;
+      dofs[4] = 7;
+      dofs[5] = 8;
+      dofs[6] = 10;
+      dofs[7] = 12;
+      dofs[8] = 13;
+      dofs[9] = 14;
+      dofs[10] = 17;
+      dofs[11] = 18;
+      break;
+    case 2:
+      dofs[0] = 0;
+      dofs[1] = 1;
+      dofs[2] = 3;
+      dofs[3] = 5;
+      dofs[4] = 7;
+      dofs[5] = 9;
+      dofs[6] = 10;
+      dofs[7] = 11;
+      dofs[8] = 13;
+      dofs[9] = 15;
+      dofs[10] = 17;
+      dofs[11] = 19;
+      break;
+    case 3:
+      dofs[0] = 0;
+      dofs[1] = 1;
+      dofs[2] = 2;
+      dofs[3] = 6;
+      dofs[4] = 8;
+      dofs[5] = 9;
+      dofs[6] = 10;
+      dofs[7] = 11;
+      dofs[8] = 12;
+      dofs[9] = 16;
+      dofs[10] = 18;
+      dofs[11] = 19;
+      break;
+    }
+}
+
+/// Tabulate the local-to-local mapping of dofs on entity (d, i)
+void solitarywave3d_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 solitarywave3d_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[0][2] = x[0][2];
+    coordinates[1][0] = x[1][0];
+    coordinates[1][1] = x[1][1];
+    coordinates[1][2] = x[1][2];
+    coordinates[2][0] = x[2][0];
+    coordinates[2][1] = x[2][1];
+    coordinates[2][2] = x[2][2];
+    coordinates[3][0] = x[3][0];
+    coordinates[3][1] = x[3][1];
+    coordinates[3][2] = x[3][2];
+    coordinates[4][0] = 0.5*x[2][0] + 0.5*x[3][0];
+    coordinates[4][1] = 0.5*x[2][1] + 0.5*x[3][1];
+    coordinates[4][2] = 0.5*x[2][2] + 0.5*x[3][2];
+    coordinates[5][0] = 0.5*x[1][0] + 0.5*x[3][0];
+    coordinates[5][1] = 0.5*x[1][1] + 0.5*x[3][1];
+    coordinates[5][2] = 0.5*x[1][2] + 0.5*x[3][2];
+    coordinates[6][0] = 0.5*x[1][0] + 0.5*x[2][0];
+    coordinates[6][1] = 0.5*x[1][1] + 0.5*x[2][1];
+    coordinates[6][2] = 0.5*x[1][2] + 0.5*x[2][2];
+    coordinates[7][0] = 0.5*x[0][0] + 0.5*x[3][0];
+    coordinates[7][1] = 0.5*x[0][1] + 0.5*x[3][1];
+    coordinates[7][2] = 0.5*x[0][2] + 0.5*x[3][2];
+    coordinates[8][0] = 0.5*x[0][0] + 0.5*x[2][0];
+    coordinates[8][1] = 0.5*x[0][1] + 0.5*x[2][1];
+    coordinates[8][2] = 0.5*x[0][2] + 0.5*x[2][2];
+    coordinates[9][0] = 0.5*x[0][0] + 0.5*x[1][0];
+    coordinates[9][1] = 0.5*x[0][1] + 0.5*x[1][1];
+    coordinates[9][2] = 0.5*x[0][2] + 0.5*x[1][2];
+    coordinates[10][0] = x[0][0];
+    coordinates[10][1] = x[0][1];
+    coordinates[10][2] = x[0][2];
+    coordinates[11][0] = x[1][0];
+    coordinates[11][1] = x[1][1];
+    coordinates[11][2] = x[1][2];
+    coordinates[12][0] = x[2][0];
+    coordinates[12][1] = x[2][1];
+    coordinates[12][2] = x[2][2];
+    coordinates[13][0] = x[3][0];
+    coordinates[13][1] = x[3][1];
+    coordinates[13][2] = x[3][2];
+    coordinates[14][0] = 0.5*x[2][0] + 0.5*x[3][0];
+    coordinates[14][1] = 0.5*x[2][1] + 0.5*x[3][1];
+    coordinates[14][2] = 0.5*x[2][2] + 0.5*x[3][2];
+    coordinates[15][0] = 0.5*x[1][0] + 0.5*x[3][0];
+    coordinates[15][1] = 0.5*x[1][1] + 0.5*x[3][1];
+    coordinates[15][2] = 0.5*x[1][2] + 0.5*x[3][2];
+    coordinates[16][0] = 0.5*x[1][0] + 0.5*x[2][0];
+    coordinates[16][1] = 0.5*x[1][1] + 0.5*x[2][1];
+    coordinates[16][2] = 0.5*x[1][2] + 0.5*x[2][2];
+    coordinates[17][0] = 0.5*x[0][0] + 0.5*x[3][0];
+    coordinates[17][1] = 0.5*x[0][1] + 0.5*x[3][1];
+    coordinates[17][2] = 0.5*x[0][2] + 0.5*x[3][2];
+    coordinates[18][0] = 0.5*x[0][0] + 0.5*x[2][0];
+    coordinates[18][1] = 0.5*x[0][1] + 0.5*x[2][1];
+    coordinates[18][2] = 0.5*x[0][2] + 0.5*x[2][2];
+    coordinates[19][0] = 0.5*x[0][0] + 0.5*x[1][0];
+    coordinates[19][1] = 0.5*x[0][1] + 0.5*x[1][1];
+    coordinates[19][2] = 0.5*x[0][2] + 0.5*x[1][2];
+}
+
+/// Return the number of sub dof maps (for a mixed element)
+unsigned int solitarywave3d_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* solitarywave3d_1_dof_map_0::create_sub_dof_map(unsigned int i) const
+{
+    switch ( i )
+    {
+    case 0:
+      return new solitarywave3d_1_dof_map_0_0();
+      break;
+    case 1:
+      return new solitarywave3d_1_dof_map_0_1();
+      break;
+    }
+    return 0;
+}
+
+
+/// Constructor
+solitarywave3d_1_dof_map_1_0::solitarywave3d_1_dof_map_1_0() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+solitarywave3d_1_dof_map_1_0::~solitarywave3d_1_dof_map_1_0()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* solitarywave3d_1_dof_map_1_0::signature() const
+{
+    return "FFC dof map for FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool solitarywave3d_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;
+    case 3:
+      return false;
+      break;
+    }
+    return false;
+}
+
+/// Initialize dof map for mesh (return true iff init_cell() is needed)
+bool solitarywave3d_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 solitarywave3d_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 solitarywave3d_1_dof_map_1_0::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int solitarywave3d_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 solitarywave3d_1_dof_map_1_0::local_dimension(const ufc::cell& c) const
+{
+    return 10;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int solitarywave3d_1_dof_map_1_0::max_local_dimension() const
+{
+    return 10;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int solitarywave3d_1_dof_map_1_0::geometric_dimension() const
+{
+    return 3;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int solitarywave3d_1_dof_map_1_0::num_facet_dofs() const
+{
+    return 6;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int solitarywave3d_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 solitarywave3d_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];
+    dofs[3] = c.entity_indices[0][3];
+    unsigned int offset = m.num_entities[0];
+    dofs[4] = offset + c.entity_indices[1][0];
+    dofs[5] = offset + c.entity_indices[1][1];
+    dofs[6] = offset + c.entity_indices[1][2];
+    dofs[7] = offset + c.entity_indices[1][3];
+    dofs[8] = offset + c.entity_indices[1][4];
+    dofs[9] = offset + c.entity_indices[1][5];
+}
+
+/// Tabulate the local-to-local mapping from facet dofs to cell dofs
+void solitarywave3d_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;
+      dofs[3] = 4;
+      dofs[4] = 5;
+      dofs[5] = 6;
+      break;
+    case 1:
+      dofs[0] = 0;
+      dofs[1] = 2;
+      dofs[2] = 3;
+      dofs[3] = 4;
+      dofs[4] = 7;
+      dofs[5] = 8;
+      break;
+    case 2:
+      dofs[0] = 0;
+      dofs[1] = 1;
+      dofs[2] = 3;
+      dofs[3] = 5;
+      dofs[4] = 7;
+      dofs[5] = 9;
+      break;
+    case 3:
+      dofs[0] = 0;
+      dofs[1] = 1;
+      dofs[2] = 2;
+      dofs[3] = 6;
+      dofs[4] = 8;
+      dofs[5] = 9;
+      break;
+    }
+}
+
+/// Tabulate the local-to-local mapping of dofs on entity (d, i)
+void solitarywave3d_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 solitarywave3d_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[0][2] = x[0][2];
+    coordinates[1][0] = x[1][0];
+    coordinates[1][1] = x[1][1];
+    coordinates[1][2] = x[1][2];
+    coordinates[2][0] = x[2][0];
+    coordinates[2][1] = x[2][1];
+    coordinates[2][2] = x[2][2];
+    coordinates[3][0] = x[3][0];
+    coordinates[3][1] = x[3][1];
+    coordinates[3][2] = x[3][2];
+    coordinates[4][0] = 0.5*x[2][0] + 0.5*x[3][0];
+    coordinates[4][1] = 0.5*x[2][1] + 0.5*x[3][1];
+    coordinates[4][2] = 0.5*x[2][2] + 0.5*x[3][2];
+    coordinates[5][0] = 0.5*x[1][0] + 0.5*x[3][0];
+    coordinates[5][1] = 0.5*x[1][1] + 0.5*x[3][1];
+    coordinates[5][2] = 0.5*x[1][2] + 0.5*x[3][2];
+    coordinates[6][0] = 0.5*x[1][0] + 0.5*x[2][0];
+    coordinates[6][1] = 0.5*x[1][1] + 0.5*x[2][1];
+    coordinates[6][2] = 0.5*x[1][2] + 0.5*x[2][2];
+    coordinates[7][0] = 0.5*x[0][0] + 0.5*x[3][0];
+    coordinates[7][1] = 0.5*x[0][1] + 0.5*x[3][1];
+    coordinates[7][2] = 0.5*x[0][2] + 0.5*x[3][2];
+    coordinates[8][0] = 0.5*x[0][0] + 0.5*x[2][0];
+    coordinates[8][1] = 0.5*x[0][1] + 0.5*x[2][1];
+    coordinates[8][2] = 0.5*x[0][2] + 0.5*x[2][2];
+    coordinates[9][0] = 0.5*x[0][0] + 0.5*x[1][0];
+    coordinates[9][1] = 0.5*x[0][1] + 0.5*x[1][1];
+    coordinates[9][2] = 0.5*x[0][2] + 0.5*x[1][2];
+}
+
+/// Return the number of sub dof maps (for a mixed element)
+unsigned int solitarywave3d_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* solitarywave3d_1_dof_map_1_0::create_sub_dof_map(unsigned int i) const
+{
+    return new solitarywave3d_1_dof_map_1_0();
+}
+
+
+/// Constructor
+solitarywave3d_1_dof_map_1_1::solitarywave3d_1_dof_map_1_1() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+solitarywave3d_1_dof_map_1_1::~solitarywave3d_1_dof_map_1_1()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* solitarywave3d_1_dof_map_1_1::signature() const
+{
+    return "FFC dof map for FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool solitarywave3d_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;
+    case 3:
+      return false;
+      break;
+    }
+    return false;
+}
+
+/// Initialize dof map for mesh (return true iff init_cell() is needed)
+bool solitarywave3d_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 solitarywave3d_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 solitarywave3d_1_dof_map_1_1::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int solitarywave3d_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 solitarywave3d_1_dof_map_1_1::local_dimension(const ufc::cell& c) const
+{
+    return 10;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int solitarywave3d_1_dof_map_1_1::max_local_dimension() const
+{
+    return 10;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int solitarywave3d_1_dof_map_1_1::geometric_dimension() const
+{
+    return 3;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int solitarywave3d_1_dof_map_1_1::num_facet_dofs() const
+{
+    return 6;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int solitarywave3d_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 solitarywave3d_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];
+    dofs[3] = c.entity_indices[0][3];
+    unsigned int offset = m.num_entities[0];
+    dofs[4] = offset + c.entity_indices[1][0];
+    dofs[5] = offset + c.entity_indices[1][1];
+    dofs[6] = offset + c.entity_indices[1][2];
+    dofs[7] = offset + c.entity_indices[1][3];
+    dofs[8] = offset + c.entity_indices[1][4];
+    dofs[9] = offset + c.entity_indices[1][5];
+}
+
+/// Tabulate the local-to-local mapping from facet dofs to cell dofs
+void solitarywave3d_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;
+      dofs[3] = 4;
+      dofs[4] = 5;
+      dofs[5] = 6;
+      break;
+    case 1:
+      dofs[0] = 0;
+      dofs[1] = 2;
+      dofs[2] = 3;
+      dofs[3] = 4;
+      dofs[4] = 7;
+      dofs[5] = 8;
+      break;
+    case 2:
+      dofs[0] = 0;
+      dofs[1] = 1;
+      dofs[2] = 3;
+      dofs[3] = 5;
+      dofs[4] = 7;
+      dofs[5] = 9;
+      break;
+    case 3:
+      dofs[0] = 0;
+      dofs[1] = 1;
+      dofs[2] = 2;
+      dofs[3] = 6;
+      dofs[4] = 8;
+      dofs[5] = 9;
+      break;
+    }
+}
+
+/// Tabulate the local-to-local mapping of dofs on entity (d, i)
+void solitarywave3d_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 solitarywave3d_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[0][2] = x[0][2];
+    coordinates[1][0] = x[1][0];
+    coordinates[1][1] = x[1][1];
+    coordinates[1][2] = x[1][2];
+    coordinates[2][0] = x[2][0];
+    coordinates[2][1] = x[2][1];
+    coordinates[2][2] = x[2][2];
+    coordinates[3][0] = x[3][0];
+    coordinates[3][1] = x[3][1];
+    coordinates[3][2] = x[3][2];
+    coordinates[4][0] = 0.5*x[2][0] + 0.5*x[3][0];
+    coordinates[4][1] = 0.5*x[2][1] + 0.5*x[3][1];
+    coordinates[4][2] = 0.5*x[2][2] + 0.5*x[3][2];
+    coordinates[5][0] = 0.5*x[1][0] + 0.5*x[3][0];
+    coordinates[5][1] = 0.5*x[1][1] + 0.5*x[3][1];
+    coordinates[5][2] = 0.5*x[1][2] + 0.5*x[3][2];
+    coordinates[6][0] = 0.5*x[1][0] + 0.5*x[2][0];
+    coordinates[6][1] = 0.5*x[1][1] + 0.5*x[2][1];
+    coordinates[6][2] = 0.5*x[1][2] + 0.5*x[2][2];
+    coordinates[7][0] = 0.5*x[0][0] + 0.5*x[3][0];
+    coordinates[7][1] = 0.5*x[0][1] + 0.5*x[3][1];
+    coordinates[7][2] = 0.5*x[0][2] + 0.5*x[3][2];
+    coordinates[8][0] = 0.5*x[0][0] + 0.5*x[2][0];
+    coordinates[8][1] = 0.5*x[0][1] + 0.5*x[2][1];
+    coordinates[8][2] = 0.5*x[0][2] + 0.5*x[2][2];
+    coordinates[9][0] = 0.5*x[0][0] + 0.5*x[1][0];
+    coordinates[9][1] = 0.5*x[0][1] + 0.5*x[1][1];
+    coordinates[9][2] = 0.5*x[0][2] + 0.5*x[1][2];
+}
+
+/// Return the number of sub dof maps (for a mixed element)
+unsigned int solitarywave3d_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* solitarywave3d_1_dof_map_1_1::create_sub_dof_map(unsigned int i) const
+{
+    return new solitarywave3d_1_dof_map_1_1();
+}
+
+
+/// Constructor
+solitarywave3d_1_dof_map_1::solitarywave3d_1_dof_map_1() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+solitarywave3d_1_dof_map_1::~solitarywave3d_1_dof_map_1()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* solitarywave3d_1_dof_map_1::signature() const
+{
+    return "FFC dof map for MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) })";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool solitarywave3d_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;
+    case 3:
+      return false;
+      break;
+    }
+    return false;
+}
+
+/// Initialize dof map for mesh (return true iff init_cell() is needed)
+bool solitarywave3d_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 solitarywave3d_1_dof_map_1::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void solitarywave3d_1_dof_map_1::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int solitarywave3d_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 solitarywave3d_1_dof_map_1::local_dimension(const ufc::cell& c) const
+{
+    return 20;
+}
+
+/// Return the maximum dimension of the local finite element function space
+unsigned int solitarywave3d_1_dof_map_1::max_local_dimension() const
+{
+    return 20;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int solitarywave3d_1_dof_map_1::geometric_dimension() const
+{
+    return 3;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int solitarywave3d_1_dof_map_1::num_facet_dofs() const
+{
+    return 12;
+}
+
+/// Return the number of dofs associated with each cell entity of dimension d
+unsigned int solitarywave3d_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 solitarywave3d_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];
+    dofs[3] = c.entity_indices[0][3];
+    unsigned int offset = m.num_entities[0];
+    dofs[4] = offset + c.entity_indices[1][0];
+    dofs[5] = offset + c.entity_indices[1][1];
+    dofs[6] = offset + c.entity_indices[1][2];
+    dofs[7] = offset + c.entity_indices[1][3];
+    dofs[8] = offset + c.entity_indices[1][4];
+    dofs[9] = offset + c.entity_indices[1][5];
+    offset = offset + m.num_entities[1];
+    dofs[10] = offset + c.entity_indices[0][0];
+    dofs[11] = offset + c.entity_indices[0][1];
+    dofs[12] = offset + c.entity_indices[0][2];
+    dofs[13] = offset + c.entity_indices[0][3];
+    offset = offset + m.num_entities[0];
+    dofs[14] = offset + c.entity_indices[1][0];
+    dofs[15] = offset + c.entity_indices[1][1];
+    dofs[16] = offset + c.entity_indices[1][2];
+    dofs[17] = offset + c.entity_indices[1][3];
+    dofs[18] = offset + c.entity_indices[1][4];
+    dofs[19] = offset + c.entity_indices[1][5];
+}
+
+/// Tabulate the local-to-local mapping from facet dofs to cell dofs
+void solitarywave3d_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] = 4;
+      dofs[4] = 5;
+      dofs[5] = 6;
+      dofs[6] = 11;
+      dofs[7] = 12;
+      dofs[8] = 13;
+      dofs[9] = 14;
+      dofs[10] = 15;
+      dofs[11] = 16;
+      break;
+    case 1:
+      dofs[0] = 0;
+      dofs[1] = 2;
+      dofs[2] = 3;
+      dofs[3] = 4;
+      dofs[4] = 7;
+      dofs[5] = 8;
+      dofs[6] = 10;
+      dofs[7] = 12;
+      dofs[8] = 13;
+      dofs[9] = 14;
+      dofs[10] = 17;
+      dofs[11] = 18;
+      break;
+    case 2:
+      dofs[0] = 0;
+      dofs[1] = 1;
+      dofs[2] = 3;
+      dofs[3] = 5;
+      dofs[4] = 7;
+      dofs[5] = 9;
+      dofs[6] = 10;
+      dofs[7] = 11;
+      dofs[8] = 13;
+      dofs[9] = 15;
+      dofs[10] = 17;
+      dofs[11] = 19;
+      break;
+    case 3:
+      dofs[0] = 0;
+      dofs[1] = 1;
+      dofs[2] = 2;
+      dofs[3] = 6;
+      dofs[4] = 8;
+      dofs[5] = 9;
+      dofs[6] = 10;
+      dofs[7] = 11;
+      dofs[8] = 12;
+      dofs[9] = 16;
+      dofs[10] = 18;
+      dofs[11] = 19;
+      break;
+    }
+}
+
+/// Tabulate the local-to-local mapping of dofs on entity (d, i)
+void solitarywave3d_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 solitarywave3d_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[0][2] = x[0][2];
+    coordinates[1][0] = x[1][0];
+    coordinates[1][1] = x[1][1];
+    coordinates[1][2] = x[1][2];
+    coordinates[2][0] = x[2][0];
+    coordinates[2][1] = x[2][1];
+    coordinates[2][2] = x[2][2];
+    coordinates[3][0] = x[3][0];
+    coordinates[3][1] = x[3][1];
+    coordinates[3][2] = x[3][2];
+    coordinates[4][0] = 0.5*x[2][0] + 0.5*x[3][0];
+    coordinates[4][1] = 0.5*x[2][1] + 0.5*x[3][1];
+    coordinates[4][2] = 0.5*x[2][2] + 0.5*x[3][2];
+    coordinates[5][0] = 0.5*x[1][0] + 0.5*x[3][0];
+    coordinates[5][1] = 0.5*x[1][1] + 0.5*x[3][1];
+    coordinates[5][2] = 0.5*x[1][2] + 0.5*x[3][2];
+    coordinates[6][0] = 0.5*x[1][0] + 0.5*x[2][0];
+    coordinates[6][1] = 0.5*x[1][1] + 0.5*x[2][1];
+    coordinates[6][2] = 0.5*x[1][2] + 0.5*x[2][2];
+    coordinates[7][0] = 0.5*x[0][0] + 0.5*x[3][0];
+    coordinates[7][1] = 0.5*x[0][1] + 0.5*x[3][1];
+    coordinates[7][2] = 0.5*x[0][2] + 0.5*x[3][2];
+    coordinates[8][0] = 0.5*x[0][0] + 0.5*x[2][0];
+    coordinates[8][1] = 0.5*x[0][1] + 0.5*x[2][1];
+    coordinates[8][2] = 0.5*x[0][2] + 0.5*x[2][2];
+    coordinates[9][0] = 0.5*x[0][0] + 0.5*x[1][0];
+    coordinates[9][1] = 0.5*x[0][1] + 0.5*x[1][1];
+    coordinates[9][2] = 0.5*x[0][2] + 0.5*x[1][2];
+    coordinates[10][0] = x[0][0];
+    coordinates[10][1] = x[0][1];
+    coordinates[10][2] = x[0][2];
+    coordinates[11][0] = x[1][0];
+    coordinates[11][1] = x[1][1];
+    coordinates[11][2] = x[1][2];
+    coordinates[12][0] = x[2][0];
+    coordinates[12][1] = x[2][1];
+    coordinates[12][2] = x[2][2];
+    coordinates[13][0] = x[3][0];
+    coordinates[13][1] = x[3][1];
+    coordinates[13][2] = x[3][2];
+    coordinates[14][0] = 0.5*x[2][0] + 0.5*x[3][0];
+    coordinates[14][1] = 0.5*x[2][1] + 0.5*x[3][1];
+    coordinates[14][2] = 0.5*x[2][2] + 0.5*x[3][2];
+    coordinates[15][0] = 0.5*x[1][0] + 0.5*x[3][0];
+    coordinates[15][1] = 0.5*x[1][1] + 0.5*x[3][1];
+    coordinates[15][2] = 0.5*x[1][2] + 0.5*x[3][2];
+    coordinates[16][0] = 0.5*x[1][0] + 0.5*x[2][0];
+    coordinates[16][1] = 0.5*x[1][1] + 0.5*x[2][1];
+    coordinates[16][2] = 0.5*x[1][2] + 0.5*x[2][2];
+    coordinates[17][0] = 0.5*x[0][0] + 0.5*x[3][0];
+    coordinates[17][1] = 0.5*x[0][1] + 0.5*x[3][1];
+    coordinates[17][2] = 0.5*x[0][2] + 0.5*x[3][2];
+    coordinates[18][0] = 0.5*x[0][0] + 0.5*x[2][0];
+    coordinates[18][1] = 0.5*x[0][1] + 0.5*x[2][1];
+    coordinates[18][2] = 0.5*x[0][2] + 0.5*x[2][2];
+    coordinates[19][0] = 0.5*x[0][0] + 0.5*x[1][0];
+    coordinates[19][1] = 0.5*x[0][1] + 0.5*x[1][1];
+    coordinates[19][2] = 0.5*x[0][2] + 0.5*x[1][2];
+}
+
+/// Return the number of sub dof maps (for a mixed element)
+unsigned int solitarywave3d_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* solitarywave3d_1_dof_map_1::create_sub_dof_map(unsigned int i) const
+{
+    switch ( i )
+    {
+    case 0:
+      return new solitarywave3d_1_dof_map_1_0();
+      break;
+    case 1:
+      return new solitarywave3d_1_dof_map_1_1();
+      break;
+    }
+    return 0;
+}
+
+
+/// Constructor
+solitarywave3d_1_dof_map_2::solitarywave3d_1_dof_map_2() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+solitarywave3d_1_dof_map_2::~solitarywave3d_1_dof_map_2()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* solitarywave3d_1_dof_map_2::signature() const
+{
+    return "FFC dof map for FiniteElement('Discontinuous Lagrange', Cell('tetrahedron', 1, Space(3)), 0)";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool solitarywave3d_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 false;
+      break;
+    case 3:
+      return true;
+      break;
+    }
+    return false;
+}
+
+/// Initialize dof map for mesh (return true iff init_cell() is needed)
+bool solitarywave3d_1_dof_map_2::init_mesh(const ufc::mesh& m)
+{
+    __global_dimension = m.num_entities[3];
+    return false;
+}
+
+/// Initialize dof map for given cell
+void solitarywave3d_1_dof_map_2::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void solitarywave3d_1_dof_map_2::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int solitarywave3d_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 solitarywave3d_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 solitarywave3d_1_dof_map_2::max_local_dimension() const
+{
+    return 1;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int solitarywave3d_1_dof_map_2::geometric_dimension() const
+{
+    return 3;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int solitarywave3d_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 solitarywave3d_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 solitarywave3d_1_dof_map_2::tabulate_dofs(unsigned int* dofs,
+                                  const ufc::mesh& m,
+                                  const ufc::cell& c) const
+{
+    dofs[0] = c.entity_indices[3][0];
+}
+
+/// Tabulate the local-to-local mapping from facet dofs to cell dofs
+void solitarywave3d_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;
+    case 3:
+      
+      break;
+    }
+}
+
+/// Tabulate the local-to-local mapping of dofs on entity (d, i)
+void solitarywave3d_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 solitarywave3d_1_dof_map_2::tabulate_coordinates(double** coordinates,
+                                         const ufc::cell& c) const
+{
+    const double * const * x = c.coordinates;
+    coordinates[0][0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0] + 0.25*x[3][0];
+    coordinates[0][1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1] + 0.25*x[3][1];
+    coordinates[0][2] = 0.25*x[0][2] + 0.25*x[1][2] + 0.25*x[2][2] + 0.25*x[3][2];
+}
+
+/// Return the number of sub dof maps (for a mixed element)
+unsigned int solitarywave3d_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* solitarywave3d_1_dof_map_2::create_sub_dof_map(unsigned int i) const
+{
+    return new solitarywave3d_1_dof_map_2();
+}
+
+
+/// Constructor
+solitarywave3d_1_dof_map_3::solitarywave3d_1_dof_map_3() : ufc::dof_map()
+{
+    __global_dimension = 0;
+}
+
+/// Destructor
+solitarywave3d_1_dof_map_3::~solitarywave3d_1_dof_map_3()
+{
+    // Do nothing
+}
+
+/// Return a string identifying the dof map
+const char* solitarywave3d_1_dof_map_3::signature() const
+{
+    return "FFC dof map for FiniteElement('Discontinuous Lagrange', Cell('tetrahedron', 1, Space(3)), 0)";
+}
+
+/// Return true iff mesh entities of topological dimension d are needed
+bool solitarywave3d_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 false;
+      break;
+    case 3:
+      return true;
+      break;
+    }
+    return false;
+}
+
+/// Initialize dof map for mesh (return true iff init_cell() is needed)
+bool solitarywave3d_1_dof_map_3::init_mesh(const ufc::mesh& m)
+{
+    __global_dimension = m.num_entities[3];
+    return false;
+}
+
+/// Initialize dof map for given cell
+void solitarywave3d_1_dof_map_3::init_cell(const ufc::mesh& m,
+                              const ufc::cell& c)
+{
+    // Do nothing
+}
+
+/// Finish initialization of dof map for cells
+void solitarywave3d_1_dof_map_3::init_cell_finalize()
+{
+    // Do nothing
+}
+
+/// Return the dimension of the global finite element function space
+unsigned int solitarywave3d_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 solitarywave3d_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 solitarywave3d_1_dof_map_3::max_local_dimension() const
+{
+    return 1;
+}
+
+// Return the geometric dimension of the coordinates this dof map provides
+unsigned int solitarywave3d_1_dof_map_3::geometric_dimension() const
+{
+    return 3;
+}
+
+/// Return the number of dofs on each cell facet
+unsigned int solitarywave3d_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 solitarywave3d_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 solitarywave3d_1_dof_map_3::tabulate_dofs(unsigned int* dofs,
+                                  const ufc::mesh& m,
+                                  const ufc::cell& c) const
+{
+    dofs[0] = c.entity_indices[3][0];
+}
+
+/// Tabulate the local-to-local mapping from facet dofs to cell dofs
+void solitarywave3d_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;
+    case 3:
+      
+      break;
+    }
+}
+
+/// Tabulate the local-to-local mapping of dofs on entity (d, i)
+void solitarywave3d_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 solitarywave3d_1_dof_map_3::tabulate_coordinates(double** coordinates,
+                                         const ufc::cell& c) const
+{
+    const double * const * x = c.coordinates;
+    coordinates[0][0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0] + 0.25*x[3][0];
+    coordinates[0][1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1] + 0.25*x[3][1];
+    coordinates[0][2] = 0.25*x[0][2] + 0.25*x[1][2] + 0.25*x[2][2] + 0.25*x[3][2];
+}
+
+/// Return the number of sub dof maps (for a mixed element)
+unsigned int solitarywave3d_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* solitarywave3d_1_dof_map_3::create_sub_dof_map(unsigned int i) const
+{
+    return new solitarywave3d_1_dof_map_3();
+}
+
+
+/// Constructor
+solitarywave3d_1_cell_integral_0_quadrature::solitarywave3d_1_cell_integral_0_quadrature() : ufc::cell_integral()
+{
+    // Do nothing
+}
+
+/// Destructor
+solitarywave3d_1_cell_integral_0_quadrature::~solitarywave3d_1_cell_integral_0_quadrature()
+{
+    // Do nothing
+}
+
+/// Tabulate the tensor for the contribution from a local cell
+void solitarywave3d_1_cell_integral_0_quadrature::tabulate_tensor(double* A,
                                     const double * const * w,
                                     const ufc::cell& c) const
 {
@@ -10658,31 +18930,25 @@ void solitarywave3d_0_cell_integral_0_qu
     // Array of non-zero columns
     static const unsigned int nzc3[7] = {0, 1, 5, 6, 7, 8, 9};
     
-    // Number of operations to compute geometry constants: 88
+    // Number of operations to compute geometry constants: 43
     const double G0 = det*(Jinv_10*Jinv_20 + Jinv_11*Jinv_21 + Jinv_12*Jinv_22);
-    const double G1 = -3*Jinv_22*det;
-    const double G2 = 3*det*(Jinv_20*Jinv_20 + Jinv_21*Jinv_21 + Jinv_22*Jinv_22);
-    const double G3 = 3*det*(Jinv_00*Jinv_20 + Jinv_01*Jinv_21 + Jinv_02*Jinv_22);
-    const double G4 = 3*det*(Jinv_10*Jinv_20 + Jinv_11*Jinv_21 + Jinv_12*Jinv_22);
-    const double G5 = det*(Jinv_00*Jinv_00 + Jinv_01*Jinv_01 + Jinv_02*Jinv_02);
-    const double G6 = det*w[2][0];
-    const double G7 = -3*Jinv_02*det;
-    const double G8 = 3*det*(Jinv_00*Jinv_00 + Jinv_01*Jinv_01 + Jinv_02*Jinv_02);
-    const double G9 = 3*det*(Jinv_00*Jinv_10 + Jinv_01*Jinv_11 + Jinv_02*Jinv_12);
-    const double G10 = det*(Jinv_00*Jinv_10 + Jinv_01*Jinv_11 + Jinv_02*Jinv_12);
-    const double G11 = -3*Jinv_12*det;
-    const double G12 = 3*det*(Jinv_10*Jinv_10 + Jinv_11*Jinv_11 + Jinv_12*Jinv_12);
-    const double G13 = det*(Jinv_10*Jinv_10 + Jinv_11*Jinv_11 + Jinv_12*Jinv_12);
-    const double G14 = det*(Jinv_20*Jinv_20 + Jinv_21*Jinv_21 + Jinv_22*Jinv_22);
-    const double G15 = det*(Jinv_00*Jinv_20 + Jinv_01*Jinv_21 + Jinv_02*Jinv_22);
-    const double G16 = -0.5*det*w[1][0]*w[2][0];
+    const double G1 = det*(Jinv_10*Jinv_10 + Jinv_11*Jinv_11 + Jinv_12*Jinv_12);
+    const double G2 = -Jinv_12*det;
+    const double G3 = det*(Jinv_00*Jinv_10 + Jinv_01*Jinv_11 + Jinv_02*Jinv_12);
+    const double G4 = -0.5*det*w[1][0]*w[2][0];
+    const double G5 = det*(Jinv_20*Jinv_20 + Jinv_21*Jinv_21 + Jinv_22*Jinv_22);
+    const double G6 = -Jinv_22*det;
+    const double G7 = det*(Jinv_00*Jinv_20 + Jinv_01*Jinv_21 + Jinv_02*Jinv_22);
+    const double G8 = -Jinv_02*det;
+    const double G9 = det*(Jinv_00*Jinv_00 + Jinv_01*Jinv_01 + Jinv_02*Jinv_02);
+    const double G10 = 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: 371213
+    // Total number of operations to compute element tensor: 25043
     
     // Loop quadrature points for integral
-    // Number of operations to compute element tensor for following IP loop = 371125
+    // Number of operations to compute element tensor for following IP loop = 25000
     for (unsigned int ip = 0; ip < 125; ip++)
     {
       
@@ -10691,134 +18957,81 @@ void solitarywave3d_0_cell_integral_0_qu
       double F1 = 0;
       double F2 = 0;
       double F3 = 0;
-      
-      // Total number of operations to compute function values = 20
+      double F4 = 0;
+      
+      // Total number of operations to compute function values = 40
       for (unsigned int r = 0; r < 10; r++)
       {
         F0 += FE1_C0[ip][r]*w[0][nzc4[r]];
+        F1 += FE1_C0[ip][r]*w[0][nzc0[r]];
       }// end loop over 'r'
       
       // Total number of operations to compute function values = 42
       for (unsigned int r = 0; r < 7; r++)
       {
-        F1 += FE1_C0_D100[ip][r]*w[0][nzc3[r]];
-        F2 += FE1_C0_D010[ip][r]*w[0][nzc2[r]];
-        F3 += FE1_C0_D001[ip][r]*w[0][nzc1[r]];
+        F2 += FE1_C0_D100[ip][r]*w[0][nzc3[r]];
+        F3 += FE1_C0_D010[ip][r]*w[0][nzc2[r]];
+        F4 += FE1_C0_D001[ip][r]*w[0][nzc1[r]];
       }// end loop over 'r'
       
-      // Number of operations to compute ip constants: 54
+      // Number of operations to compute ip constants: 36
+      // Number of operations: 10
+      const double Gip0 = F0*F0*F0*W125[ip]*(G2 + F2*G3 + F3*G1 + F4*G0);
+      
       // Number of operations: 4
-      const double Gip0 = F0*F0*F0*G0*W125[ip];
-      
-      // Number of operations: 1
-      const double Gip1 = W125[ip]*det;
-      
-      // Number of operations: 9
-      const double Gip2 = F0*F0*W125[ip]*(G1 + F1*G3 + F2*G4 + F3*G2);
-      
-      // Number of operations: 4
-      const double Gip3 = F0*F0*F0*G5*W125[ip];
-      
-      // Number of operations: 1
-      const double Gip4 = G6*W125[ip];
-      
-      // Number of operations: 9
-      const double Gip5 = F0*F0*W125[ip]*(G7 + F1*G8 + F2*G9 + F3*G3);
-      
-      // Number of operations: 4
-      const double Gip6 = F0*F0*F0*G10*W125[ip];
-      
-      // Number of operations: 9
-      const double Gip7 = F0*F0*W125[ip]*(G11 + F1*G9 + F2*G12 + F3*G4);
-      
-      // Number of operations: 4
-      const double Gip8 = F0*F0*F0*G13*W125[ip];
-      
-      // Number of operations: 4
-      const double Gip9 = F0*F0*F0*G14*W125[ip];
-      
-      // Number of operations: 4
-      const double Gip10 = F0*F0*F0*G15*W125[ip];
-      
-      // Number of operations: 1
-      const double Gip11 = G16*W125[ip];
-      
-      
-      // Number of operations for primary indices: 1323
+      const double Gip1 = W125[ip]*(F0*det + F1*G4);
+      
+      // Number of operations: 10
+      const double Gip2 = F0*F0*F0*W125[ip]*(G6 + F2*G7 + F3*G0 + F4*G5);
+      
+      // Number of operations: 10
+      const double Gip3 = F0*F0*F0*W125[ip]*(G8 + F2*G9 + F3*G3 + F4*G7);
+      
+      // Number of operations: 2
+      const double Gip4 = F1*G10*W125[ip];
+      
+      
+      // Number of operations for primary indices: 40
+      for (unsigned int j = 0; j < 10; j++)
+      {
+        // Number of operations to compute entry: 2
+        A[nzc4[j]] += FE1_C0[ip][j]*Gip1;
+        // Number of operations to compute entry: 2
+        A[nzc0[j]] += FE1_C0[ip][j]*Gip4;
+      }// end loop over 'j'
+      
+      // Number of operations for primary indices: 42
       for (unsigned int j = 0; j < 7; j++)
       {
-        for (unsigned int k = 0; k < 7; k++)
-        {
-          // Number of operations to compute entry: 3
-          A[nzc2[j]*20 + nzc1[k]] += FE1_C0_D001[ip][k]*FE1_C0_D010[ip][j]*Gip0;
-          // Number of operations to compute entry: 3
-          A[nzc3[j]*20 + nzc3[k]] += FE1_C0_D100[ip][j]*FE1_C0_D100[ip][k]*Gip3;
-          // Number of operations to compute entry: 3
-          A[nzc2[j]*20 + nzc3[k]] += FE1_C0_D010[ip][j]*FE1_C0_D100[ip][k]*Gip6;
-          // Number of operations to compute entry: 3
-          A[nzc3[j]*20 + nzc2[k]] += FE1_C0_D010[ip][k]*FE1_C0_D100[ip][j]*Gip6;
-          // Number of operations to compute entry: 3
-          A[nzc1[j]*20 + nzc2[k]] += FE1_C0_D001[ip][j]*FE1_C0_D010[ip][k]*Gip0;
-          // Number of operations to compute entry: 3
-          A[nzc2[j]*20 + nzc2[k]] += FE1_C0_D010[ip][j]*FE1_C0_D010[ip][k]*Gip8;
-          // Number of operations to compute entry: 3
-          A[nzc1[j]*20 + nzc1[k]] += FE1_C0_D001[ip][j]*FE1_C0_D001[ip][k]*Gip9;
-          // Number of operations to compute entry: 3
-          A[nzc3[j]*20 + nzc1[k]] += FE1_C0_D001[ip][k]*FE1_C0_D100[ip][j]*Gip10;
-          // Number of operations to compute entry: 3
-          A[nzc1[j]*20 + nzc3[k]] += FE1_C0_D001[ip][j]*FE1_C0_D100[ip][k]*Gip10;
-        }// end loop over 'k'
-      }// end loop over 'j'
-      
-      // Number of operations for primary indices: 900
-      for (unsigned int j = 0; j < 10; j++)
-      {
-        for (unsigned int k = 0; k < 10; k++)
-        {
-          // Number of operations to compute entry: 3
-          A[nzc4[j]*20 + nzc4[k]] += FE1_C0[ip][j]*FE1_C0[ip][k]*Gip1;
-          // Number of operations to compute entry: 3
-          A[nzc0[j]*20 + nzc0[k]] += FE1_C0[ip][j]*FE1_C0[ip][k]*Gip4;
-          // Number of operations to compute entry: 3
-          A[nzc4[j]*20 + nzc0[k]] += FE1_C0[ip][j]*FE1_C0[ip][k]*Gip11;
-        }// end loop over 'k'
-      }// end loop over 'j'
-      
-      // Number of operations for primary indices: 630
-      for (unsigned int j = 0; j < 7; j++)
-      {
-        for (unsigned int k = 0; k < 10; k++)
-        {
-          // Number of operations to compute entry: 3
-          A[nzc1[j]*20 + nzc4[k]] += FE1_C0[ip][k]*FE1_C0_D001[ip][j]*Gip2;
-          // Number of operations to compute entry: 3
-          A[nzc3[j]*20 + nzc4[k]] += FE1_C0[ip][k]*FE1_C0_D100[ip][j]*Gip5;
-          // Number of operations to compute entry: 3
-          A[nzc2[j]*20 + nzc4[k]] += FE1_C0[ip][k]*FE1_C0_D010[ip][j]*Gip7;
-        }// end loop over 'k'
+        // Number of operations to compute entry: 2
+        A[nzc2[j]] += FE1_C0_D010[ip][j]*Gip0;
+        // Number of operations to compute entry: 2
+        A[nzc1[j]] += FE1_C0_D001[ip][j]*Gip2;
+        // Number of operations to compute entry: 2
+        A[nzc3[j]] += FE1_C0_D100[ip][j]*Gip3;
       }// end loop over 'j'
     }// end loop over 'ip'
 }
 
 /// Constructor
-solitarywave3d_0_cell_integral_0::solitarywave3d_0_cell_integral_0() : ufc::cell_integral()
-{
-    // Do nothing
-}
-
-/// Destructor
-solitarywave3d_0_cell_integral_0::~solitarywave3d_0_cell_integral_0()
+solitarywave3d_1_cell_integral_0::solitarywave3d_1_cell_integral_0() : ufc::cell_integral()
+{
+    // Do nothing
+}
+
+/// Destructor
+solitarywave3d_1_cell_integral_0::~solitarywave3d_1_cell_integral_0()
 {
     // Do nothing
 }
 
 /// Tabulate the tensor for the contribution from a local cell
-void solitarywave3d_0_cell_integral_0::tabulate_tensor(double* A,
+void solitarywave3d_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 < 400; j++)
+    for (unsigned int j = 0; j < 20; j++)
       A[j] = 0;
     
     // Add all contributions to element tensor
@@ -10826,19 +19039,19 @@ void solitarywave3d_0_cell_integral_0::t
 }
 
 /// Constructor
-solitarywave3d_0_exterior_facet_integral_0_quadrature::solitarywave3d_0_exterior_facet_integral_0_quadrature() : ufc::exterior_facet_integral()
-{
-    // Do nothing
-}
-
-/// Destructor
-solitarywave3d_0_exterior_facet_integral_0_quadrature::~solitarywave3d_0_exterior_facet_integral_0_quadrature()
+solitarywave3d_1_exterior_facet_integral_0_quadrature::solitarywave3d_1_exterior_facet_integral_0_quadrature() : ufc::exterior_facet_integral()
+{
+    // Do nothing
+}
+
+/// Destructor
+solitarywave3d_1_exterior_facet_integral_0_quadrature::~solitarywave3d_1_exterior_facet_integral_0_quadrature()
 {
     // Do nothing
 }
 
 /// Tabulate the tensor for the contribution from a local exterior facet
-void solitarywave3d_0_exterior_facet_integral_0_quadrature::tabulate_tensor(double* A,
+void solitarywave3d_1_exterior_facet_integral_0_quadrature::tabulate_tensor(double* A,
                                     const double * const * w,
                                     const ufc::cell& c,
                                     unsigned int facet) const
@@ -10927,8219 +19140,6 @@ void solitarywave3d_0_exterior_facet_int
     // Array of non-zero columns
     static const unsigned int nzc7[6] = {10, 11, 12, 16, 18, 19};
     
-    // Number of operations to compute geometry constants: 2
-    // Should be added to total operation count.
-    const double G0 = 3*det*n2;
-    
-    // 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): 3075
-      
-      // Loop quadrature points for integral
-      // Number of operations to compute element tensor for following IP loop = 3075
-      for (unsigned int ip = 0; ip < 25; ip++)
-      {
-        
-        // Function declarations
-        double F0 = 0;
-        
-        // Total number of operations to compute function values = 12
-        for (unsigned int r = 0; r < 6; r++)
-        {
-          F0 += FE0_f0_C0[ip][r]*w[0][nzc1[r]];
-        }// end loop over 'r'
-        
-        // Number of operations to compute ip constants: 3
-        // Number of operations: 3
-        const double Gip0 = F0*F0*G0*W25[ip];
-        
-        
-        // Number of operations for primary indices: 108
-        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]*20 + nzc1[k]] += FE0_f0_C0[ip][j]*FE0_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): 3075
-      
-      // Loop quadrature points for integral
-      // Number of operations to compute element tensor for following IP loop = 3075
-      for (unsigned int ip = 0; ip < 25; ip++)
-      {
-        
-        // Function declarations
-        double F0 = 0;
-        
-        // Total number of operations to compute function values = 12
-        for (unsigned int r = 0; r < 6; r++)
-        {
-          F0 += FE0_f0_C0[ip][r]*w[0][nzc3[r]];
-        }// end loop over 'r'
-        
-        // Number of operations to compute ip constants: 3
-        // Number of operations: 3
-        const double Gip0 = F0*F0*G0*W25[ip];
-        
-        
-        // Number of operations for primary indices: 108
-        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]*20 + nzc3[k]] += FE0_f0_C0[ip][j]*FE0_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): 3075
-      
-      // Loop quadrature points for integral
-      // Number of operations to compute element tensor for following IP loop = 3075
-      for (unsigned int ip = 0; ip < 25; ip++)
-      {
-        
-        // Function declarations
-        double F0 = 0;
-        
-        // Total number of operations to compute function values = 12
-        for (unsigned int r = 0; r < 6; r++)
-        {
-          F0 += FE0_f0_C0[ip][r]*w[0][nzc5[r]];
-        }// end loop over 'r'
-        
-        // Number of operations to compute ip constants: 3
-        // Number of operations: 3
-        const double Gip0 = F0*F0*G0*W25[ip];
-        
-        
-        // Number of operations for primary indices: 108
-        for (unsigned int j = 0; j < 6; j++)
-        {
-          for (unsigned int k = 0; k < 6; k++)
-          {
-            // Number of operations to compute entry: 3
-            A[nzc4[j]*20 + nzc5[k]] += FE0_f0_C0[ip][j]*FE0_f0_C0[ip][k]*Gip0;
-          }// end loop over 'k'
-        }// end loop over 'j'
-      }// end loop over 'ip'
-      }
-      break;
-    case 3:
-      {
-      // Total number of operations to compute element tensor (from this point): 3075
-      
-      // Loop quadrature points for integral
-      // Number of operations to compute element tensor for following IP loop = 3075
-      for (unsigned int ip = 0; ip < 25; ip++)
-      {
-        
-        // Function declarations
-        double F0 = 0;
-        
-        // Total number of operations to compute function values = 12
-        for (unsigned int r = 0; r < 6; r++)
-        {
-          F0 += FE0_f0_C0[ip][r]*w[0][nzc7[r]];
-        }// end loop over 'r'
-        
-        // Number of operations to compute ip constants: 3
-        // Number of operations: 3
-        const double Gip0 = F0*F0*G0*W25[ip];
-        
-        
-        // Number of operations for primary indices: 108
-        for (unsigned int j = 0; j < 6; j++)
-        {
-          for (unsigned int k = 0; k < 6; k++)
-          {
-            // Number of operations to compute entry: 3
-            A[nzc6[j]*20 + nzc7[k]] += FE0_f0_C0[ip][j]*FE0_f0_C0[ip][k]*Gip0;
-          }// end loop over 'k'
-        }// end loop over 'j'
-      }// end loop over 'ip'
-      }
-      break;
-    }
-}
-
-/// Constructor
-solitarywave3d_0_exterior_facet_integral_0::solitarywave3d_0_exterior_facet_integral_0() : ufc::exterior_facet_integral()
-{
-    // Do nothing
-}
-
-/// Destructor
-solitarywave3d_0_exterior_facet_integral_0::~solitarywave3d_0_exterior_facet_integral_0()
-{
-    // Do nothing
-}
-
-/// Tabulate the tensor for the contribution from a local exterior facet
-void solitarywave3d_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 < 400; j++)
-      A[j] = 0;
-    
-    // Add all contributions to element tensor
-    integral_0_quadrature.tabulate_tensor(A, w, c, facet);
-}
-
-/// Constructor
-solitarywave3d_form_0::solitarywave3d_form_0() : ufc::form()
-{
-    // Do nothing
-}
-
-/// Destructor
-solitarywave3d_form_0::~solitarywave3d_form_0()
-{
-    // Do nothing
-}
-
-/// Return a string identifying the form
-const char* solitarywave3d_form_0::signature() const
-{
-    return "Form([Integral(Sum(Product(Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})), Sum(Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) }), 1), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})), Product(IntValue(-1, (), (), {}), Product(Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) }), 1), MultiIndex((FixedIndex(0),), {FixedIndex(0): 2})), Product(Constant(Cell('tetrahedron', 1, Space(3)), 2), Product(FloatValue(0.5, (), (), {}), Constant(Cell('tetrahedron', 1, Space(3)), 1))))))), Sum(Product(IntValue(-1, (), (), {}), Product(Indexed(SpatialDerivative(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(2),), {FixedIndex(2): 3})), MultiIndex((FixedIndex(0),), {FixedIndex(0): 2})), Sum(Product(Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) }), 1), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})), Power(Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})), IntValue(2, (), (), {}))), Product(Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})), Product(Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})), Product(IntValue(2, (), (), {}), Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) }), 1), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})))))))), Sum(Product(Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) }), 1), MultiIndex((FixedIndex(0),), {FixedIndex(0): 2})), Product(Constant(Cell('tetrahedron', 1, Space(3)), 2), Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(0),), {FixedIndex(0): 2})))), Sum(Product(IndexSum(Product(Indexed(ComponentTensor(Indexed(SpatialDerivative(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((Index(0),), {Index(0): 3})), MultiIndex((FixedIndex(0),), {})), MultiIndex((Index(0),), {Index(0): 3})), MultiIndex((Index(1),), {Index(1): 3})), Indexed(ComponentTensor(Indexed(SpatialDerivative(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) }), 1), MultiIndex((Index(2),), {Index(2): 3})), MultiIndex((FixedIndex(0),), {})), MultiIndex((Index(2),), {Index(2): 3})), MultiIndex((Index(1),), {Index(1): 3}))), MultiIndex((Index(1),), {Index(1): 3})), Product(Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})), Power(Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 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('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((Index(0),), {Index(0): 3})), MultiIndex((FixedIndex(0),), {})), MultiIndex((Index(0),), {Index(0): 3})), MultiIndex((Index(1),), {Index(1): 3})), Indexed(ComponentTensor(Indexed(SpatialDerivative(Function(MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((Index(2),), {Index(2): 3})), MultiIndex((FixedIndex(0),), {})), MultiIndex((Index(2),), {Index(2): 3})), MultiIndex((Index(1),), {Index(1): 3}))), MultiIndex((Index(1),), {Index(1): 3})), Sum(Product(Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) }), 1), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})), Power(Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})), IntValue(2, (), (), {}))), Product(Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})), Product(Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})), Product(IntValue(2, (), (), {}), Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) }), 1), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2}))))))))))), Measure('cell', 0, None)), Integral(Product(Indexed(FacetNormal(Cell('tetrahedron', 1, Space(3))), MultiIndex((FixedIndex(2),), {FixedIndex(2): 3})), Product(Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(0),), {FixedIndex(0): 2})), Sum(Product(Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) }), 1), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})), Power(Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})), IntValue(2, (), (), {}))), Product(Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})), Product(Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})), Product(IntValue(2, (), (), {}), Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) }), 1), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})))))))), Measure('exterior_facet', 0, None))])";
-}
-
-/// Return the rank of the global tensor (r)
-unsigned int solitarywave3d_form_0::rank() const
-{
-    return 2;
-}
-
-/// Return the number of coefficients (n)
-unsigned int solitarywave3d_form_0::num_coefficients() const
-{
-    return 3;
-}
-
-/// Return the number of cell integrals
-unsigned int solitarywave3d_form_0::num_cell_integrals() const
-{
-    return 1;
-}
-
-/// Return the number of exterior facet integrals
-unsigned int solitarywave3d_form_0::num_exterior_facet_integrals() const
-{
-    return 1;
-}
-
-/// Return the number of interior facet integrals
-unsigned int solitarywave3d_form_0::num_interior_facet_integrals() const
-{
-    return 0;
-}
-
-/// Create a new finite element for argument function i
-ufc::finite_element* solitarywave3d_form_0::create_finite_element(unsigned int i) const
-{
-    switch ( i )
-    {
-    case 0:
-      return new solitarywave3d_0_finite_element_0();
-      break;
-    case 1:
-      return new solitarywave3d_0_finite_element_1();
-      break;
-    case 2:
-      return new solitarywave3d_0_finite_element_2();
-      break;
-    case 3:
-      return new solitarywave3d_0_finite_element_3();
-      break;
-    case 4:
-      return new solitarywave3d_0_finite_element_4();
-      break;
-    }
-    return 0;
-}
-
-/// Create a new dof map for argument function i
-ufc::dof_map* solitarywave3d_form_0::create_dof_map(unsigned int i) const
-{
-    switch ( i )
-    {
-    case 0:
-      return new solitarywave3d_0_dof_map_0();
-      break;
-    case 1:
-      return new solitarywave3d_0_dof_map_1();
-      break;
-    case 2:
-      return new solitarywave3d_0_dof_map_2();
-      break;
-    case 3:
-      return new solitarywave3d_0_dof_map_3();
-      break;
-    case 4:
-      return new solitarywave3d_0_dof_map_4();
-      break;
-    }
-    return 0;
-}
-
-/// Create a new cell integral on sub domain i
-ufc::cell_integral* solitarywave3d_form_0::create_cell_integral(unsigned int i) const
-{
-    return new solitarywave3d_0_cell_integral_0();
-}
-
-/// Create a new exterior facet integral on sub domain i
-ufc::exterior_facet_integral* solitarywave3d_form_0::create_exterior_facet_integral(unsigned int i) const
-{
-    return new solitarywave3d_0_exterior_facet_integral_0();
-}
-
-/// Create a new interior facet integral on sub domain i
-ufc::interior_facet_integral* solitarywave3d_form_0::create_interior_facet_integral(unsigned int i) const
-{
-    return 0;
-}
-
-
-/// Constructor
-solitarywave3d_1_finite_element_0_0::solitarywave3d_1_finite_element_0_0() : ufc::finite_element()
-{
-    // Do nothing
-}
-
-/// Destructor
-solitarywave3d_1_finite_element_0_0::~solitarywave3d_1_finite_element_0_0()
-{
-    // Do nothing
-}
-
-/// Return a string identifying the finite element
-const char* solitarywave3d_1_finite_element_0_0::signature() const
-{
-    return "FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)";
-}
-
-/// Return the cell shape
-ufc::shape solitarywave3d_1_finite_element_0_0::cell_shape() const
-{
-    return ufc::tetrahedron;
-}
-
-/// Return the dimension of the finite element function space
-unsigned int solitarywave3d_1_finite_element_0_0::space_dimension() const
-{
-    return 10;
-}
-
-/// Return the rank of the value space
-unsigned int solitarywave3d_1_finite_element_0_0::value_rank() const
-{
-    return 0;
-}
-
-/// Return the dimension of the value space for axis i
-unsigned int solitarywave3d_1_finite_element_0_0::value_dimension(unsigned int i) const
-{
-    return 1;
-}
-
-/// Evaluate basis function i at given point in cell
-void solitarywave3d_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_02 = element_coordinates[3][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];
-    const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
-    const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
-    const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
-    const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
-    
-    // Compute sub determinants
-    const double d00 = J_11*J_22 - J_12*J_21;
-    const double d01 = J_12*J_20 - J_10*J_22;
-    const double d02 = J_10*J_21 - J_11*J_20;
-    
-    const double d10 = J_02*J_21 - J_01*J_22;
-    const double d11 = J_00*J_22 - J_02*J_20;
-    const double d12 = J_01*J_20 - J_00*J_21;
-    
-    const double d20 = J_01*J_12 - J_02*J_11;
-    const double d21 = J_02*J_10 - J_00*J_12;
-    const double d22 = J_00*J_11 - J_01*J_10;
-    
-    // Compute determinant of Jacobian
-    double detJ = J_00*d00 + J_10*d10 + J_20*d20;
-    
-    // Compute inverse of Jacobian
-    
-    // Compute constants
-    const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
-                    + d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
-                    + d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
-    
-    const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
-                    + d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
-                    + d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
-    
-    const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
-                    + d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
-                    + d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
-    
-    // Get coordinates and map to the UFC reference element
-    double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
-    double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
-    double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
-    
-    // Map coordinates to the reference cube
-    if (std::abs(y + z - 1.0) < 1e-14)
-      x = 1.0;
-    else
-      x = -2.0 * x/(y + z - 1.0) - 1.0;
-    if (std::abs(z - 1.0) < 1e-14)
-      y = -1.0;
-    else
-      y = 2.0 * y/(1.0 - z) - 1.0;
-    z = 2.0 * z - 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);
-    const double scalings_z_0 = 1;
-    const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
-    const double scalings_z_2 = scalings_z_1*(0.5 - 0.5*z);
-    
-    // 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 psitilde_cs
-    const double psitilde_cs_00_0 = 1;
-    const double psitilde_cs_00_1 = 2*z + 1;
-    const double psitilde_cs_00_2 = 0.3125*psitilde_cs_00_1 + 1.875*z*psitilde_cs_00_1 - 0.5625*psitilde_cs_00_0;
-    const double psitilde_cs_01_0 = 1;
-    const double psitilde_cs_01_1 = 3*z + 2;
-    const double psitilde_cs_02_0 = 1;
-    const double psitilde_cs_10_0 = 1;
-    const double psitilde_cs_10_1 = 3*z + 2;
-    const double psitilde_cs_11_0 = 1;
-    const double psitilde_cs_20_0 = 1;
-    
-    // Compute basisvalues
-    const double basisvalue0 = 0.866025403784439*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
-    const double basisvalue1 = 2.73861278752583*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
-    const double basisvalue2 = 1.58113883008419*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
-    const double basisvalue3 = 1.11803398874989*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
-    const double basisvalue4 = 5.1234753829798*psitilde_a_2*scalings_y_2*psitilde_bs_2_0*scalings_z_2*psitilde_cs_20_0;
-    const double basisvalue5 = 3.96862696659689*psitilde_a_1*scalings_y_1*psitilde_bs_1_1*scalings_z_2*psitilde_cs_11_0;
-    const double basisvalue6 = 2.29128784747792*psitilde_a_0*scalings_y_0*psitilde_bs_0_2*scalings_z_2*psitilde_cs_02_0;
-    const double basisvalue7 = 3.24037034920393*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_1;
-    const double basisvalue8 = 1.87082869338697*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_1;
-    const double basisvalue9 = 1.3228756555323*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_2;
-    
-    // Table(s) of coefficients
-    static const double coefficients0[10][10] = \
-    {{-0.0577350269189626, -0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, 0.0503952630678969, 0.0290957186981323, 0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
-    {-0.0577350269189625, 0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, -0.050395263067897, 0.0290957186981323, -0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
-    {-0.0577350269189625, 0, 0.0702728368926306, -0.0248451997499977, 0, 0, 0.0872871560943969, 0, -0.0475131096733199, 0.0167984210226323},
-    {-0.0577350269189626, 0, 0, 0.074535599249993, 0, 0, 0, 0, 0, 0.100790526135794},
-    {0.23094010767585, 0, 0.140545673785261, 0.0993807989999906, 0, 0, 0, 0, 0.1187827741833, -0.0671936840905293},
-    {0.230940107675851, 0.121716123890037, -0.0702728368926306, 0.0993807989999907, 0, 0, 0, 0.102868899974728, -0.0593913870916499, -0.0671936840905293},
-    {0.23094010767585, 0.121716123890037, 0.0702728368926307, -0.0993807989999907, 0, 0.100790526135794, -0.087287156094397, -0.0205737799949456, -0.01187827741833, 0.0167984210226323},
-    {0.23094010767585, -0.121716123890037, -0.0702728368926307, 0.0993807989999906, 0, 0, 0, -0.102868899974728, -0.0593913870916499, -0.0671936840905293},
-    {0.23094010767585, -0.121716123890037, 0.0702728368926306, -0.0993807989999906, 0, -0.100790526135794, -0.0872871560943969, 0.0205737799949456, -0.01187827741833, 0.0167984210226323},
-    {0.23094010767585, 0, -0.140545673785261, -0.0993807989999906, -0.130120009726471, 0, 0.0290957186981323, 0, 0.02375655483666, 0.0167984210226323}};
-    
-    // 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];
-    const double coeff0_6 = coefficients0[dof][6];
-    const double coeff0_7 = coefficients0[dof][7];
-    const double coeff0_8 = coefficients0[dof][8];
-    const double coeff0_9 = coefficients0[dof][9];
-    
-    // Compute value(s)
-    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5 + coeff0_6*basisvalue6 + coeff0_7*basisvalue7 + coeff0_8*basisvalue8 + coeff0_9*basisvalue9;
-}
-
-/// Evaluate all basis functions at given point in cell
-void solitarywave3d_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 solitarywave3d_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_02 = element_coordinates[3][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];
-    const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
-    const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
-    const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
-    const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
-    
-    // Compute sub determinants
-    const double d00 = J_11*J_22 - J_12*J_21;
-    const double d01 = J_12*J_20 - J_10*J_22;
-    const double d02 = J_10*J_21 - J_11*J_20;
-    
-    const double d10 = J_02*J_21 - J_01*J_22;
-    const double d11 = J_00*J_22 - J_02*J_20;
-    const double d12 = J_01*J_20 - J_00*J_21;
-    
-    const double d20 = J_01*J_12 - J_02*J_11;
-    const double d21 = J_02*J_10 - J_00*J_12;
-    const double d22 = J_00*J_11 - J_01*J_10;
-    
-    // Compute determinant of Jacobian
-    double detJ = J_00*d00 + J_10*d10 + J_20*d20;
-    
-    // Compute inverse of Jacobian
-    
-    // Compute constants
-    const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
-                    + d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
-                    + d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
-    
-    const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
-                    + d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
-                    + d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
-    
-    const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
-                    + d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
-                    + d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
-    
-    // Get coordinates and map to the UFC reference element
-    double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
-    double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
-    double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
-    
-    // Map coordinates to the reference cube
-    if (std::abs(y + z - 1.0) < 1e-14)
-      x = 1.0;
-    else
-      x = -2.0 * x/(y + z - 1.0) - 1.0;
-    if (std::abs(z - 1.0) < 1e-14)
-      y = -1.0;
-    else
-      y = 2.0 * y/(1.0 - z) - 1.0;
-    z = 2.0 * z - 1.0;
-    
-    // Compute number of derivatives
-    unsigned int num_derivatives = 1;
-    
-    for (unsigned int j = 0; j < n; j++)
-      num_derivatives *= 3;
-    
-    
-    // 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 > 2)
-            combinations[row][col] = 0;
-          else
-          {
-            combinations[row][col] += 1;
-            break;
-          }
-        }
-      }
-    }
-    
-    // Compute inverse of Jacobian
-    const double Jinv[3][3] ={{d00 / detJ, d10 / detJ, d20 / detJ}, {d01 / detJ, d11 / detJ, d21 / detJ}, {d02 / detJ, d12 / detJ, d22 / 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);
-    const double scalings_z_0 = 1;
-    const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
-    const double scalings_z_2 = scalings_z_1*(0.5 - 0.5*z);
-    
-    // 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 psitilde_cs
-    const double psitilde_cs_00_0 = 1;
-    const double psitilde_cs_00_1 = 2*z + 1;
-    const double psitilde_cs_00_2 = 0.3125*psitilde_cs_00_1 + 1.875*z*psitilde_cs_00_1 - 0.5625*psitilde_cs_00_0;
-    const double psitilde_cs_01_0 = 1;
-    const double psitilde_cs_01_1 = 3*z + 2;
-    const double psitilde_cs_02_0 = 1;
-    const double psitilde_cs_10_0 = 1;
-    const double psitilde_cs_10_1 = 3*z + 2;
-    const double psitilde_cs_11_0 = 1;
-    const double psitilde_cs_20_0 = 1;
-    
-    // Compute basisvalues
-    const double basisvalue0 = 0.866025403784439*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
-    const double basisvalue1 = 2.73861278752583*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
-    const double basisvalue2 = 1.58113883008419*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
-    const double basisvalue3 = 1.11803398874989*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
-    const double basisvalue4 = 5.1234753829798*psitilde_a_2*scalings_y_2*psitilde_bs_2_0*scalings_z_2*psitilde_cs_20_0;
-    const double basisvalue5 = 3.96862696659689*psitilde_a_1*scalings_y_1*psitilde_bs_1_1*scalings_z_2*psitilde_cs_11_0;
-    const double basisvalue6 = 2.29128784747792*psitilde_a_0*scalings_y_0*psitilde_bs_0_2*scalings_z_2*psitilde_cs_02_0;
-    const double basisvalue7 = 3.24037034920393*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_1;
-    const double basisvalue8 = 1.87082869338697*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_1;
-    const double basisvalue9 = 1.3228756555323*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_2;
-    
-    // Table(s) of coefficients
-    static const double coefficients0[10][10] = \
-    {{-0.0577350269189626, -0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, 0.0503952630678969, 0.0290957186981323, 0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
-    {-0.0577350269189625, 0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, -0.050395263067897, 0.0290957186981323, -0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
-    {-0.0577350269189625, 0, 0.0702728368926306, -0.0248451997499977, 0, 0, 0.0872871560943969, 0, -0.0475131096733199, 0.0167984210226323},
-    {-0.0577350269189626, 0, 0, 0.074535599249993, 0, 0, 0, 0, 0, 0.100790526135794},
-    {0.23094010767585, 0, 0.140545673785261, 0.0993807989999906, 0, 0, 0, 0, 0.1187827741833, -0.0671936840905293},
-    {0.230940107675851, 0.121716123890037, -0.0702728368926306, 0.0993807989999907, 0, 0, 0, 0.102868899974728, -0.0593913870916499, -0.0671936840905293},
-    {0.23094010767585, 0.121716123890037, 0.0702728368926307, -0.0993807989999907, 0, 0.100790526135794, -0.087287156094397, -0.0205737799949456, -0.01187827741833, 0.0167984210226323},
-    {0.23094010767585, -0.121716123890037, -0.0702728368926307, 0.0993807989999906, 0, 0, 0, -0.102868899974728, -0.0593913870916499, -0.0671936840905293},
-    {0.23094010767585, -0.121716123890037, 0.0702728368926306, -0.0993807989999906, 0, -0.100790526135794, -0.0872871560943969, 0.0205737799949456, -0.01187827741833, 0.0167984210226323},
-    {0.23094010767585, 0, -0.140545673785261, -0.0993807989999906, -0.130120009726471, 0, 0.0290957186981323, 0, 0.02375655483666, 0.0167984210226323}};
-    
-    // Interesting (new) part
-    // Tables of derivatives of the polynomial base (transpose)
-    static const double dmats0[10][10] = \
-    {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-    {6.32455532033676, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-    {0, 11.2249721603218, 0, 0, 0, 0, 0, 0, 0, 0},
-    {4.58257569495584, 0, 8.36660026534076, -1.18321595661992, 0, 0, 0, 0, 0, 0},
-    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-    {3.74165738677394, 0, 0, 8.69482604771366, 0, 0, 0, 0, 0, 0},
-    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
-    
-    static const double dmats1[10][10] = \
-    {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-    {3.16227766016838, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-    {5.47722557505166, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-    {2.95803989154981, 5.61248608016091, -1.08012344973464, -0.763762615825974, 0, 0, 0, 0, 0, 0},
-    {2.29128784747792, 7.24568837309472, 4.18330013267038, -0.591607978309962, 0, 0, 0, 0, 0, 0},
-    {-2.64575131106459, 0, 9.66091783079296, 0.683130051063974, 0, 0, 0, 0, 0, 0},
-    {1.87082869338697, 0, 0, 4.34741302385683, 0, 0, 0, 0, 0, 0},
-    {3.24037034920393, 0, 0, 7.52994023880668, 0, 0, 0, 0, 0, 0},
-    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
-    
-    static const double dmats2[10][10] = \
-    {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-    {3.16227766016838, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-    {1.82574185835055, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-    {5.16397779494322, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-    {2.95803989154981, 5.61248608016091, -1.08012344973464, -0.763762615825974, 0, 0, 0, 0, 0, 0},
-    {2.29128784747792, 1.44913767461894, 4.18330013267038, -0.591607978309962, 0, 0, 0, 0, 0, 0},
-    {1.32287565553229, 0, 3.86436713231718, -0.341565025531986, 0, 0, 0, 0, 0, 0},
-    {1.87082869338697, 7.09929573971954, 0, 4.34741302385683, 0, 0, 0, 0, 0, 0},
-    {1.08012344973464, 0, 7.09929573971954, 2.50998007960223, 0, 0, 0, 0, 0, 0},
-    {-3.81881307912987, 0, 0, 8.87411967464942, 0, 0, 0, 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;
-    double coeff0_6 = 0;
-    double coeff0_7 = 0;
-    double coeff0_8 = 0;
-    double coeff0_9 = 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;
-    double new_coeff0_6 = 0;
-    double new_coeff0_7 = 0;
-    double new_coeff0_8 = 0;
-    double new_coeff0_9 = 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];
-      new_coeff0_6 = coefficients0[dof][6];
-      new_coeff0_7 = coefficients0[dof][7];
-      new_coeff0_8 = coefficients0[dof][8];
-      new_coeff0_9 = coefficients0[dof][9];
-    
-      // 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;
-        coeff0_6 = new_coeff0_6;
-        coeff0_7 = new_coeff0_7;
-        coeff0_8 = new_coeff0_8;
-        coeff0_9 = new_coeff0_9;
-    
-        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] + coeff0_6*dmats0[6][0] + coeff0_7*dmats0[7][0] + coeff0_8*dmats0[8][0] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][1] + coeff0_7*dmats0[7][1] + coeff0_8*dmats0[8][1] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][2] + coeff0_7*dmats0[7][2] + coeff0_8*dmats0[8][2] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][3] + coeff0_7*dmats0[7][3] + coeff0_8*dmats0[8][3] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][4] + coeff0_7*dmats0[7][4] + coeff0_8*dmats0[8][4] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][5] + coeff0_7*dmats0[7][5] + coeff0_8*dmats0[8][5] + coeff0_9*dmats0[9][5];
-          new_coeff0_6 = coeff0_0*dmats0[0][6] + coeff0_1*dmats0[1][6] + coeff0_2*dmats0[2][6] + coeff0_3*dmats0[3][6] + coeff0_4*dmats0[4][6] + coeff0_5*dmats0[5][6] + coeff0_6*dmats0[6][6] + coeff0_7*dmats0[7][6] + coeff0_8*dmats0[8][6] + coeff0_9*dmats0[9][6];
-          new_coeff0_7 = coeff0_0*dmats0[0][7] + coeff0_1*dmats0[1][7] + coeff0_2*dmats0[2][7] + coeff0_3*dmats0[3][7] + coeff0_4*dmats0[4][7] + coeff0_5*dmats0[5][7] + coeff0_6*dmats0[6][7] + coeff0_7*dmats0[7][7] + coeff0_8*dmats0[8][7] + coeff0_9*dmats0[9][7];
-          new_coeff0_8 = coeff0_0*dmats0[0][8] + coeff0_1*dmats0[1][8] + coeff0_2*dmats0[2][8] + coeff0_3*dmats0[3][8] + coeff0_4*dmats0[4][8] + coeff0_5*dmats0[5][8] + coeff0_6*dmats0[6][8] + coeff0_7*dmats0[7][8] + coeff0_8*dmats0[8][8] + coeff0_9*dmats0[9][8];
-          new_coeff0_9 = coeff0_0*dmats0[0][9] + coeff0_1*dmats0[1][9] + coeff0_2*dmats0[2][9] + coeff0_3*dmats0[3][9] + coeff0_4*dmats0[4][9] + coeff0_5*dmats0[5][9] + coeff0_6*dmats0[6][9] + coeff0_7*dmats0[7][9] + coeff0_8*dmats0[8][9] + coeff0_9*dmats0[9][9];
-        }
-        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] + coeff0_6*dmats1[6][0] + coeff0_7*dmats1[7][0] + coeff0_8*dmats1[8][0] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][1] + coeff0_7*dmats1[7][1] + coeff0_8*dmats1[8][1] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][2] + coeff0_7*dmats1[7][2] + coeff0_8*dmats1[8][2] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][3] + coeff0_7*dmats1[7][3] + coeff0_8*dmats1[8][3] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][4] + coeff0_7*dmats1[7][4] + coeff0_8*dmats1[8][4] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][5] + coeff0_7*dmats1[7][5] + coeff0_8*dmats1[8][5] + coeff0_9*dmats1[9][5];
-          new_coeff0_6 = coeff0_0*dmats1[0][6] + coeff0_1*dmats1[1][6] + coeff0_2*dmats1[2][6] + coeff0_3*dmats1[3][6] + coeff0_4*dmats1[4][6] + coeff0_5*dmats1[5][6] + coeff0_6*dmats1[6][6] + coeff0_7*dmats1[7][6] + coeff0_8*dmats1[8][6] + coeff0_9*dmats1[9][6];
-          new_coeff0_7 = coeff0_0*dmats1[0][7] + coeff0_1*dmats1[1][7] + coeff0_2*dmats1[2][7] + coeff0_3*dmats1[3][7] + coeff0_4*dmats1[4][7] + coeff0_5*dmats1[5][7] + coeff0_6*dmats1[6][7] + coeff0_7*dmats1[7][7] + coeff0_8*dmats1[8][7] + coeff0_9*dmats1[9][7];
-          new_coeff0_8 = coeff0_0*dmats1[0][8] + coeff0_1*dmats1[1][8] + coeff0_2*dmats1[2][8] + coeff0_3*dmats1[3][8] + coeff0_4*dmats1[4][8] + coeff0_5*dmats1[5][8] + coeff0_6*dmats1[6][8] + coeff0_7*dmats1[7][8] + coeff0_8*dmats1[8][8] + coeff0_9*dmats1[9][8];
-          new_coeff0_9 = coeff0_0*dmats1[0][9] + coeff0_1*dmats1[1][9] + coeff0_2*dmats1[2][9] + coeff0_3*dmats1[3][9] + coeff0_4*dmats1[4][9] + coeff0_5*dmats1[5][9] + coeff0_6*dmats1[6][9] + coeff0_7*dmats1[7][9] + coeff0_8*dmats1[8][9] + coeff0_9*dmats1[9][9];
-        }
-        if(combinations[deriv_num][j] == 2)
-        {
-          new_coeff0_0 = coeff0_0*dmats2[0][0] + coeff0_1*dmats2[1][0] + coeff0_2*dmats2[2][0] + coeff0_3*dmats2[3][0] + coeff0_4*dmats2[4][0] + coeff0_5*dmats2[5][0] + coeff0_6*dmats2[6][0] + coeff0_7*dmats2[7][0] + coeff0_8*dmats2[8][0] + coeff0_9*dmats2[9][0];
-          new_coeff0_1 = coeff0_0*dmats2[0][1] + coeff0_1*dmats2[1][1] + coeff0_2*dmats2[2][1] + coeff0_3*dmats2[3][1] + coeff0_4*dmats2[4][1] + coeff0_5*dmats2[5][1] + coeff0_6*dmats2[6][1] + coeff0_7*dmats2[7][1] + coeff0_8*dmats2[8][1] + coeff0_9*dmats2[9][1];
-          new_coeff0_2 = coeff0_0*dmats2[0][2] + coeff0_1*dmats2[1][2] + coeff0_2*dmats2[2][2] + coeff0_3*dmats2[3][2] + coeff0_4*dmats2[4][2] + coeff0_5*dmats2[5][2] + coeff0_6*dmats2[6][2] + coeff0_7*dmats2[7][2] + coeff0_8*dmats2[8][2] + coeff0_9*dmats2[9][2];
-          new_coeff0_3 = coeff0_0*dmats2[0][3] + coeff0_1*dmats2[1][3] + coeff0_2*dmats2[2][3] + coeff0_3*dmats2[3][3] + coeff0_4*dmats2[4][3] + coeff0_5*dmats2[5][3] + coeff0_6*dmats2[6][3] + coeff0_7*dmats2[7][3] + coeff0_8*dmats2[8][3] + coeff0_9*dmats2[9][3];
-          new_coeff0_4 = coeff0_0*dmats2[0][4] + coeff0_1*dmats2[1][4] + coeff0_2*dmats2[2][4] + coeff0_3*dmats2[3][4] + coeff0_4*dmats2[4][4] + coeff0_5*dmats2[5][4] + coeff0_6*dmats2[6][4] + coeff0_7*dmats2[7][4] + coeff0_8*dmats2[8][4] + coeff0_9*dmats2[9][4];
-          new_coeff0_5 = coeff0_0*dmats2[0][5] + coeff0_1*dmats2[1][5] + coeff0_2*dmats2[2][5] + coeff0_3*dmats2[3][5] + coeff0_4*dmats2[4][5] + coeff0_5*dmats2[5][5] + coeff0_6*dmats2[6][5] + coeff0_7*dmats2[7][5] + coeff0_8*dmats2[8][5] + coeff0_9*dmats2[9][5];
-          new_coeff0_6 = coeff0_0*dmats2[0][6] + coeff0_1*dmats2[1][6] + coeff0_2*dmats2[2][6] + coeff0_3*dmats2[3][6] + coeff0_4*dmats2[4][6] + coeff0_5*dmats2[5][6] + coeff0_6*dmats2[6][6] + coeff0_7*dmats2[7][6] + coeff0_8*dmats2[8][6] + coeff0_9*dmats2[9][6];
-          new_coeff0_7 = coeff0_0*dmats2[0][7] + coeff0_1*dmats2[1][7] + coeff0_2*dmats2[2][7] + coeff0_3*dmats2[3][7] + coeff0_4*dmats2[4][7] + coeff0_5*dmats2[5][7] + coeff0_6*dmats2[6][7] + coeff0_7*dmats2[7][7] + coeff0_8*dmats2[8][7] + coeff0_9*dmats2[9][7];
-          new_coeff0_8 = coeff0_0*dmats2[0][8] + coeff0_1*dmats2[1][8] + coeff0_2*dmats2[2][8] + coeff0_3*dmats2[3][8] + coeff0_4*dmats2[4][8] + coeff0_5*dmats2[5][8] + coeff0_6*dmats2[6][8] + coeff0_7*dmats2[7][8] + coeff0_8*dmats2[8][8] + coeff0_9*dmats2[9][8];
-          new_coeff0_9 = coeff0_0*dmats2[0][9] + coeff0_1*dmats2[1][9] + coeff0_2*dmats2[2][9] + coeff0_3*dmats2[3][9] + coeff0_4*dmats2[4][9] + coeff0_5*dmats2[5][9] + coeff0_6*dmats2[6][9] + coeff0_7*dmats2[7][9] + coeff0_8*dmats2[8][9] + coeff0_9*dmats2[9][9];
-        }
-    
-      }
-      // 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 + new_coeff0_6*basisvalue6 + new_coeff0_7*basisvalue7 + new_coeff0_8*basisvalue8 + new_coeff0_9*basisvalue9;
-    }
-    
-    // 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 solitarywave3d_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 solitarywave3d_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[10][1][3] = {{{0, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 0, 1}}, {{0, 0.5, 0.5}}, {{0.5, 0, 0.5}}, {{0.5, 0.5, 0}}, {{0, 0, 0.5}}, {{0, 0.5, 0}}, {{0.5, 0, 0}}};
-    static const double W[10][1] = {{1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}};
-    static const double D[10][1][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] - X[i][0][2];
-    const double w1 = X[i][0][0];
-    const double w2 = X[i][0][1];
-    const double w3 = X[i][0][2];
-    
-    // Compute affine mapping y = F(X)
-    double y[3];
-    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0] + w3*x[3][0];
-    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1] + w3*x[3][1];
-    y[2] = w0*x[0][2] + w1*x[1][2] + w2*x[2][2] + w3*x[3][2];
-    
-    // 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 solitarywave3d_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 solitarywave3d_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];
-    vertex_values[3] = dof_values[3];
-}
-
-/// Return the number of sub elements (for a mixed element)
-unsigned int solitarywave3d_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* solitarywave3d_1_finite_element_0_0::create_sub_element(unsigned int i) const
-{
-    return new solitarywave3d_1_finite_element_0_0();
-}
-
-
-/// Constructor
-solitarywave3d_1_finite_element_0_1::solitarywave3d_1_finite_element_0_1() : ufc::finite_element()
-{
-    // Do nothing
-}
-
-/// Destructor
-solitarywave3d_1_finite_element_0_1::~solitarywave3d_1_finite_element_0_1()
-{
-    // Do nothing
-}
-
-/// Return a string identifying the finite element
-const char* solitarywave3d_1_finite_element_0_1::signature() const
-{
-    return "FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)";
-}
-
-/// Return the cell shape
-ufc::shape solitarywave3d_1_finite_element_0_1::cell_shape() const
-{
-    return ufc::tetrahedron;
-}
-
-/// Return the dimension of the finite element function space
-unsigned int solitarywave3d_1_finite_element_0_1::space_dimension() const
-{
-    return 10;
-}
-
-/// Return the rank of the value space
-unsigned int solitarywave3d_1_finite_element_0_1::value_rank() const
-{
-    return 0;
-}
-
-/// Return the dimension of the value space for axis i
-unsigned int solitarywave3d_1_finite_element_0_1::value_dimension(unsigned int i) const
-{
-    return 1;
-}
-
-/// Evaluate basis function i at given point in cell
-void solitarywave3d_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_02 = element_coordinates[3][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];
-    const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
-    const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
-    const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
-    const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
-    
-    // Compute sub determinants
-    const double d00 = J_11*J_22 - J_12*J_21;
-    const double d01 = J_12*J_20 - J_10*J_22;
-    const double d02 = J_10*J_21 - J_11*J_20;
-    
-    const double d10 = J_02*J_21 - J_01*J_22;
-    const double d11 = J_00*J_22 - J_02*J_20;
-    const double d12 = J_01*J_20 - J_00*J_21;
-    
-    const double d20 = J_01*J_12 - J_02*J_11;
-    const double d21 = J_02*J_10 - J_00*J_12;
-    const double d22 = J_00*J_11 - J_01*J_10;
-    
-    // Compute determinant of Jacobian
-    double detJ = J_00*d00 + J_10*d10 + J_20*d20;
-    
-    // Compute inverse of Jacobian
-    
-    // Compute constants
-    const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
-                    + d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
-                    + d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
-    
-    const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
-                    + d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
-                    + d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
-    
-    const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
-                    + d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
-                    + d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
-    
-    // Get coordinates and map to the UFC reference element
-    double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
-    double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
-    double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
-    
-    // Map coordinates to the reference cube
-    if (std::abs(y + z - 1.0) < 1e-14)
-      x = 1.0;
-    else
-      x = -2.0 * x/(y + z - 1.0) - 1.0;
-    if (std::abs(z - 1.0) < 1e-14)
-      y = -1.0;
-    else
-      y = 2.0 * y/(1.0 - z) - 1.0;
-    z = 2.0 * z - 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);
-    const double scalings_z_0 = 1;
-    const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
-    const double scalings_z_2 = scalings_z_1*(0.5 - 0.5*z);
-    
-    // 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 psitilde_cs
-    const double psitilde_cs_00_0 = 1;
-    const double psitilde_cs_00_1 = 2*z + 1;
-    const double psitilde_cs_00_2 = 0.3125*psitilde_cs_00_1 + 1.875*z*psitilde_cs_00_1 - 0.5625*psitilde_cs_00_0;
-    const double psitilde_cs_01_0 = 1;
-    const double psitilde_cs_01_1 = 3*z + 2;
-    const double psitilde_cs_02_0 = 1;
-    const double psitilde_cs_10_0 = 1;
-    const double psitilde_cs_10_1 = 3*z + 2;
-    const double psitilde_cs_11_0 = 1;
-    const double psitilde_cs_20_0 = 1;
-    
-    // Compute basisvalues
-    const double basisvalue0 = 0.866025403784439*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
-    const double basisvalue1 = 2.73861278752583*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
-    const double basisvalue2 = 1.58113883008419*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
-    const double basisvalue3 = 1.11803398874989*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
-    const double basisvalue4 = 5.1234753829798*psitilde_a_2*scalings_y_2*psitilde_bs_2_0*scalings_z_2*psitilde_cs_20_0;
-    const double basisvalue5 = 3.96862696659689*psitilde_a_1*scalings_y_1*psitilde_bs_1_1*scalings_z_2*psitilde_cs_11_0;
-    const double basisvalue6 = 2.29128784747792*psitilde_a_0*scalings_y_0*psitilde_bs_0_2*scalings_z_2*psitilde_cs_02_0;
-    const double basisvalue7 = 3.24037034920393*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_1;
-    const double basisvalue8 = 1.87082869338697*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_1;
-    const double basisvalue9 = 1.3228756555323*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_2;
-    
-    // Table(s) of coefficients
-    static const double coefficients0[10][10] = \
-    {{-0.0577350269189626, -0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, 0.0503952630678969, 0.0290957186981323, 0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
-    {-0.0577350269189625, 0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, -0.050395263067897, 0.0290957186981323, -0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
-    {-0.0577350269189625, 0, 0.0702728368926306, -0.0248451997499977, 0, 0, 0.0872871560943969, 0, -0.0475131096733199, 0.0167984210226323},
-    {-0.0577350269189626, 0, 0, 0.074535599249993, 0, 0, 0, 0, 0, 0.100790526135794},
-    {0.23094010767585, 0, 0.140545673785261, 0.0993807989999906, 0, 0, 0, 0, 0.1187827741833, -0.0671936840905293},
-    {0.230940107675851, 0.121716123890037, -0.0702728368926306, 0.0993807989999907, 0, 0, 0, 0.102868899974728, -0.0593913870916499, -0.0671936840905293},
-    {0.23094010767585, 0.121716123890037, 0.0702728368926307, -0.0993807989999907, 0, 0.100790526135794, -0.087287156094397, -0.0205737799949456, -0.01187827741833, 0.0167984210226323},
-    {0.23094010767585, -0.121716123890037, -0.0702728368926307, 0.0993807989999906, 0, 0, 0, -0.102868899974728, -0.0593913870916499, -0.0671936840905293},
-    {0.23094010767585, -0.121716123890037, 0.0702728368926306, -0.0993807989999906, 0, -0.100790526135794, -0.0872871560943969, 0.0205737799949456, -0.01187827741833, 0.0167984210226323},
-    {0.23094010767585, 0, -0.140545673785261, -0.0993807989999906, -0.130120009726471, 0, 0.0290957186981323, 0, 0.02375655483666, 0.0167984210226323}};
-    
-    // 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];
-    const double coeff0_6 = coefficients0[dof][6];
-    const double coeff0_7 = coefficients0[dof][7];
-    const double coeff0_8 = coefficients0[dof][8];
-    const double coeff0_9 = coefficients0[dof][9];
-    
-    // Compute value(s)
-    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5 + coeff0_6*basisvalue6 + coeff0_7*basisvalue7 + coeff0_8*basisvalue8 + coeff0_9*basisvalue9;
-}
-
-/// Evaluate all basis functions at given point in cell
-void solitarywave3d_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 solitarywave3d_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_02 = element_coordinates[3][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];
-    const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
-    const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
-    const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
-    const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
-    
-    // Compute sub determinants
-    const double d00 = J_11*J_22 - J_12*J_21;
-    const double d01 = J_12*J_20 - J_10*J_22;
-    const double d02 = J_10*J_21 - J_11*J_20;
-    
-    const double d10 = J_02*J_21 - J_01*J_22;
-    const double d11 = J_00*J_22 - J_02*J_20;
-    const double d12 = J_01*J_20 - J_00*J_21;
-    
-    const double d20 = J_01*J_12 - J_02*J_11;
-    const double d21 = J_02*J_10 - J_00*J_12;
-    const double d22 = J_00*J_11 - J_01*J_10;
-    
-    // Compute determinant of Jacobian
-    double detJ = J_00*d00 + J_10*d10 + J_20*d20;
-    
-    // Compute inverse of Jacobian
-    
-    // Compute constants
-    const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
-                    + d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
-                    + d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
-    
-    const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
-                    + d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
-                    + d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
-    
-    const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
-                    + d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
-                    + d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
-    
-    // Get coordinates and map to the UFC reference element
-    double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
-    double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
-    double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
-    
-    // Map coordinates to the reference cube
-    if (std::abs(y + z - 1.0) < 1e-14)
-      x = 1.0;
-    else
-      x = -2.0 * x/(y + z - 1.0) - 1.0;
-    if (std::abs(z - 1.0) < 1e-14)
-      y = -1.0;
-    else
-      y = 2.0 * y/(1.0 - z) - 1.0;
-    z = 2.0 * z - 1.0;
-    
-    // Compute number of derivatives
-    unsigned int num_derivatives = 1;
-    
-    for (unsigned int j = 0; j < n; j++)
-      num_derivatives *= 3;
-    
-    
-    // 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 > 2)
-            combinations[row][col] = 0;
-          else
-          {
-            combinations[row][col] += 1;
-            break;
-          }
-        }
-      }
-    }
-    
-    // Compute inverse of Jacobian
-    const double Jinv[3][3] ={{d00 / detJ, d10 / detJ, d20 / detJ}, {d01 / detJ, d11 / detJ, d21 / detJ}, {d02 / detJ, d12 / detJ, d22 / 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);
-    const double scalings_z_0 = 1;
-    const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
-    const double scalings_z_2 = scalings_z_1*(0.5 - 0.5*z);
-    
-    // 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 psitilde_cs
-    const double psitilde_cs_00_0 = 1;
-    const double psitilde_cs_00_1 = 2*z + 1;
-    const double psitilde_cs_00_2 = 0.3125*psitilde_cs_00_1 + 1.875*z*psitilde_cs_00_1 - 0.5625*psitilde_cs_00_0;
-    const double psitilde_cs_01_0 = 1;
-    const double psitilde_cs_01_1 = 3*z + 2;
-    const double psitilde_cs_02_0 = 1;
-    const double psitilde_cs_10_0 = 1;
-    const double psitilde_cs_10_1 = 3*z + 2;
-    const double psitilde_cs_11_0 = 1;
-    const double psitilde_cs_20_0 = 1;
-    
-    // Compute basisvalues
-    const double basisvalue0 = 0.866025403784439*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
-    const double basisvalue1 = 2.73861278752583*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
-    const double basisvalue2 = 1.58113883008419*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
-    const double basisvalue3 = 1.11803398874989*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
-    const double basisvalue4 = 5.1234753829798*psitilde_a_2*scalings_y_2*psitilde_bs_2_0*scalings_z_2*psitilde_cs_20_0;
-    const double basisvalue5 = 3.96862696659689*psitilde_a_1*scalings_y_1*psitilde_bs_1_1*scalings_z_2*psitilde_cs_11_0;
-    const double basisvalue6 = 2.29128784747792*psitilde_a_0*scalings_y_0*psitilde_bs_0_2*scalings_z_2*psitilde_cs_02_0;
-    const double basisvalue7 = 3.24037034920393*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_1;
-    const double basisvalue8 = 1.87082869338697*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_1;
-    const double basisvalue9 = 1.3228756555323*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_2;
-    
-    // Table(s) of coefficients
-    static const double coefficients0[10][10] = \
-    {{-0.0577350269189626, -0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, 0.0503952630678969, 0.0290957186981323, 0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
-    {-0.0577350269189625, 0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, -0.050395263067897, 0.0290957186981323, -0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
-    {-0.0577350269189625, 0, 0.0702728368926306, -0.0248451997499977, 0, 0, 0.0872871560943969, 0, -0.0475131096733199, 0.0167984210226323},
-    {-0.0577350269189626, 0, 0, 0.074535599249993, 0, 0, 0, 0, 0, 0.100790526135794},
-    {0.23094010767585, 0, 0.140545673785261, 0.0993807989999906, 0, 0, 0, 0, 0.1187827741833, -0.0671936840905293},
-    {0.230940107675851, 0.121716123890037, -0.0702728368926306, 0.0993807989999907, 0, 0, 0, 0.102868899974728, -0.0593913870916499, -0.0671936840905293},
-    {0.23094010767585, 0.121716123890037, 0.0702728368926307, -0.0993807989999907, 0, 0.100790526135794, -0.087287156094397, -0.0205737799949456, -0.01187827741833, 0.0167984210226323},
-    {0.23094010767585, -0.121716123890037, -0.0702728368926307, 0.0993807989999906, 0, 0, 0, -0.102868899974728, -0.0593913870916499, -0.0671936840905293},
-    {0.23094010767585, -0.121716123890037, 0.0702728368926306, -0.0993807989999906, 0, -0.100790526135794, -0.0872871560943969, 0.0205737799949456, -0.01187827741833, 0.0167984210226323},
-    {0.23094010767585, 0, -0.140545673785261, -0.0993807989999906, -0.130120009726471, 0, 0.0290957186981323, 0, 0.02375655483666, 0.0167984210226323}};
-    
-    // Interesting (new) part
-    // Tables of derivatives of the polynomial base (transpose)
-    static const double dmats0[10][10] = \
-    {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-    {6.32455532033676, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-    {0, 11.2249721603218, 0, 0, 0, 0, 0, 0, 0, 0},
-    {4.58257569495584, 0, 8.36660026534076, -1.18321595661992, 0, 0, 0, 0, 0, 0},
-    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-    {3.74165738677394, 0, 0, 8.69482604771366, 0, 0, 0, 0, 0, 0},
-    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
-    
-    static const double dmats1[10][10] = \
-    {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-    {3.16227766016838, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-    {5.47722557505166, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-    {2.95803989154981, 5.61248608016091, -1.08012344973464, -0.763762615825974, 0, 0, 0, 0, 0, 0},
-    {2.29128784747792, 7.24568837309472, 4.18330013267038, -0.591607978309962, 0, 0, 0, 0, 0, 0},
-    {-2.64575131106459, 0, 9.66091783079296, 0.683130051063974, 0, 0, 0, 0, 0, 0},
-    {1.87082869338697, 0, 0, 4.34741302385683, 0, 0, 0, 0, 0, 0},
-    {3.24037034920393, 0, 0, 7.52994023880668, 0, 0, 0, 0, 0, 0},
-    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
-    
-    static const double dmats2[10][10] = \
-    {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-    {3.16227766016838, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-    {1.82574185835055, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-    {5.16397779494322, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-    {2.95803989154981, 5.61248608016091, -1.08012344973464, -0.763762615825974, 0, 0, 0, 0, 0, 0},
-    {2.29128784747792, 1.44913767461894, 4.18330013267038, -0.591607978309962, 0, 0, 0, 0, 0, 0},
-    {1.32287565553229, 0, 3.86436713231718, -0.341565025531986, 0, 0, 0, 0, 0, 0},
-    {1.87082869338697, 7.09929573971954, 0, 4.34741302385683, 0, 0, 0, 0, 0, 0},
-    {1.08012344973464, 0, 7.09929573971954, 2.50998007960223, 0, 0, 0, 0, 0, 0},
-    {-3.81881307912987, 0, 0, 8.87411967464942, 0, 0, 0, 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;
-    double coeff0_6 = 0;
-    double coeff0_7 = 0;
-    double coeff0_8 = 0;
-    double coeff0_9 = 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;
-    double new_coeff0_6 = 0;
-    double new_coeff0_7 = 0;
-    double new_coeff0_8 = 0;
-    double new_coeff0_9 = 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];
-      new_coeff0_6 = coefficients0[dof][6];
-      new_coeff0_7 = coefficients0[dof][7];
-      new_coeff0_8 = coefficients0[dof][8];
-      new_coeff0_9 = coefficients0[dof][9];
-    
-      // 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;
-        coeff0_6 = new_coeff0_6;
-        coeff0_7 = new_coeff0_7;
-        coeff0_8 = new_coeff0_8;
-        coeff0_9 = new_coeff0_9;
-    
-        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] + coeff0_6*dmats0[6][0] + coeff0_7*dmats0[7][0] + coeff0_8*dmats0[8][0] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][1] + coeff0_7*dmats0[7][1] + coeff0_8*dmats0[8][1] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][2] + coeff0_7*dmats0[7][2] + coeff0_8*dmats0[8][2] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][3] + coeff0_7*dmats0[7][3] + coeff0_8*dmats0[8][3] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][4] + coeff0_7*dmats0[7][4] + coeff0_8*dmats0[8][4] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][5] + coeff0_7*dmats0[7][5] + coeff0_8*dmats0[8][5] + coeff0_9*dmats0[9][5];
-          new_coeff0_6 = coeff0_0*dmats0[0][6] + coeff0_1*dmats0[1][6] + coeff0_2*dmats0[2][6] + coeff0_3*dmats0[3][6] + coeff0_4*dmats0[4][6] + coeff0_5*dmats0[5][6] + coeff0_6*dmats0[6][6] + coeff0_7*dmats0[7][6] + coeff0_8*dmats0[8][6] + coeff0_9*dmats0[9][6];
-          new_coeff0_7 = coeff0_0*dmats0[0][7] + coeff0_1*dmats0[1][7] + coeff0_2*dmats0[2][7] + coeff0_3*dmats0[3][7] + coeff0_4*dmats0[4][7] + coeff0_5*dmats0[5][7] + coeff0_6*dmats0[6][7] + coeff0_7*dmats0[7][7] + coeff0_8*dmats0[8][7] + coeff0_9*dmats0[9][7];
-          new_coeff0_8 = coeff0_0*dmats0[0][8] + coeff0_1*dmats0[1][8] + coeff0_2*dmats0[2][8] + coeff0_3*dmats0[3][8] + coeff0_4*dmats0[4][8] + coeff0_5*dmats0[5][8] + coeff0_6*dmats0[6][8] + coeff0_7*dmats0[7][8] + coeff0_8*dmats0[8][8] + coeff0_9*dmats0[9][8];
-          new_coeff0_9 = coeff0_0*dmats0[0][9] + coeff0_1*dmats0[1][9] + coeff0_2*dmats0[2][9] + coeff0_3*dmats0[3][9] + coeff0_4*dmats0[4][9] + coeff0_5*dmats0[5][9] + coeff0_6*dmats0[6][9] + coeff0_7*dmats0[7][9] + coeff0_8*dmats0[8][9] + coeff0_9*dmats0[9][9];
-        }
-        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] + coeff0_6*dmats1[6][0] + coeff0_7*dmats1[7][0] + coeff0_8*dmats1[8][0] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][1] + coeff0_7*dmats1[7][1] + coeff0_8*dmats1[8][1] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][2] + coeff0_7*dmats1[7][2] + coeff0_8*dmats1[8][2] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][3] + coeff0_7*dmats1[7][3] + coeff0_8*dmats1[8][3] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][4] + coeff0_7*dmats1[7][4] + coeff0_8*dmats1[8][4] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][5] + coeff0_7*dmats1[7][5] + coeff0_8*dmats1[8][5] + coeff0_9*dmats1[9][5];
-          new_coeff0_6 = coeff0_0*dmats1[0][6] + coeff0_1*dmats1[1][6] + coeff0_2*dmats1[2][6] + coeff0_3*dmats1[3][6] + coeff0_4*dmats1[4][6] + coeff0_5*dmats1[5][6] + coeff0_6*dmats1[6][6] + coeff0_7*dmats1[7][6] + coeff0_8*dmats1[8][6] + coeff0_9*dmats1[9][6];
-          new_coeff0_7 = coeff0_0*dmats1[0][7] + coeff0_1*dmats1[1][7] + coeff0_2*dmats1[2][7] + coeff0_3*dmats1[3][7] + coeff0_4*dmats1[4][7] + coeff0_5*dmats1[5][7] + coeff0_6*dmats1[6][7] + coeff0_7*dmats1[7][7] + coeff0_8*dmats1[8][7] + coeff0_9*dmats1[9][7];
-          new_coeff0_8 = coeff0_0*dmats1[0][8] + coeff0_1*dmats1[1][8] + coeff0_2*dmats1[2][8] + coeff0_3*dmats1[3][8] + coeff0_4*dmats1[4][8] + coeff0_5*dmats1[5][8] + coeff0_6*dmats1[6][8] + coeff0_7*dmats1[7][8] + coeff0_8*dmats1[8][8] + coeff0_9*dmats1[9][8];
-          new_coeff0_9 = coeff0_0*dmats1[0][9] + coeff0_1*dmats1[1][9] + coeff0_2*dmats1[2][9] + coeff0_3*dmats1[3][9] + coeff0_4*dmats1[4][9] + coeff0_5*dmats1[5][9] + coeff0_6*dmats1[6][9] + coeff0_7*dmats1[7][9] + coeff0_8*dmats1[8][9] + coeff0_9*dmats1[9][9];
-        }
-        if(combinations[deriv_num][j] == 2)
-        {
-          new_coeff0_0 = coeff0_0*dmats2[0][0] + coeff0_1*dmats2[1][0] + coeff0_2*dmats2[2][0] + coeff0_3*dmats2[3][0] + coeff0_4*dmats2[4][0] + coeff0_5*dmats2[5][0] + coeff0_6*dmats2[6][0] + coeff0_7*dmats2[7][0] + coeff0_8*dmats2[8][0] + coeff0_9*dmats2[9][0];
-          new_coeff0_1 = coeff0_0*dmats2[0][1] + coeff0_1*dmats2[1][1] + coeff0_2*dmats2[2][1] + coeff0_3*dmats2[3][1] + coeff0_4*dmats2[4][1] + coeff0_5*dmats2[5][1] + coeff0_6*dmats2[6][1] + coeff0_7*dmats2[7][1] + coeff0_8*dmats2[8][1] + coeff0_9*dmats2[9][1];
-          new_coeff0_2 = coeff0_0*dmats2[0][2] + coeff0_1*dmats2[1][2] + coeff0_2*dmats2[2][2] + coeff0_3*dmats2[3][2] + coeff0_4*dmats2[4][2] + coeff0_5*dmats2[5][2] + coeff0_6*dmats2[6][2] + coeff0_7*dmats2[7][2] + coeff0_8*dmats2[8][2] + coeff0_9*dmats2[9][2];
-          new_coeff0_3 = coeff0_0*dmats2[0][3] + coeff0_1*dmats2[1][3] + coeff0_2*dmats2[2][3] + coeff0_3*dmats2[3][3] + coeff0_4*dmats2[4][3] + coeff0_5*dmats2[5][3] + coeff0_6*dmats2[6][3] + coeff0_7*dmats2[7][3] + coeff0_8*dmats2[8][3] + coeff0_9*dmats2[9][3];
-          new_coeff0_4 = coeff0_0*dmats2[0][4] + coeff0_1*dmats2[1][4] + coeff0_2*dmats2[2][4] + coeff0_3*dmats2[3][4] + coeff0_4*dmats2[4][4] + coeff0_5*dmats2[5][4] + coeff0_6*dmats2[6][4] + coeff0_7*dmats2[7][4] + coeff0_8*dmats2[8][4] + coeff0_9*dmats2[9][4];
-          new_coeff0_5 = coeff0_0*dmats2[0][5] + coeff0_1*dmats2[1][5] + coeff0_2*dmats2[2][5] + coeff0_3*dmats2[3][5] + coeff0_4*dmats2[4][5] + coeff0_5*dmats2[5][5] + coeff0_6*dmats2[6][5] + coeff0_7*dmats2[7][5] + coeff0_8*dmats2[8][5] + coeff0_9*dmats2[9][5];
-          new_coeff0_6 = coeff0_0*dmats2[0][6] + coeff0_1*dmats2[1][6] + coeff0_2*dmats2[2][6] + coeff0_3*dmats2[3][6] + coeff0_4*dmats2[4][6] + coeff0_5*dmats2[5][6] + coeff0_6*dmats2[6][6] + coeff0_7*dmats2[7][6] + coeff0_8*dmats2[8][6] + coeff0_9*dmats2[9][6];
-          new_coeff0_7 = coeff0_0*dmats2[0][7] + coeff0_1*dmats2[1][7] + coeff0_2*dmats2[2][7] + coeff0_3*dmats2[3][7] + coeff0_4*dmats2[4][7] + coeff0_5*dmats2[5][7] + coeff0_6*dmats2[6][7] + coeff0_7*dmats2[7][7] + coeff0_8*dmats2[8][7] + coeff0_9*dmats2[9][7];
-          new_coeff0_8 = coeff0_0*dmats2[0][8] + coeff0_1*dmats2[1][8] + coeff0_2*dmats2[2][8] + coeff0_3*dmats2[3][8] + coeff0_4*dmats2[4][8] + coeff0_5*dmats2[5][8] + coeff0_6*dmats2[6][8] + coeff0_7*dmats2[7][8] + coeff0_8*dmats2[8][8] + coeff0_9*dmats2[9][8];
-          new_coeff0_9 = coeff0_0*dmats2[0][9] + coeff0_1*dmats2[1][9] + coeff0_2*dmats2[2][9] + coeff0_3*dmats2[3][9] + coeff0_4*dmats2[4][9] + coeff0_5*dmats2[5][9] + coeff0_6*dmats2[6][9] + coeff0_7*dmats2[7][9] + coeff0_8*dmats2[8][9] + coeff0_9*dmats2[9][9];
-        }
-    
-      }
-      // 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 + new_coeff0_6*basisvalue6 + new_coeff0_7*basisvalue7 + new_coeff0_8*basisvalue8 + new_coeff0_9*basisvalue9;
-    }
-    
-    // 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 solitarywave3d_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 solitarywave3d_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[10][1][3] = {{{0, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 0, 1}}, {{0, 0.5, 0.5}}, {{0.5, 0, 0.5}}, {{0.5, 0.5, 0}}, {{0, 0, 0.5}}, {{0, 0.5, 0}}, {{0.5, 0, 0}}};
-    static const double W[10][1] = {{1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}};
-    static const double D[10][1][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] - X[i][0][2];
-    const double w1 = X[i][0][0];
-    const double w2 = X[i][0][1];
-    const double w3 = X[i][0][2];
-    
-    // Compute affine mapping y = F(X)
-    double y[3];
-    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0] + w3*x[3][0];
-    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1] + w3*x[3][1];
-    y[2] = w0*x[0][2] + w1*x[1][2] + w2*x[2][2] + w3*x[3][2];
-    
-    // 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 solitarywave3d_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 solitarywave3d_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];
-    vertex_values[3] = dof_values[3];
-}
-
-/// Return the number of sub elements (for a mixed element)
-unsigned int solitarywave3d_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* solitarywave3d_1_finite_element_0_1::create_sub_element(unsigned int i) const
-{
-    return new solitarywave3d_1_finite_element_0_1();
-}
-
-
-/// Constructor
-solitarywave3d_1_finite_element_0::solitarywave3d_1_finite_element_0() : ufc::finite_element()
-{
-    // Do nothing
-}
-
-/// Destructor
-solitarywave3d_1_finite_element_0::~solitarywave3d_1_finite_element_0()
-{
-    // Do nothing
-}
-
-/// Return a string identifying the finite element
-const char* solitarywave3d_1_finite_element_0::signature() const
-{
-    return "MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) })";
-}
-
-/// Return the cell shape
-ufc::shape solitarywave3d_1_finite_element_0::cell_shape() const
-{
-    return ufc::tetrahedron;
-}
-
-/// Return the dimension of the finite element function space
-unsigned int solitarywave3d_1_finite_element_0::space_dimension() const
-{
-    return 20;
-}
-
-/// Return the rank of the value space
-unsigned int solitarywave3d_1_finite_element_0::value_rank() const
-{
-    return 1;
-}
-
-/// Return the dimension of the value space for axis i
-unsigned int solitarywave3d_1_finite_element_0::value_dimension(unsigned int i) const
-{
-    return 2;
-}
-
-/// Evaluate basis function i at given point in cell
-void solitarywave3d_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_02 = element_coordinates[3][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];
-    const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
-    const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
-    const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
-    const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
-    
-    // Compute sub determinants
-    const double d00 = J_11*J_22 - J_12*J_21;
-    const double d01 = J_12*J_20 - J_10*J_22;
-    const double d02 = J_10*J_21 - J_11*J_20;
-    
-    const double d10 = J_02*J_21 - J_01*J_22;
-    const double d11 = J_00*J_22 - J_02*J_20;
-    const double d12 = J_01*J_20 - J_00*J_21;
-    
-    const double d20 = J_01*J_12 - J_02*J_11;
-    const double d21 = J_02*J_10 - J_00*J_12;
-    const double d22 = J_00*J_11 - J_01*J_10;
-    
-    // Compute determinant of Jacobian
-    double detJ = J_00*d00 + J_10*d10 + J_20*d20;
-    
-    // Compute inverse of Jacobian
-    
-    // Compute constants
-    const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
-                    + d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
-                    + d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
-    
-    const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
-                    + d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
-                    + d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
-    
-    const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
-                    + d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
-                    + d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
-    
-    // Get coordinates and map to the UFC reference element
-    double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
-    double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
-    double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
-    
-    // Map coordinates to the reference cube
-    if (std::abs(y + z - 1.0) < 1e-14)
-      x = 1.0;
-    else
-      x = -2.0 * x/(y + z - 1.0) - 1.0;
-    if (std::abs(z - 1.0) < 1e-14)
-      y = -1.0;
-    else
-      y = 2.0 * y/(1.0 - z) - 1.0;
-    z = 2.0 * z - 1.0;
-    
-    // Reset values
-    values[0] = 0;
-    values[1] = 0;
-    
-    if (0 <= i && i <= 9)
-    {
-      // 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);
-      const double scalings_z_0 = 1;
-      const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
-      const double scalings_z_2 = scalings_z_1*(0.5 - 0.5*z);
-    
-      // 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 psitilde_cs
-      const double psitilde_cs_00_0 = 1;
-      const double psitilde_cs_00_1 = 2*z + 1;
-      const double psitilde_cs_00_2 = 0.3125*psitilde_cs_00_1 + 1.875*z*psitilde_cs_00_1 - 0.5625*psitilde_cs_00_0;
-      const double psitilde_cs_01_0 = 1;
-      const double psitilde_cs_01_1 = 3*z + 2;
-      const double psitilde_cs_02_0 = 1;
-      const double psitilde_cs_10_0 = 1;
-      const double psitilde_cs_10_1 = 3*z + 2;
-      const double psitilde_cs_11_0 = 1;
-      const double psitilde_cs_20_0 = 1;
-    
-      // Compute basisvalues
-      const double basisvalue0 = 0.866025403784439*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
-      const double basisvalue1 = 2.73861278752583*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
-      const double basisvalue2 = 1.58113883008419*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
-      const double basisvalue3 = 1.11803398874989*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
-      const double basisvalue4 = 5.1234753829798*psitilde_a_2*scalings_y_2*psitilde_bs_2_0*scalings_z_2*psitilde_cs_20_0;
-      const double basisvalue5 = 3.96862696659689*psitilde_a_1*scalings_y_1*psitilde_bs_1_1*scalings_z_2*psitilde_cs_11_0;
-      const double basisvalue6 = 2.29128784747792*psitilde_a_0*scalings_y_0*psitilde_bs_0_2*scalings_z_2*psitilde_cs_02_0;
-      const double basisvalue7 = 3.24037034920393*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_1;
-      const double basisvalue8 = 1.87082869338697*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_1;
-      const double basisvalue9 = 1.3228756555323*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_2;
-    
-      // Table(s) of coefficients
-      static const double coefficients0[10][10] =   \
-      {{-0.0577350269189626, -0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, 0.0503952630678969, 0.0290957186981323, 0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
-      {-0.0577350269189625, 0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, -0.050395263067897, 0.0290957186981323, -0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
-      {-0.0577350269189625, 0, 0.0702728368926306, -0.0248451997499977, 0, 0, 0.0872871560943969, 0, -0.0475131096733199, 0.0167984210226323},
-      {-0.0577350269189626, 0, 0, 0.074535599249993, 0, 0, 0, 0, 0, 0.100790526135794},
-      {0.23094010767585, 0, 0.140545673785261, 0.0993807989999906, 0, 0, 0, 0, 0.1187827741833, -0.0671936840905293},
-      {0.230940107675851, 0.121716123890037, -0.0702728368926306, 0.0993807989999907, 0, 0, 0, 0.102868899974728, -0.0593913870916499, -0.0671936840905293},
-      {0.23094010767585, 0.121716123890037, 0.0702728368926307, -0.0993807989999907, 0, 0.100790526135794, -0.087287156094397, -0.0205737799949456, -0.01187827741833, 0.0167984210226323},
-      {0.23094010767585, -0.121716123890037, -0.0702728368926307, 0.0993807989999906, 0, 0, 0, -0.102868899974728, -0.0593913870916499, -0.0671936840905293},
-      {0.23094010767585, -0.121716123890037, 0.0702728368926306, -0.0993807989999906, 0, -0.100790526135794, -0.0872871560943969, 0.0205737799949456, -0.01187827741833, 0.0167984210226323},
-      {0.23094010767585, 0, -0.140545673785261, -0.0993807989999906, -0.130120009726471, 0, 0.0290957186981323, 0, 0.02375655483666, 0.0167984210226323}};
-    
-      // 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];
-      const double coeff0_6 =   coefficients0[dof][6];
-      const double coeff0_7 =   coefficients0[dof][7];
-      const double coeff0_8 =   coefficients0[dof][8];
-      const double coeff0_9 =   coefficients0[dof][9];
-    
-      // Compute value(s)
-      values[0] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5 + coeff0_6*basisvalue6 + coeff0_7*basisvalue7 + coeff0_8*basisvalue8 + coeff0_9*basisvalue9;
-    }
-    
-    if (10 <= i && i <= 19)
-    {
-      // Map degree of freedom to element degree of freedom
-      const unsigned int dof = i - 10;
-    
-      // 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);
-      const double scalings_z_0 = 1;
-      const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
-      const double scalings_z_2 = scalings_z_1*(0.5 - 0.5*z);
-    
-      // 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 psitilde_cs
-      const double psitilde_cs_00_0 = 1;
-      const double psitilde_cs_00_1 = 2*z + 1;
-      const double psitilde_cs_00_2 = 0.3125*psitilde_cs_00_1 + 1.875*z*psitilde_cs_00_1 - 0.5625*psitilde_cs_00_0;
-      const double psitilde_cs_01_0 = 1;
-      const double psitilde_cs_01_1 = 3*z + 2;
-      const double psitilde_cs_02_0 = 1;
-      const double psitilde_cs_10_0 = 1;
-      const double psitilde_cs_10_1 = 3*z + 2;
-      const double psitilde_cs_11_0 = 1;
-      const double psitilde_cs_20_0 = 1;
-    
-      // Compute basisvalues
-      const double basisvalue0 = 0.866025403784439*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
-      const double basisvalue1 = 2.73861278752583*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
-      const double basisvalue2 = 1.58113883008419*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
-      const double basisvalue3 = 1.11803398874989*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
-      const double basisvalue4 = 5.1234753829798*psitilde_a_2*scalings_y_2*psitilde_bs_2_0*scalings_z_2*psitilde_cs_20_0;
-      const double basisvalue5 = 3.96862696659689*psitilde_a_1*scalings_y_1*psitilde_bs_1_1*scalings_z_2*psitilde_cs_11_0;
-      const double basisvalue6 = 2.29128784747792*psitilde_a_0*scalings_y_0*psitilde_bs_0_2*scalings_z_2*psitilde_cs_02_0;
-      const double basisvalue7 = 3.24037034920393*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_1;
-      const double basisvalue8 = 1.87082869338697*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_1;
-      const double basisvalue9 = 1.3228756555323*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_2;
-    
-      // Table(s) of coefficients
-      static const double coefficients0[10][10] =   \
-      {{-0.0577350269189626, -0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, 0.0503952630678969, 0.0290957186981323, 0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
-      {-0.0577350269189625, 0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, -0.050395263067897, 0.0290957186981323, -0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
-      {-0.0577350269189625, 0, 0.0702728368926306, -0.0248451997499977, 0, 0, 0.0872871560943969, 0, -0.0475131096733199, 0.0167984210226323},
-      {-0.0577350269189626, 0, 0, 0.074535599249993, 0, 0, 0, 0, 0, 0.100790526135794},
-      {0.23094010767585, 0, 0.140545673785261, 0.0993807989999906, 0, 0, 0, 0, 0.1187827741833, -0.0671936840905293},
-      {0.230940107675851, 0.121716123890037, -0.0702728368926306, 0.0993807989999907, 0, 0, 0, 0.102868899974728, -0.0593913870916499, -0.0671936840905293},
-      {0.23094010767585, 0.121716123890037, 0.0702728368926307, -0.0993807989999907, 0, 0.100790526135794, -0.087287156094397, -0.0205737799949456, -0.01187827741833, 0.0167984210226323},
-      {0.23094010767585, -0.121716123890037, -0.0702728368926307, 0.0993807989999906, 0, 0, 0, -0.102868899974728, -0.0593913870916499, -0.0671936840905293},
-      {0.23094010767585, -0.121716123890037, 0.0702728368926306, -0.0993807989999906, 0, -0.100790526135794, -0.0872871560943969, 0.0205737799949456, -0.01187827741833, 0.0167984210226323},
-      {0.23094010767585, 0, -0.140545673785261, -0.0993807989999906, -0.130120009726471, 0, 0.0290957186981323, 0, 0.02375655483666, 0.0167984210226323}};
-    
-      // 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];
-      const double coeff0_6 =   coefficients0[dof][6];
-      const double coeff0_7 =   coefficients0[dof][7];
-      const double coeff0_8 =   coefficients0[dof][8];
-      const double coeff0_9 =   coefficients0[dof][9];
-    
-      // Compute value(s)
-      values[1] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5 + coeff0_6*basisvalue6 + coeff0_7*basisvalue7 + coeff0_8*basisvalue8 + coeff0_9*basisvalue9;
-    }
-    
-}
-
-/// Evaluate all basis functions at given point in cell
-void solitarywave3d_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 solitarywave3d_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_02 = element_coordinates[3][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];
-    const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
-    const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
-    const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
-    const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
-    
-    // Compute sub determinants
-    const double d00 = J_11*J_22 - J_12*J_21;
-    const double d01 = J_12*J_20 - J_10*J_22;
-    const double d02 = J_10*J_21 - J_11*J_20;
-    
-    const double d10 = J_02*J_21 - J_01*J_22;
-    const double d11 = J_00*J_22 - J_02*J_20;
-    const double d12 = J_01*J_20 - J_00*J_21;
-    
-    const double d20 = J_01*J_12 - J_02*J_11;
-    const double d21 = J_02*J_10 - J_00*J_12;
-    const double d22 = J_00*J_11 - J_01*J_10;
-    
-    // Compute determinant of Jacobian
-    double detJ = J_00*d00 + J_10*d10 + J_20*d20;
-    
-    // Compute inverse of Jacobian
-    
-    // Compute constants
-    const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
-                    + d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
-                    + d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
-    
-    const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
-                    + d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
-                    + d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
-    
-    const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
-                    + d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
-                    + d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
-    
-    // Get coordinates and map to the UFC reference element
-    double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
-    double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
-    double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
-    
-    // Map coordinates to the reference cube
-    if (std::abs(y + z - 1.0) < 1e-14)
-      x = 1.0;
-    else
-      x = -2.0 * x/(y + z - 1.0) - 1.0;
-    if (std::abs(z - 1.0) < 1e-14)
-      y = -1.0;
-    else
-      y = 2.0 * y/(1.0 - z) - 1.0;
-    z = 2.0 * z - 1.0;
-    
-    // Compute number of derivatives
-    unsigned int num_derivatives = 1;
-    
-    for (unsigned int j = 0; j < n; j++)
-      num_derivatives *= 3;
-    
-    
-    // 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 > 2)
-            combinations[row][col] = 0;
-          else
-          {
-            combinations[row][col] += 1;
-            break;
-          }
-        }
-      }
-    }
-    
-    // Compute inverse of Jacobian
-    const double Jinv[3][3] ={{d00 / detJ, d10 / detJ, d20 / detJ}, {d01 / detJ, d11 / detJ, d21 / detJ}, {d02 / detJ, d12 / detJ, d22 / 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 <= 9)
-    {
-      // 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);
-      const double scalings_z_0 = 1;
-      const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
-      const double scalings_z_2 = scalings_z_1*(0.5 - 0.5*z);
-    
-      // 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 psitilde_cs
-      const double psitilde_cs_00_0 = 1;
-      const double psitilde_cs_00_1 = 2*z + 1;
-      const double psitilde_cs_00_2 = 0.3125*psitilde_cs_00_1 + 1.875*z*psitilde_cs_00_1 - 0.5625*psitilde_cs_00_0;
-      const double psitilde_cs_01_0 = 1;
-      const double psitilde_cs_01_1 = 3*z + 2;
-      const double psitilde_cs_02_0 = 1;
-      const double psitilde_cs_10_0 = 1;
-      const double psitilde_cs_10_1 = 3*z + 2;
-      const double psitilde_cs_11_0 = 1;
-      const double psitilde_cs_20_0 = 1;
-    
-      // Compute basisvalues
-      const double basisvalue0 = 0.866025403784439*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
-      const double basisvalue1 = 2.73861278752583*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
-      const double basisvalue2 = 1.58113883008419*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
-      const double basisvalue3 = 1.11803398874989*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
-      const double basisvalue4 = 5.1234753829798*psitilde_a_2*scalings_y_2*psitilde_bs_2_0*scalings_z_2*psitilde_cs_20_0;
-      const double basisvalue5 = 3.96862696659689*psitilde_a_1*scalings_y_1*psitilde_bs_1_1*scalings_z_2*psitilde_cs_11_0;
-      const double basisvalue6 = 2.29128784747792*psitilde_a_0*scalings_y_0*psitilde_bs_0_2*scalings_z_2*psitilde_cs_02_0;
-      const double basisvalue7 = 3.24037034920393*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_1;
-      const double basisvalue8 = 1.87082869338697*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_1;
-      const double basisvalue9 = 1.3228756555323*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_2;
-    
-      // Table(s) of coefficients
-      static const double coefficients0[10][10] =   \
-      {{-0.0577350269189626, -0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, 0.0503952630678969, 0.0290957186981323, 0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
-      {-0.0577350269189625, 0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, -0.050395263067897, 0.0290957186981323, -0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
-      {-0.0577350269189625, 0, 0.0702728368926306, -0.0248451997499977, 0, 0, 0.0872871560943969, 0, -0.0475131096733199, 0.0167984210226323},
-      {-0.0577350269189626, 0, 0, 0.074535599249993, 0, 0, 0, 0, 0, 0.100790526135794},
-      {0.23094010767585, 0, 0.140545673785261, 0.0993807989999906, 0, 0, 0, 0, 0.1187827741833, -0.0671936840905293},
-      {0.230940107675851, 0.121716123890037, -0.0702728368926306, 0.0993807989999907, 0, 0, 0, 0.102868899974728, -0.0593913870916499, -0.0671936840905293},
-      {0.23094010767585, 0.121716123890037, 0.0702728368926307, -0.0993807989999907, 0, 0.100790526135794, -0.087287156094397, -0.0205737799949456, -0.01187827741833, 0.0167984210226323},
-      {0.23094010767585, -0.121716123890037, -0.0702728368926307, 0.0993807989999906, 0, 0, 0, -0.102868899974728, -0.0593913870916499, -0.0671936840905293},
-      {0.23094010767585, -0.121716123890037, 0.0702728368926306, -0.0993807989999906, 0, -0.100790526135794, -0.0872871560943969, 0.0205737799949456, -0.01187827741833, 0.0167984210226323},
-      {0.23094010767585, 0, -0.140545673785261, -0.0993807989999906, -0.130120009726471, 0, 0.0290957186981323, 0, 0.02375655483666, 0.0167984210226323}};
-    
-      // Interesting (new) part
-      // Tables of derivatives of the polynomial base (transpose)
-      static const double dmats0[10][10] =   \
-      {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-      {6.32455532033676, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-      {0, 11.2249721603218, 0, 0, 0, 0, 0, 0, 0, 0},
-      {4.58257569495584, 0, 8.36660026534076, -1.18321595661992, 0, 0, 0, 0, 0, 0},
-      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-      {3.74165738677394, 0, 0, 8.69482604771366, 0, 0, 0, 0, 0, 0},
-      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
-    
-      static const double dmats1[10][10] =   \
-      {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-      {3.16227766016838, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-      {5.47722557505166, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-      {2.95803989154981, 5.61248608016091, -1.08012344973464, -0.763762615825974, 0, 0, 0, 0, 0, 0},
-      {2.29128784747792, 7.24568837309472, 4.18330013267038, -0.591607978309962, 0, 0, 0, 0, 0, 0},
-      {-2.64575131106459, 0, 9.66091783079296, 0.683130051063974, 0, 0, 0, 0, 0, 0},
-      {1.87082869338697, 0, 0, 4.34741302385683, 0, 0, 0, 0, 0, 0},
-      {3.24037034920393, 0, 0, 7.52994023880668, 0, 0, 0, 0, 0, 0},
-      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
-    
-      static const double dmats2[10][10] =   \
-      {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-      {3.16227766016838, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-      {1.82574185835055, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-      {5.16397779494322, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-      {2.95803989154981, 5.61248608016091, -1.08012344973464, -0.763762615825974, 0, 0, 0, 0, 0, 0},
-      {2.29128784747792, 1.44913767461894, 4.18330013267038, -0.591607978309962, 0, 0, 0, 0, 0, 0},
-      {1.32287565553229, 0, 3.86436713231718, -0.341565025531986, 0, 0, 0, 0, 0, 0},
-      {1.87082869338697, 7.09929573971954, 0, 4.34741302385683, 0, 0, 0, 0, 0, 0},
-      {1.08012344973464, 0, 7.09929573971954, 2.50998007960223, 0, 0, 0, 0, 0, 0},
-      {-3.81881307912987, 0, 0, 8.87411967464942, 0, 0, 0, 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;
-      double coeff0_6 = 0;
-      double coeff0_7 = 0;
-      double coeff0_8 = 0;
-      double coeff0_9 = 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;
-      double new_coeff0_6 = 0;
-      double new_coeff0_7 = 0;
-      double new_coeff0_8 = 0;
-      double new_coeff0_9 = 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];
-        new_coeff0_6 = coefficients0[dof][6];
-        new_coeff0_7 = coefficients0[dof][7];
-        new_coeff0_8 = coefficients0[dof][8];
-        new_coeff0_9 = coefficients0[dof][9];
-    
-        // 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;
-          coeff0_6 = new_coeff0_6;
-          coeff0_7 = new_coeff0_7;
-          coeff0_8 = new_coeff0_8;
-          coeff0_9 = new_coeff0_9;
-    
-          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] + coeff0_6*dmats0[6][0] + coeff0_7*dmats0[7][0] + coeff0_8*dmats0[8][0] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][1] + coeff0_7*dmats0[7][1] + coeff0_8*dmats0[8][1] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][2] + coeff0_7*dmats0[7][2] + coeff0_8*dmats0[8][2] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][3] + coeff0_7*dmats0[7][3] + coeff0_8*dmats0[8][3] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][4] + coeff0_7*dmats0[7][4] + coeff0_8*dmats0[8][4] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][5] + coeff0_7*dmats0[7][5] + coeff0_8*dmats0[8][5] + coeff0_9*dmats0[9][5];
-            new_coeff0_6 = coeff0_0*dmats0[0][6] + coeff0_1*dmats0[1][6] + coeff0_2*dmats0[2][6] + coeff0_3*dmats0[3][6] + coeff0_4*dmats0[4][6] + coeff0_5*dmats0[5][6] + coeff0_6*dmats0[6][6] + coeff0_7*dmats0[7][6] + coeff0_8*dmats0[8][6] + coeff0_9*dmats0[9][6];
-            new_coeff0_7 = coeff0_0*dmats0[0][7] + coeff0_1*dmats0[1][7] + coeff0_2*dmats0[2][7] + coeff0_3*dmats0[3][7] + coeff0_4*dmats0[4][7] + coeff0_5*dmats0[5][7] + coeff0_6*dmats0[6][7] + coeff0_7*dmats0[7][7] + coeff0_8*dmats0[8][7] + coeff0_9*dmats0[9][7];
-            new_coeff0_8 = coeff0_0*dmats0[0][8] + coeff0_1*dmats0[1][8] + coeff0_2*dmats0[2][8] + coeff0_3*dmats0[3][8] + coeff0_4*dmats0[4][8] + coeff0_5*dmats0[5][8] + coeff0_6*dmats0[6][8] + coeff0_7*dmats0[7][8] + coeff0_8*dmats0[8][8] + coeff0_9*dmats0[9][8];
-            new_coeff0_9 = coeff0_0*dmats0[0][9] + coeff0_1*dmats0[1][9] + coeff0_2*dmats0[2][9] + coeff0_3*dmats0[3][9] + coeff0_4*dmats0[4][9] + coeff0_5*dmats0[5][9] + coeff0_6*dmats0[6][9] + coeff0_7*dmats0[7][9] + coeff0_8*dmats0[8][9] + coeff0_9*dmats0[9][9];
-          }
-          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] + coeff0_6*dmats1[6][0] + coeff0_7*dmats1[7][0] + coeff0_8*dmats1[8][0] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][1] + coeff0_7*dmats1[7][1] + coeff0_8*dmats1[8][1] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][2] + coeff0_7*dmats1[7][2] + coeff0_8*dmats1[8][2] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][3] + coeff0_7*dmats1[7][3] + coeff0_8*dmats1[8][3] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][4] + coeff0_7*dmats1[7][4] + coeff0_8*dmats1[8][4] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][5] + coeff0_7*dmats1[7][5] + coeff0_8*dmats1[8][5] + coeff0_9*dmats1[9][5];
-            new_coeff0_6 = coeff0_0*dmats1[0][6] + coeff0_1*dmats1[1][6] + coeff0_2*dmats1[2][6] + coeff0_3*dmats1[3][6] + coeff0_4*dmats1[4][6] + coeff0_5*dmats1[5][6] + coeff0_6*dmats1[6][6] + coeff0_7*dmats1[7][6] + coeff0_8*dmats1[8][6] + coeff0_9*dmats1[9][6];
-            new_coeff0_7 = coeff0_0*dmats1[0][7] + coeff0_1*dmats1[1][7] + coeff0_2*dmats1[2][7] + coeff0_3*dmats1[3][7] + coeff0_4*dmats1[4][7] + coeff0_5*dmats1[5][7] + coeff0_6*dmats1[6][7] + coeff0_7*dmats1[7][7] + coeff0_8*dmats1[8][7] + coeff0_9*dmats1[9][7];
-            new_coeff0_8 = coeff0_0*dmats1[0][8] + coeff0_1*dmats1[1][8] + coeff0_2*dmats1[2][8] + coeff0_3*dmats1[3][8] + coeff0_4*dmats1[4][8] + coeff0_5*dmats1[5][8] + coeff0_6*dmats1[6][8] + coeff0_7*dmats1[7][8] + coeff0_8*dmats1[8][8] + coeff0_9*dmats1[9][8];
-            new_coeff0_9 = coeff0_0*dmats1[0][9] + coeff0_1*dmats1[1][9] + coeff0_2*dmats1[2][9] + coeff0_3*dmats1[3][9] + coeff0_4*dmats1[4][9] + coeff0_5*dmats1[5][9] + coeff0_6*dmats1[6][9] + coeff0_7*dmats1[7][9] + coeff0_8*dmats1[8][9] + coeff0_9*dmats1[9][9];
-          }
-          if(combinations[deriv_num][j] == 2)
-          {
-            new_coeff0_0 = coeff0_0*dmats2[0][0] + coeff0_1*dmats2[1][0] + coeff0_2*dmats2[2][0] + coeff0_3*dmats2[3][0] + coeff0_4*dmats2[4][0] + coeff0_5*dmats2[5][0] + coeff0_6*dmats2[6][0] + coeff0_7*dmats2[7][0] + coeff0_8*dmats2[8][0] + coeff0_9*dmats2[9][0];
-            new_coeff0_1 = coeff0_0*dmats2[0][1] + coeff0_1*dmats2[1][1] + coeff0_2*dmats2[2][1] + coeff0_3*dmats2[3][1] + coeff0_4*dmats2[4][1] + coeff0_5*dmats2[5][1] + coeff0_6*dmats2[6][1] + coeff0_7*dmats2[7][1] + coeff0_8*dmats2[8][1] + coeff0_9*dmats2[9][1];
-            new_coeff0_2 = coeff0_0*dmats2[0][2] + coeff0_1*dmats2[1][2] + coeff0_2*dmats2[2][2] + coeff0_3*dmats2[3][2] + coeff0_4*dmats2[4][2] + coeff0_5*dmats2[5][2] + coeff0_6*dmats2[6][2] + coeff0_7*dmats2[7][2] + coeff0_8*dmats2[8][2] + coeff0_9*dmats2[9][2];
-            new_coeff0_3 = coeff0_0*dmats2[0][3] + coeff0_1*dmats2[1][3] + coeff0_2*dmats2[2][3] + coeff0_3*dmats2[3][3] + coeff0_4*dmats2[4][3] + coeff0_5*dmats2[5][3] + coeff0_6*dmats2[6][3] + coeff0_7*dmats2[7][3] + coeff0_8*dmats2[8][3] + coeff0_9*dmats2[9][3];
-            new_coeff0_4 = coeff0_0*dmats2[0][4] + coeff0_1*dmats2[1][4] + coeff0_2*dmats2[2][4] + coeff0_3*dmats2[3][4] + coeff0_4*dmats2[4][4] + coeff0_5*dmats2[5][4] + coeff0_6*dmats2[6][4] + coeff0_7*dmats2[7][4] + coeff0_8*dmats2[8][4] + coeff0_9*dmats2[9][4];
-            new_coeff0_5 = coeff0_0*dmats2[0][5] + coeff0_1*dmats2[1][5] + coeff0_2*dmats2[2][5] + coeff0_3*dmats2[3][5] + coeff0_4*dmats2[4][5] + coeff0_5*dmats2[5][5] + coeff0_6*dmats2[6][5] + coeff0_7*dmats2[7][5] + coeff0_8*dmats2[8][5] + coeff0_9*dmats2[9][5];
-            new_coeff0_6 = coeff0_0*dmats2[0][6] + coeff0_1*dmats2[1][6] + coeff0_2*dmats2[2][6] + coeff0_3*dmats2[3][6] + coeff0_4*dmats2[4][6] + coeff0_5*dmats2[5][6] + coeff0_6*dmats2[6][6] + coeff0_7*dmats2[7][6] + coeff0_8*dmats2[8][6] + coeff0_9*dmats2[9][6];
-            new_coeff0_7 = coeff0_0*dmats2[0][7] + coeff0_1*dmats2[1][7] + coeff0_2*dmats2[2][7] + coeff0_3*dmats2[3][7] + coeff0_4*dmats2[4][7] + coeff0_5*dmats2[5][7] + coeff0_6*dmats2[6][7] + coeff0_7*dmats2[7][7] + coeff0_8*dmats2[8][7] + coeff0_9*dmats2[9][7];
-            new_coeff0_8 = coeff0_0*dmats2[0][8] + coeff0_1*dmats2[1][8] + coeff0_2*dmats2[2][8] + coeff0_3*dmats2[3][8] + coeff0_4*dmats2[4][8] + coeff0_5*dmats2[5][8] + coeff0_6*dmats2[6][8] + coeff0_7*dmats2[7][8] + coeff0_8*dmats2[8][8] + coeff0_9*dmats2[9][8];
-            new_coeff0_9 = coeff0_0*dmats2[0][9] + coeff0_1*dmats2[1][9] + coeff0_2*dmats2[2][9] + coeff0_3*dmats2[3][9] + coeff0_4*dmats2[4][9] + coeff0_5*dmats2[5][9] + coeff0_6*dmats2[6][9] + coeff0_7*dmats2[7][9] + coeff0_8*dmats2[8][9] + coeff0_9*dmats2[9][9];
-          }
-    
-        }
-        // 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 + new_coeff0_6*basisvalue6 + new_coeff0_7*basisvalue7 + new_coeff0_8*basisvalue8 + new_coeff0_9*basisvalue9;
-      }
-    
-      // 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 (10 <= i && i <= 19)
-    {
-      // Map degree of freedom to element degree of freedom
-      const unsigned int dof = i - 10;
-    
-      // 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);
-      const double scalings_z_0 = 1;
-      const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
-      const double scalings_z_2 = scalings_z_1*(0.5 - 0.5*z);
-    
-      // 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 psitilde_cs
-      const double psitilde_cs_00_0 = 1;
-      const double psitilde_cs_00_1 = 2*z + 1;
-      const double psitilde_cs_00_2 = 0.3125*psitilde_cs_00_1 + 1.875*z*psitilde_cs_00_1 - 0.5625*psitilde_cs_00_0;
-      const double psitilde_cs_01_0 = 1;
-      const double psitilde_cs_01_1 = 3*z + 2;
-      const double psitilde_cs_02_0 = 1;
-      const double psitilde_cs_10_0 = 1;
-      const double psitilde_cs_10_1 = 3*z + 2;
-      const double psitilde_cs_11_0 = 1;
-      const double psitilde_cs_20_0 = 1;
-    
-      // Compute basisvalues
-      const double basisvalue0 = 0.866025403784439*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
-      const double basisvalue1 = 2.73861278752583*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
-      const double basisvalue2 = 1.58113883008419*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
-      const double basisvalue3 = 1.11803398874989*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
-      const double basisvalue4 = 5.1234753829798*psitilde_a_2*scalings_y_2*psitilde_bs_2_0*scalings_z_2*psitilde_cs_20_0;
-      const double basisvalue5 = 3.96862696659689*psitilde_a_1*scalings_y_1*psitilde_bs_1_1*scalings_z_2*psitilde_cs_11_0;
-      const double basisvalue6 = 2.29128784747792*psitilde_a_0*scalings_y_0*psitilde_bs_0_2*scalings_z_2*psitilde_cs_02_0;
-      const double basisvalue7 = 3.24037034920393*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_1;
-      const double basisvalue8 = 1.87082869338697*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_1;
-      const double basisvalue9 = 1.3228756555323*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_2;
-    
-      // Table(s) of coefficients
-      static const double coefficients0[10][10] =   \
-      {{-0.0577350269189626, -0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, 0.0503952630678969, 0.0290957186981323, 0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
-      {-0.0577350269189625, 0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, -0.050395263067897, 0.0290957186981323, -0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
-      {-0.0577350269189625, 0, 0.0702728368926306, -0.0248451997499977, 0, 0, 0.0872871560943969, 0, -0.0475131096733199, 0.0167984210226323},
-      {-0.0577350269189626, 0, 0, 0.074535599249993, 0, 0, 0, 0, 0, 0.100790526135794},
-      {0.23094010767585, 0, 0.140545673785261, 0.0993807989999906, 0, 0, 0, 0, 0.1187827741833, -0.0671936840905293},
-      {0.230940107675851, 0.121716123890037, -0.0702728368926306, 0.0993807989999907, 0, 0, 0, 0.102868899974728, -0.0593913870916499, -0.0671936840905293},
-      {0.23094010767585, 0.121716123890037, 0.0702728368926307, -0.0993807989999907, 0, 0.100790526135794, -0.087287156094397, -0.0205737799949456, -0.01187827741833, 0.0167984210226323},
-      {0.23094010767585, -0.121716123890037, -0.0702728368926307, 0.0993807989999906, 0, 0, 0, -0.102868899974728, -0.0593913870916499, -0.0671936840905293},
-      {0.23094010767585, -0.121716123890037, 0.0702728368926306, -0.0993807989999906, 0, -0.100790526135794, -0.0872871560943969, 0.0205737799949456, -0.01187827741833, 0.0167984210226323},
-      {0.23094010767585, 0, -0.140545673785261, -0.0993807989999906, -0.130120009726471, 0, 0.0290957186981323, 0, 0.02375655483666, 0.0167984210226323}};
-    
-      // Interesting (new) part
-      // Tables of derivatives of the polynomial base (transpose)
-      static const double dmats0[10][10] =   \
-      {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-      {6.32455532033676, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-      {0, 11.2249721603218, 0, 0, 0, 0, 0, 0, 0, 0},
-      {4.58257569495584, 0, 8.36660026534076, -1.18321595661992, 0, 0, 0, 0, 0, 0},
-      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-      {3.74165738677394, 0, 0, 8.69482604771366, 0, 0, 0, 0, 0, 0},
-      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
-    
-      static const double dmats1[10][10] =   \
-      {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-      {3.16227766016838, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-      {5.47722557505166, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-      {2.95803989154981, 5.61248608016091, -1.08012344973464, -0.763762615825974, 0, 0, 0, 0, 0, 0},
-      {2.29128784747792, 7.24568837309472, 4.18330013267038, -0.591607978309962, 0, 0, 0, 0, 0, 0},
-      {-2.64575131106459, 0, 9.66091783079296, 0.683130051063974, 0, 0, 0, 0, 0, 0},
-      {1.87082869338697, 0, 0, 4.34741302385683, 0, 0, 0, 0, 0, 0},
-      {3.24037034920393, 0, 0, 7.52994023880668, 0, 0, 0, 0, 0, 0},
-      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
-    
-      static const double dmats2[10][10] =   \
-      {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-      {3.16227766016838, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-      {1.82574185835055, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-      {5.16397779494322, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-      {2.95803989154981, 5.61248608016091, -1.08012344973464, -0.763762615825974, 0, 0, 0, 0, 0, 0},
-      {2.29128784747792, 1.44913767461894, 4.18330013267038, -0.591607978309962, 0, 0, 0, 0, 0, 0},
-      {1.32287565553229, 0, 3.86436713231718, -0.341565025531986, 0, 0, 0, 0, 0, 0},
-      {1.87082869338697, 7.09929573971954, 0, 4.34741302385683, 0, 0, 0, 0, 0, 0},
-      {1.08012344973464, 0, 7.09929573971954, 2.50998007960223, 0, 0, 0, 0, 0, 0},
-      {-3.81881307912987, 0, 0, 8.87411967464942, 0, 0, 0, 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;
-      double coeff0_6 = 0;
-      double coeff0_7 = 0;
-      double coeff0_8 = 0;
-      double coeff0_9 = 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;
-      double new_coeff0_6 = 0;
-      double new_coeff0_7 = 0;
-      double new_coeff0_8 = 0;
-      double new_coeff0_9 = 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];
-        new_coeff0_6 = coefficients0[dof][6];
-        new_coeff0_7 = coefficients0[dof][7];
-        new_coeff0_8 = coefficients0[dof][8];
-        new_coeff0_9 = coefficients0[dof][9];
-    
-        // 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;
-          coeff0_6 = new_coeff0_6;
-          coeff0_7 = new_coeff0_7;
-          coeff0_8 = new_coeff0_8;
-          coeff0_9 = new_coeff0_9;
-    
-          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] + coeff0_6*dmats0[6][0] + coeff0_7*dmats0[7][0] + coeff0_8*dmats0[8][0] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][1] + coeff0_7*dmats0[7][1] + coeff0_8*dmats0[8][1] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][2] + coeff0_7*dmats0[7][2] + coeff0_8*dmats0[8][2] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][3] + coeff0_7*dmats0[7][3] + coeff0_8*dmats0[8][3] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][4] + coeff0_7*dmats0[7][4] + coeff0_8*dmats0[8][4] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][5] + coeff0_7*dmats0[7][5] + coeff0_8*dmats0[8][5] + coeff0_9*dmats0[9][5];
-            new_coeff0_6 = coeff0_0*dmats0[0][6] + coeff0_1*dmats0[1][6] + coeff0_2*dmats0[2][6] + coeff0_3*dmats0[3][6] + coeff0_4*dmats0[4][6] + coeff0_5*dmats0[5][6] + coeff0_6*dmats0[6][6] + coeff0_7*dmats0[7][6] + coeff0_8*dmats0[8][6] + coeff0_9*dmats0[9][6];
-            new_coeff0_7 = coeff0_0*dmats0[0][7] + coeff0_1*dmats0[1][7] + coeff0_2*dmats0[2][7] + coeff0_3*dmats0[3][7] + coeff0_4*dmats0[4][7] + coeff0_5*dmats0[5][7] + coeff0_6*dmats0[6][7] + coeff0_7*dmats0[7][7] + coeff0_8*dmats0[8][7] + coeff0_9*dmats0[9][7];
-            new_coeff0_8 = coeff0_0*dmats0[0][8] + coeff0_1*dmats0[1][8] + coeff0_2*dmats0[2][8] + coeff0_3*dmats0[3][8] + coeff0_4*dmats0[4][8] + coeff0_5*dmats0[5][8] + coeff0_6*dmats0[6][8] + coeff0_7*dmats0[7][8] + coeff0_8*dmats0[8][8] + coeff0_9*dmats0[9][8];
-            new_coeff0_9 = coeff0_0*dmats0[0][9] + coeff0_1*dmats0[1][9] + coeff0_2*dmats0[2][9] + coeff0_3*dmats0[3][9] + coeff0_4*dmats0[4][9] + coeff0_5*dmats0[5][9] + coeff0_6*dmats0[6][9] + coeff0_7*dmats0[7][9] + coeff0_8*dmats0[8][9] + coeff0_9*dmats0[9][9];
-          }
-          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] + coeff0_6*dmats1[6][0] + coeff0_7*dmats1[7][0] + coeff0_8*dmats1[8][0] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][1] + coeff0_7*dmats1[7][1] + coeff0_8*dmats1[8][1] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][2] + coeff0_7*dmats1[7][2] + coeff0_8*dmats1[8][2] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][3] + coeff0_7*dmats1[7][3] + coeff0_8*dmats1[8][3] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][4] + coeff0_7*dmats1[7][4] + coeff0_8*dmats1[8][4] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][5] + coeff0_7*dmats1[7][5] + coeff0_8*dmats1[8][5] + coeff0_9*dmats1[9][5];
-            new_coeff0_6 = coeff0_0*dmats1[0][6] + coeff0_1*dmats1[1][6] + coeff0_2*dmats1[2][6] + coeff0_3*dmats1[3][6] + coeff0_4*dmats1[4][6] + coeff0_5*dmats1[5][6] + coeff0_6*dmats1[6][6] + coeff0_7*dmats1[7][6] + coeff0_8*dmats1[8][6] + coeff0_9*dmats1[9][6];
-            new_coeff0_7 = coeff0_0*dmats1[0][7] + coeff0_1*dmats1[1][7] + coeff0_2*dmats1[2][7] + coeff0_3*dmats1[3][7] + coeff0_4*dmats1[4][7] + coeff0_5*dmats1[5][7] + coeff0_6*dmats1[6][7] + coeff0_7*dmats1[7][7] + coeff0_8*dmats1[8][7] + coeff0_9*dmats1[9][7];
-            new_coeff0_8 = coeff0_0*dmats1[0][8] + coeff0_1*dmats1[1][8] + coeff0_2*dmats1[2][8] + coeff0_3*dmats1[3][8] + coeff0_4*dmats1[4][8] + coeff0_5*dmats1[5][8] + coeff0_6*dmats1[6][8] + coeff0_7*dmats1[7][8] + coeff0_8*dmats1[8][8] + coeff0_9*dmats1[9][8];
-            new_coeff0_9 = coeff0_0*dmats1[0][9] + coeff0_1*dmats1[1][9] + coeff0_2*dmats1[2][9] + coeff0_3*dmats1[3][9] + coeff0_4*dmats1[4][9] + coeff0_5*dmats1[5][9] + coeff0_6*dmats1[6][9] + coeff0_7*dmats1[7][9] + coeff0_8*dmats1[8][9] + coeff0_9*dmats1[9][9];
-          }
-          if(combinations[deriv_num][j] == 2)
-          {
-            new_coeff0_0 = coeff0_0*dmats2[0][0] + coeff0_1*dmats2[1][0] + coeff0_2*dmats2[2][0] + coeff0_3*dmats2[3][0] + coeff0_4*dmats2[4][0] + coeff0_5*dmats2[5][0] + coeff0_6*dmats2[6][0] + coeff0_7*dmats2[7][0] + coeff0_8*dmats2[8][0] + coeff0_9*dmats2[9][0];
-            new_coeff0_1 = coeff0_0*dmats2[0][1] + coeff0_1*dmats2[1][1] + coeff0_2*dmats2[2][1] + coeff0_3*dmats2[3][1] + coeff0_4*dmats2[4][1] + coeff0_5*dmats2[5][1] + coeff0_6*dmats2[6][1] + coeff0_7*dmats2[7][1] + coeff0_8*dmats2[8][1] + coeff0_9*dmats2[9][1];
-            new_coeff0_2 = coeff0_0*dmats2[0][2] + coeff0_1*dmats2[1][2] + coeff0_2*dmats2[2][2] + coeff0_3*dmats2[3][2] + coeff0_4*dmats2[4][2] + coeff0_5*dmats2[5][2] + coeff0_6*dmats2[6][2] + coeff0_7*dmats2[7][2] + coeff0_8*dmats2[8][2] + coeff0_9*dmats2[9][2];
-            new_coeff0_3 = coeff0_0*dmats2[0][3] + coeff0_1*dmats2[1][3] + coeff0_2*dmats2[2][3] + coeff0_3*dmats2[3][3] + coeff0_4*dmats2[4][3] + coeff0_5*dmats2[5][3] + coeff0_6*dmats2[6][3] + coeff0_7*dmats2[7][3] + coeff0_8*dmats2[8][3] + coeff0_9*dmats2[9][3];
-            new_coeff0_4 = coeff0_0*dmats2[0][4] + coeff0_1*dmats2[1][4] + coeff0_2*dmats2[2][4] + coeff0_3*dmats2[3][4] + coeff0_4*dmats2[4][4] + coeff0_5*dmats2[5][4] + coeff0_6*dmats2[6][4] + coeff0_7*dmats2[7][4] + coeff0_8*dmats2[8][4] + coeff0_9*dmats2[9][4];
-            new_coeff0_5 = coeff0_0*dmats2[0][5] + coeff0_1*dmats2[1][5] + coeff0_2*dmats2[2][5] + coeff0_3*dmats2[3][5] + coeff0_4*dmats2[4][5] + coeff0_5*dmats2[5][5] + coeff0_6*dmats2[6][5] + coeff0_7*dmats2[7][5] + coeff0_8*dmats2[8][5] + coeff0_9*dmats2[9][5];
-            new_coeff0_6 = coeff0_0*dmats2[0][6] + coeff0_1*dmats2[1][6] + coeff0_2*dmats2[2][6] + coeff0_3*dmats2[3][6] + coeff0_4*dmats2[4][6] + coeff0_5*dmats2[5][6] + coeff0_6*dmats2[6][6] + coeff0_7*dmats2[7][6] + coeff0_8*dmats2[8][6] + coeff0_9*dmats2[9][6];
-            new_coeff0_7 = coeff0_0*dmats2[0][7] + coeff0_1*dmats2[1][7] + coeff0_2*dmats2[2][7] + coeff0_3*dmats2[3][7] + coeff0_4*dmats2[4][7] + coeff0_5*dmats2[5][7] + coeff0_6*dmats2[6][7] + coeff0_7*dmats2[7][7] + coeff0_8*dmats2[8][7] + coeff0_9*dmats2[9][7];
-            new_coeff0_8 = coeff0_0*dmats2[0][8] + coeff0_1*dmats2[1][8] + coeff0_2*dmats2[2][8] + coeff0_3*dmats2[3][8] + coeff0_4*dmats2[4][8] + coeff0_5*dmats2[5][8] + coeff0_6*dmats2[6][8] + coeff0_7*dmats2[7][8] + coeff0_8*dmats2[8][8] + coeff0_9*dmats2[9][8];
-            new_coeff0_9 = coeff0_0*dmats2[0][9] + coeff0_1*dmats2[1][9] + coeff0_2*dmats2[2][9] + coeff0_3*dmats2[3][9] + coeff0_4*dmats2[4][9] + coeff0_5*dmats2[5][9] + coeff0_6*dmats2[6][9] + coeff0_7*dmats2[7][9] + coeff0_8*dmats2[8][9] + coeff0_9*dmats2[9][9];
-          }
-    
-        }
-        // 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 + new_coeff0_6*basisvalue6 + new_coeff0_7*basisvalue7 + new_coeff0_8*basisvalue8 + new_coeff0_9*basisvalue9;
-      }
-    
-      // 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 solitarywave3d_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 solitarywave3d_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[20][1][3] = {{{0, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 0, 1}}, {{0, 0.5, 0.5}}, {{0.5, 0, 0.5}}, {{0.5, 0.5, 0}}, {{0, 0, 0.5}}, {{0, 0.5, 0}}, {{0.5, 0, 0}}, {{0, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 0, 1}}, {{0, 0.5, 0.5}}, {{0.5, 0, 0.5}}, {{0.5, 0.5, 0}}, {{0, 0, 0.5}}, {{0, 0.5, 0}}, {{0.5, 0, 0}}};
-    static const double W[20][1] = {{1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}};
-    static const double D[20][1][2] = {{{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{0, 1}}, {{0, 1}}, {{0, 1}}, {{0, 1}}, {{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] - X[i][0][2];
-    const double w1 = X[i][0][0];
-    const double w2 = X[i][0][1];
-    const double w3 = X[i][0][2];
-    
-    // Compute affine mapping y = F(X)
-    double y[3];
-    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0] + w3*x[3][0];
-    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1] + w3*x[3][1];
-    y[2] = w0*x[0][2] + w1*x[1][2] + w2*x[2][2] + w3*x[3][2];
-    
-    // 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 solitarywave3d_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 solitarywave3d_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];
-    vertex_values[6] = dof_values[3];
-    // Evaluate at vertices and use affine mapping
-    vertex_values[1] = dof_values[10];
-    vertex_values[3] = dof_values[11];
-    vertex_values[5] = dof_values[12];
-    vertex_values[7] = dof_values[13];
-}
-
-/// Return the number of sub elements (for a mixed element)
-unsigned int solitarywave3d_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* solitarywave3d_1_finite_element_0::create_sub_element(unsigned int i) const
-{
-    switch ( i )
-    {
-    case 0:
-      return new solitarywave3d_1_finite_element_0_0();
-      break;
-    case 1:
-      return new solitarywave3d_1_finite_element_0_1();
-      break;
-    }
-    return 0;
-}
-
-
-/// Constructor
-solitarywave3d_1_finite_element_1_0::solitarywave3d_1_finite_element_1_0() : ufc::finite_element()
-{
-    // Do nothing
-}
-
-/// Destructor
-solitarywave3d_1_finite_element_1_0::~solitarywave3d_1_finite_element_1_0()
-{
-    // Do nothing
-}
-
-/// Return a string identifying the finite element
-const char* solitarywave3d_1_finite_element_1_0::signature() const
-{
-    return "FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)";
-}
-
-/// Return the cell shape
-ufc::shape solitarywave3d_1_finite_element_1_0::cell_shape() const
-{
-    return ufc::tetrahedron;
-}
-
-/// Return the dimension of the finite element function space
-unsigned int solitarywave3d_1_finite_element_1_0::space_dimension() const
-{
-    return 10;
-}
-
-/// Return the rank of the value space
-unsigned int solitarywave3d_1_finite_element_1_0::value_rank() const
-{
-    return 0;
-}
-
-/// Return the dimension of the value space for axis i
-unsigned int solitarywave3d_1_finite_element_1_0::value_dimension(unsigned int i) const
-{
-    return 1;
-}
-
-/// Evaluate basis function i at given point in cell
-void solitarywave3d_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_02 = element_coordinates[3][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];
-    const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
-    const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
-    const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
-    const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
-    
-    // Compute sub determinants
-    const double d00 = J_11*J_22 - J_12*J_21;
-    const double d01 = J_12*J_20 - J_10*J_22;
-    const double d02 = J_10*J_21 - J_11*J_20;
-    
-    const double d10 = J_02*J_21 - J_01*J_22;
-    const double d11 = J_00*J_22 - J_02*J_20;
-    const double d12 = J_01*J_20 - J_00*J_21;
-    
-    const double d20 = J_01*J_12 - J_02*J_11;
-    const double d21 = J_02*J_10 - J_00*J_12;
-    const double d22 = J_00*J_11 - J_01*J_10;
-    
-    // Compute determinant of Jacobian
-    double detJ = J_00*d00 + J_10*d10 + J_20*d20;
-    
-    // Compute inverse of Jacobian
-    
-    // Compute constants
-    const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
-                    + d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
-                    + d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
-    
-    const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
-                    + d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
-                    + d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
-    
-    const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
-                    + d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
-                    + d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
-    
-    // Get coordinates and map to the UFC reference element
-    double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
-    double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
-    double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
-    
-    // Map coordinates to the reference cube
-    if (std::abs(y + z - 1.0) < 1e-14)
-      x = 1.0;
-    else
-      x = -2.0 * x/(y + z - 1.0) - 1.0;
-    if (std::abs(z - 1.0) < 1e-14)
-      y = -1.0;
-    else
-      y = 2.0 * y/(1.0 - z) - 1.0;
-    z = 2.0 * z - 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);
-    const double scalings_z_0 = 1;
-    const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
-    const double scalings_z_2 = scalings_z_1*(0.5 - 0.5*z);
-    
-    // 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 psitilde_cs
-    const double psitilde_cs_00_0 = 1;
-    const double psitilde_cs_00_1 = 2*z + 1;
-    const double psitilde_cs_00_2 = 0.3125*psitilde_cs_00_1 + 1.875*z*psitilde_cs_00_1 - 0.5625*psitilde_cs_00_0;
-    const double psitilde_cs_01_0 = 1;
-    const double psitilde_cs_01_1 = 3*z + 2;
-    const double psitilde_cs_02_0 = 1;
-    const double psitilde_cs_10_0 = 1;
-    const double psitilde_cs_10_1 = 3*z + 2;
-    const double psitilde_cs_11_0 = 1;
-    const double psitilde_cs_20_0 = 1;
-    
-    // Compute basisvalues
-    const double basisvalue0 = 0.866025403784439*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
-    const double basisvalue1 = 2.73861278752583*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
-    const double basisvalue2 = 1.58113883008419*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
-    const double basisvalue3 = 1.11803398874989*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
-    const double basisvalue4 = 5.1234753829798*psitilde_a_2*scalings_y_2*psitilde_bs_2_0*scalings_z_2*psitilde_cs_20_0;
-    const double basisvalue5 = 3.96862696659689*psitilde_a_1*scalings_y_1*psitilde_bs_1_1*scalings_z_2*psitilde_cs_11_0;
-    const double basisvalue6 = 2.29128784747792*psitilde_a_0*scalings_y_0*psitilde_bs_0_2*scalings_z_2*psitilde_cs_02_0;
-    const double basisvalue7 = 3.24037034920393*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_1;
-    const double basisvalue8 = 1.87082869338697*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_1;
-    const double basisvalue9 = 1.3228756555323*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_2;
-    
-    // Table(s) of coefficients
-    static const double coefficients0[10][10] = \
-    {{-0.0577350269189626, -0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, 0.0503952630678969, 0.0290957186981323, 0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
-    {-0.0577350269189625, 0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, -0.050395263067897, 0.0290957186981323, -0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
-    {-0.0577350269189625, 0, 0.0702728368926306, -0.0248451997499977, 0, 0, 0.0872871560943969, 0, -0.0475131096733199, 0.0167984210226323},
-    {-0.0577350269189626, 0, 0, 0.074535599249993, 0, 0, 0, 0, 0, 0.100790526135794},
-    {0.23094010767585, 0, 0.140545673785261, 0.0993807989999906, 0, 0, 0, 0, 0.1187827741833, -0.0671936840905293},
-    {0.230940107675851, 0.121716123890037, -0.0702728368926306, 0.0993807989999907, 0, 0, 0, 0.102868899974728, -0.0593913870916499, -0.0671936840905293},
-    {0.23094010767585, 0.121716123890037, 0.0702728368926307, -0.0993807989999907, 0, 0.100790526135794, -0.087287156094397, -0.0205737799949456, -0.01187827741833, 0.0167984210226323},
-    {0.23094010767585, -0.121716123890037, -0.0702728368926307, 0.0993807989999906, 0, 0, 0, -0.102868899974728, -0.0593913870916499, -0.0671936840905293},
-    {0.23094010767585, -0.121716123890037, 0.0702728368926306, -0.0993807989999906, 0, -0.100790526135794, -0.0872871560943969, 0.0205737799949456, -0.01187827741833, 0.0167984210226323},
-    {0.23094010767585, 0, -0.140545673785261, -0.0993807989999906, -0.130120009726471, 0, 0.0290957186981323, 0, 0.02375655483666, 0.0167984210226323}};
-    
-    // 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];
-    const double coeff0_6 = coefficients0[dof][6];
-    const double coeff0_7 = coefficients0[dof][7];
-    const double coeff0_8 = coefficients0[dof][8];
-    const double coeff0_9 = coefficients0[dof][9];
-    
-    // Compute value(s)
-    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5 + coeff0_6*basisvalue6 + coeff0_7*basisvalue7 + coeff0_8*basisvalue8 + coeff0_9*basisvalue9;
-}
-
-/// Evaluate all basis functions at given point in cell
-void solitarywave3d_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 solitarywave3d_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_02 = element_coordinates[3][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];
-    const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
-    const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
-    const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
-    const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
-    
-    // Compute sub determinants
-    const double d00 = J_11*J_22 - J_12*J_21;
-    const double d01 = J_12*J_20 - J_10*J_22;
-    const double d02 = J_10*J_21 - J_11*J_20;
-    
-    const double d10 = J_02*J_21 - J_01*J_22;
-    const double d11 = J_00*J_22 - J_02*J_20;
-    const double d12 = J_01*J_20 - J_00*J_21;
-    
-    const double d20 = J_01*J_12 - J_02*J_11;
-    const double d21 = J_02*J_10 - J_00*J_12;
-    const double d22 = J_00*J_11 - J_01*J_10;
-    
-    // Compute determinant of Jacobian
-    double detJ = J_00*d00 + J_10*d10 + J_20*d20;
-    
-    // Compute inverse of Jacobian
-    
-    // Compute constants
-    const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
-                    + d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
-                    + d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
-    
-    const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
-                    + d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
-                    + d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
-    
-    const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
-                    + d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
-                    + d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
-    
-    // Get coordinates and map to the UFC reference element
-    double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
-    double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
-    double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
-    
-    // Map coordinates to the reference cube
-    if (std::abs(y + z - 1.0) < 1e-14)
-      x = 1.0;
-    else
-      x = -2.0 * x/(y + z - 1.0) - 1.0;
-    if (std::abs(z - 1.0) < 1e-14)
-      y = -1.0;
-    else
-      y = 2.0 * y/(1.0 - z) - 1.0;
-    z = 2.0 * z - 1.0;
-    
-    // Compute number of derivatives
-    unsigned int num_derivatives = 1;
-    
-    for (unsigned int j = 0; j < n; j++)
-      num_derivatives *= 3;
-    
-    
-    // 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 > 2)
-            combinations[row][col] = 0;
-          else
-          {
-            combinations[row][col] += 1;
-            break;
-          }
-        }
-      }
-    }
-    
-    // Compute inverse of Jacobian
-    const double Jinv[3][3] ={{d00 / detJ, d10 / detJ, d20 / detJ}, {d01 / detJ, d11 / detJ, d21 / detJ}, {d02 / detJ, d12 / detJ, d22 / 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);
-    const double scalings_z_0 = 1;
-    const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
-    const double scalings_z_2 = scalings_z_1*(0.5 - 0.5*z);
-    
-    // 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 psitilde_cs
-    const double psitilde_cs_00_0 = 1;
-    const double psitilde_cs_00_1 = 2*z + 1;
-    const double psitilde_cs_00_2 = 0.3125*psitilde_cs_00_1 + 1.875*z*psitilde_cs_00_1 - 0.5625*psitilde_cs_00_0;
-    const double psitilde_cs_01_0 = 1;
-    const double psitilde_cs_01_1 = 3*z + 2;
-    const double psitilde_cs_02_0 = 1;
-    const double psitilde_cs_10_0 = 1;
-    const double psitilde_cs_10_1 = 3*z + 2;
-    const double psitilde_cs_11_0 = 1;
-    const double psitilde_cs_20_0 = 1;
-    
-    // Compute basisvalues
-    const double basisvalue0 = 0.866025403784439*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
-    const double basisvalue1 = 2.73861278752583*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
-    const double basisvalue2 = 1.58113883008419*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
-    const double basisvalue3 = 1.11803398874989*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
-    const double basisvalue4 = 5.1234753829798*psitilde_a_2*scalings_y_2*psitilde_bs_2_0*scalings_z_2*psitilde_cs_20_0;
-    const double basisvalue5 = 3.96862696659689*psitilde_a_1*scalings_y_1*psitilde_bs_1_1*scalings_z_2*psitilde_cs_11_0;
-    const double basisvalue6 = 2.29128784747792*psitilde_a_0*scalings_y_0*psitilde_bs_0_2*scalings_z_2*psitilde_cs_02_0;
-    const double basisvalue7 = 3.24037034920393*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_1;
-    const double basisvalue8 = 1.87082869338697*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_1;
-    const double basisvalue9 = 1.3228756555323*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_2;
-    
-    // Table(s) of coefficients
-    static const double coefficients0[10][10] = \
-    {{-0.0577350269189626, -0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, 0.0503952630678969, 0.0290957186981323, 0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
-    {-0.0577350269189625, 0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, -0.050395263067897, 0.0290957186981323, -0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
-    {-0.0577350269189625, 0, 0.0702728368926306, -0.0248451997499977, 0, 0, 0.0872871560943969, 0, -0.0475131096733199, 0.0167984210226323},
-    {-0.0577350269189626, 0, 0, 0.074535599249993, 0, 0, 0, 0, 0, 0.100790526135794},
-    {0.23094010767585, 0, 0.140545673785261, 0.0993807989999906, 0, 0, 0, 0, 0.1187827741833, -0.0671936840905293},
-    {0.230940107675851, 0.121716123890037, -0.0702728368926306, 0.0993807989999907, 0, 0, 0, 0.102868899974728, -0.0593913870916499, -0.0671936840905293},
-    {0.23094010767585, 0.121716123890037, 0.0702728368926307, -0.0993807989999907, 0, 0.100790526135794, -0.087287156094397, -0.0205737799949456, -0.01187827741833, 0.0167984210226323},
-    {0.23094010767585, -0.121716123890037, -0.0702728368926307, 0.0993807989999906, 0, 0, 0, -0.102868899974728, -0.0593913870916499, -0.0671936840905293},
-    {0.23094010767585, -0.121716123890037, 0.0702728368926306, -0.0993807989999906, 0, -0.100790526135794, -0.0872871560943969, 0.0205737799949456, -0.01187827741833, 0.0167984210226323},
-    {0.23094010767585, 0, -0.140545673785261, -0.0993807989999906, -0.130120009726471, 0, 0.0290957186981323, 0, 0.02375655483666, 0.0167984210226323}};
-    
-    // Interesting (new) part
-    // Tables of derivatives of the polynomial base (transpose)
-    static const double dmats0[10][10] = \
-    {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-    {6.32455532033676, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-    {0, 11.2249721603218, 0, 0, 0, 0, 0, 0, 0, 0},
-    {4.58257569495584, 0, 8.36660026534076, -1.18321595661992, 0, 0, 0, 0, 0, 0},
-    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-    {3.74165738677394, 0, 0, 8.69482604771366, 0, 0, 0, 0, 0, 0},
-    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
-    
-    static const double dmats1[10][10] = \
-    {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-    {3.16227766016838, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-    {5.47722557505166, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-    {2.95803989154981, 5.61248608016091, -1.08012344973464, -0.763762615825974, 0, 0, 0, 0, 0, 0},
-    {2.29128784747792, 7.24568837309472, 4.18330013267038, -0.591607978309962, 0, 0, 0, 0, 0, 0},
-    {-2.64575131106459, 0, 9.66091783079296, 0.683130051063974, 0, 0, 0, 0, 0, 0},
-    {1.87082869338697, 0, 0, 4.34741302385683, 0, 0, 0, 0, 0, 0},
-    {3.24037034920393, 0, 0, 7.52994023880668, 0, 0, 0, 0, 0, 0},
-    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
-    
-    static const double dmats2[10][10] = \
-    {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-    {3.16227766016838, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-    {1.82574185835055, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-    {5.16397779494322, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-    {2.95803989154981, 5.61248608016091, -1.08012344973464, -0.763762615825974, 0, 0, 0, 0, 0, 0},
-    {2.29128784747792, 1.44913767461894, 4.18330013267038, -0.591607978309962, 0, 0, 0, 0, 0, 0},
-    {1.32287565553229, 0, 3.86436713231718, -0.341565025531986, 0, 0, 0, 0, 0, 0},
-    {1.87082869338697, 7.09929573971954, 0, 4.34741302385683, 0, 0, 0, 0, 0, 0},
-    {1.08012344973464, 0, 7.09929573971954, 2.50998007960223, 0, 0, 0, 0, 0, 0},
-    {-3.81881307912987, 0, 0, 8.87411967464942, 0, 0, 0, 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;
-    double coeff0_6 = 0;
-    double coeff0_7 = 0;
-    double coeff0_8 = 0;
-    double coeff0_9 = 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;
-    double new_coeff0_6 = 0;
-    double new_coeff0_7 = 0;
-    double new_coeff0_8 = 0;
-    double new_coeff0_9 = 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];
-      new_coeff0_6 = coefficients0[dof][6];
-      new_coeff0_7 = coefficients0[dof][7];
-      new_coeff0_8 = coefficients0[dof][8];
-      new_coeff0_9 = coefficients0[dof][9];
-    
-      // 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;
-        coeff0_6 = new_coeff0_6;
-        coeff0_7 = new_coeff0_7;
-        coeff0_8 = new_coeff0_8;
-        coeff0_9 = new_coeff0_9;
-    
-        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] + coeff0_6*dmats0[6][0] + coeff0_7*dmats0[7][0] + coeff0_8*dmats0[8][0] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][1] + coeff0_7*dmats0[7][1] + coeff0_8*dmats0[8][1] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][2] + coeff0_7*dmats0[7][2] + coeff0_8*dmats0[8][2] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][3] + coeff0_7*dmats0[7][3] + coeff0_8*dmats0[8][3] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][4] + coeff0_7*dmats0[7][4] + coeff0_8*dmats0[8][4] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][5] + coeff0_7*dmats0[7][5] + coeff0_8*dmats0[8][5] + coeff0_9*dmats0[9][5];
-          new_coeff0_6 = coeff0_0*dmats0[0][6] + coeff0_1*dmats0[1][6] + coeff0_2*dmats0[2][6] + coeff0_3*dmats0[3][6] + coeff0_4*dmats0[4][6] + coeff0_5*dmats0[5][6] + coeff0_6*dmats0[6][6] + coeff0_7*dmats0[7][6] + coeff0_8*dmats0[8][6] + coeff0_9*dmats0[9][6];
-          new_coeff0_7 = coeff0_0*dmats0[0][7] + coeff0_1*dmats0[1][7] + coeff0_2*dmats0[2][7] + coeff0_3*dmats0[3][7] + coeff0_4*dmats0[4][7] + coeff0_5*dmats0[5][7] + coeff0_6*dmats0[6][7] + coeff0_7*dmats0[7][7] + coeff0_8*dmats0[8][7] + coeff0_9*dmats0[9][7];
-          new_coeff0_8 = coeff0_0*dmats0[0][8] + coeff0_1*dmats0[1][8] + coeff0_2*dmats0[2][8] + coeff0_3*dmats0[3][8] + coeff0_4*dmats0[4][8] + coeff0_5*dmats0[5][8] + coeff0_6*dmats0[6][8] + coeff0_7*dmats0[7][8] + coeff0_8*dmats0[8][8] + coeff0_9*dmats0[9][8];
-          new_coeff0_9 = coeff0_0*dmats0[0][9] + coeff0_1*dmats0[1][9] + coeff0_2*dmats0[2][9] + coeff0_3*dmats0[3][9] + coeff0_4*dmats0[4][9] + coeff0_5*dmats0[5][9] + coeff0_6*dmats0[6][9] + coeff0_7*dmats0[7][9] + coeff0_8*dmats0[8][9] + coeff0_9*dmats0[9][9];
-        }
-        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] + coeff0_6*dmats1[6][0] + coeff0_7*dmats1[7][0] + coeff0_8*dmats1[8][0] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][1] + coeff0_7*dmats1[7][1] + coeff0_8*dmats1[8][1] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][2] + coeff0_7*dmats1[7][2] + coeff0_8*dmats1[8][2] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][3] + coeff0_7*dmats1[7][3] + coeff0_8*dmats1[8][3] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][4] + coeff0_7*dmats1[7][4] + coeff0_8*dmats1[8][4] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][5] + coeff0_7*dmats1[7][5] + coeff0_8*dmats1[8][5] + coeff0_9*dmats1[9][5];
-          new_coeff0_6 = coeff0_0*dmats1[0][6] + coeff0_1*dmats1[1][6] + coeff0_2*dmats1[2][6] + coeff0_3*dmats1[3][6] + coeff0_4*dmats1[4][6] + coeff0_5*dmats1[5][6] + coeff0_6*dmats1[6][6] + coeff0_7*dmats1[7][6] + coeff0_8*dmats1[8][6] + coeff0_9*dmats1[9][6];
-          new_coeff0_7 = coeff0_0*dmats1[0][7] + coeff0_1*dmats1[1][7] + coeff0_2*dmats1[2][7] + coeff0_3*dmats1[3][7] + coeff0_4*dmats1[4][7] + coeff0_5*dmats1[5][7] + coeff0_6*dmats1[6][7] + coeff0_7*dmats1[7][7] + coeff0_8*dmats1[8][7] + coeff0_9*dmats1[9][7];
-          new_coeff0_8 = coeff0_0*dmats1[0][8] + coeff0_1*dmats1[1][8] + coeff0_2*dmats1[2][8] + coeff0_3*dmats1[3][8] + coeff0_4*dmats1[4][8] + coeff0_5*dmats1[5][8] + coeff0_6*dmats1[6][8] + coeff0_7*dmats1[7][8] + coeff0_8*dmats1[8][8] + coeff0_9*dmats1[9][8];
-          new_coeff0_9 = coeff0_0*dmats1[0][9] + coeff0_1*dmats1[1][9] + coeff0_2*dmats1[2][9] + coeff0_3*dmats1[3][9] + coeff0_4*dmats1[4][9] + coeff0_5*dmats1[5][9] + coeff0_6*dmats1[6][9] + coeff0_7*dmats1[7][9] + coeff0_8*dmats1[8][9] + coeff0_9*dmats1[9][9];
-        }
-        if(combinations[deriv_num][j] == 2)
-        {
-          new_coeff0_0 = coeff0_0*dmats2[0][0] + coeff0_1*dmats2[1][0] + coeff0_2*dmats2[2][0] + coeff0_3*dmats2[3][0] + coeff0_4*dmats2[4][0] + coeff0_5*dmats2[5][0] + coeff0_6*dmats2[6][0] + coeff0_7*dmats2[7][0] + coeff0_8*dmats2[8][0] + coeff0_9*dmats2[9][0];
-          new_coeff0_1 = coeff0_0*dmats2[0][1] + coeff0_1*dmats2[1][1] + coeff0_2*dmats2[2][1] + coeff0_3*dmats2[3][1] + coeff0_4*dmats2[4][1] + coeff0_5*dmats2[5][1] + coeff0_6*dmats2[6][1] + coeff0_7*dmats2[7][1] + coeff0_8*dmats2[8][1] + coeff0_9*dmats2[9][1];
-          new_coeff0_2 = coeff0_0*dmats2[0][2] + coeff0_1*dmats2[1][2] + coeff0_2*dmats2[2][2] + coeff0_3*dmats2[3][2] + coeff0_4*dmats2[4][2] + coeff0_5*dmats2[5][2] + coeff0_6*dmats2[6][2] + coeff0_7*dmats2[7][2] + coeff0_8*dmats2[8][2] + coeff0_9*dmats2[9][2];
-          new_coeff0_3 = coeff0_0*dmats2[0][3] + coeff0_1*dmats2[1][3] + coeff0_2*dmats2[2][3] + coeff0_3*dmats2[3][3] + coeff0_4*dmats2[4][3] + coeff0_5*dmats2[5][3] + coeff0_6*dmats2[6][3] + coeff0_7*dmats2[7][3] + coeff0_8*dmats2[8][3] + coeff0_9*dmats2[9][3];
-          new_coeff0_4 = coeff0_0*dmats2[0][4] + coeff0_1*dmats2[1][4] + coeff0_2*dmats2[2][4] + coeff0_3*dmats2[3][4] + coeff0_4*dmats2[4][4] + coeff0_5*dmats2[5][4] + coeff0_6*dmats2[6][4] + coeff0_7*dmats2[7][4] + coeff0_8*dmats2[8][4] + coeff0_9*dmats2[9][4];
-          new_coeff0_5 = coeff0_0*dmats2[0][5] + coeff0_1*dmats2[1][5] + coeff0_2*dmats2[2][5] + coeff0_3*dmats2[3][5] + coeff0_4*dmats2[4][5] + coeff0_5*dmats2[5][5] + coeff0_6*dmats2[6][5] + coeff0_7*dmats2[7][5] + coeff0_8*dmats2[8][5] + coeff0_9*dmats2[9][5];
-          new_coeff0_6 = coeff0_0*dmats2[0][6] + coeff0_1*dmats2[1][6] + coeff0_2*dmats2[2][6] + coeff0_3*dmats2[3][6] + coeff0_4*dmats2[4][6] + coeff0_5*dmats2[5][6] + coeff0_6*dmats2[6][6] + coeff0_7*dmats2[7][6] + coeff0_8*dmats2[8][6] + coeff0_9*dmats2[9][6];
-          new_coeff0_7 = coeff0_0*dmats2[0][7] + coeff0_1*dmats2[1][7] + coeff0_2*dmats2[2][7] + coeff0_3*dmats2[3][7] + coeff0_4*dmats2[4][7] + coeff0_5*dmats2[5][7] + coeff0_6*dmats2[6][7] + coeff0_7*dmats2[7][7] + coeff0_8*dmats2[8][7] + coeff0_9*dmats2[9][7];
-          new_coeff0_8 = coeff0_0*dmats2[0][8] + coeff0_1*dmats2[1][8] + coeff0_2*dmats2[2][8] + coeff0_3*dmats2[3][8] + coeff0_4*dmats2[4][8] + coeff0_5*dmats2[5][8] + coeff0_6*dmats2[6][8] + coeff0_7*dmats2[7][8] + coeff0_8*dmats2[8][8] + coeff0_9*dmats2[9][8];
-          new_coeff0_9 = coeff0_0*dmats2[0][9] + coeff0_1*dmats2[1][9] + coeff0_2*dmats2[2][9] + coeff0_3*dmats2[3][9] + coeff0_4*dmats2[4][9] + coeff0_5*dmats2[5][9] + coeff0_6*dmats2[6][9] + coeff0_7*dmats2[7][9] + coeff0_8*dmats2[8][9] + coeff0_9*dmats2[9][9];
-        }
-    
-      }
-      // 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 + new_coeff0_6*basisvalue6 + new_coeff0_7*basisvalue7 + new_coeff0_8*basisvalue8 + new_coeff0_9*basisvalue9;
-    }
-    
-    // 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 solitarywave3d_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 solitarywave3d_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[10][1][3] = {{{0, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 0, 1}}, {{0, 0.5, 0.5}}, {{0.5, 0, 0.5}}, {{0.5, 0.5, 0}}, {{0, 0, 0.5}}, {{0, 0.5, 0}}, {{0.5, 0, 0}}};
-    static const double W[10][1] = {{1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}};
-    static const double D[10][1][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] - X[i][0][2];
-    const double w1 = X[i][0][0];
-    const double w2 = X[i][0][1];
-    const double w3 = X[i][0][2];
-    
-    // Compute affine mapping y = F(X)
-    double y[3];
-    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0] + w3*x[3][0];
-    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1] + w3*x[3][1];
-    y[2] = w0*x[0][2] + w1*x[1][2] + w2*x[2][2] + w3*x[3][2];
-    
-    // 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 solitarywave3d_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 solitarywave3d_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];
-    vertex_values[3] = dof_values[3];
-}
-
-/// Return the number of sub elements (for a mixed element)
-unsigned int solitarywave3d_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* solitarywave3d_1_finite_element_1_0::create_sub_element(unsigned int i) const
-{
-    return new solitarywave3d_1_finite_element_1_0();
-}
-
-
-/// Constructor
-solitarywave3d_1_finite_element_1_1::solitarywave3d_1_finite_element_1_1() : ufc::finite_element()
-{
-    // Do nothing
-}
-
-/// Destructor
-solitarywave3d_1_finite_element_1_1::~solitarywave3d_1_finite_element_1_1()
-{
-    // Do nothing
-}
-
-/// Return a string identifying the finite element
-const char* solitarywave3d_1_finite_element_1_1::signature() const
-{
-    return "FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)";
-}
-
-/// Return the cell shape
-ufc::shape solitarywave3d_1_finite_element_1_1::cell_shape() const
-{
-    return ufc::tetrahedron;
-}
-
-/// Return the dimension of the finite element function space
-unsigned int solitarywave3d_1_finite_element_1_1::space_dimension() const
-{
-    return 10;
-}
-
-/// Return the rank of the value space
-unsigned int solitarywave3d_1_finite_element_1_1::value_rank() const
-{
-    return 0;
-}
-
-/// Return the dimension of the value space for axis i
-unsigned int solitarywave3d_1_finite_element_1_1::value_dimension(unsigned int i) const
-{
-    return 1;
-}
-
-/// Evaluate basis function i at given point in cell
-void solitarywave3d_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_02 = element_coordinates[3][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];
-    const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
-    const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
-    const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
-    const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
-    
-    // Compute sub determinants
-    const double d00 = J_11*J_22 - J_12*J_21;
-    const double d01 = J_12*J_20 - J_10*J_22;
-    const double d02 = J_10*J_21 - J_11*J_20;
-    
-    const double d10 = J_02*J_21 - J_01*J_22;
-    const double d11 = J_00*J_22 - J_02*J_20;
-    const double d12 = J_01*J_20 - J_00*J_21;
-    
-    const double d20 = J_01*J_12 - J_02*J_11;
-    const double d21 = J_02*J_10 - J_00*J_12;
-    const double d22 = J_00*J_11 - J_01*J_10;
-    
-    // Compute determinant of Jacobian
-    double detJ = J_00*d00 + J_10*d10 + J_20*d20;
-    
-    // Compute inverse of Jacobian
-    
-    // Compute constants
-    const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
-                    + d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
-                    + d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
-    
-    const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
-                    + d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
-                    + d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
-    
-    const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
-                    + d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
-                    + d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
-    
-    // Get coordinates and map to the UFC reference element
-    double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
-    double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
-    double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
-    
-    // Map coordinates to the reference cube
-    if (std::abs(y + z - 1.0) < 1e-14)
-      x = 1.0;
-    else
-      x = -2.0 * x/(y + z - 1.0) - 1.0;
-    if (std::abs(z - 1.0) < 1e-14)
-      y = -1.0;
-    else
-      y = 2.0 * y/(1.0 - z) - 1.0;
-    z = 2.0 * z - 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);
-    const double scalings_z_0 = 1;
-    const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
-    const double scalings_z_2 = scalings_z_1*(0.5 - 0.5*z);
-    
-    // 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 psitilde_cs
-    const double psitilde_cs_00_0 = 1;
-    const double psitilde_cs_00_1 = 2*z + 1;
-    const double psitilde_cs_00_2 = 0.3125*psitilde_cs_00_1 + 1.875*z*psitilde_cs_00_1 - 0.5625*psitilde_cs_00_0;
-    const double psitilde_cs_01_0 = 1;
-    const double psitilde_cs_01_1 = 3*z + 2;
-    const double psitilde_cs_02_0 = 1;
-    const double psitilde_cs_10_0 = 1;
-    const double psitilde_cs_10_1 = 3*z + 2;
-    const double psitilde_cs_11_0 = 1;
-    const double psitilde_cs_20_0 = 1;
-    
-    // Compute basisvalues
-    const double basisvalue0 = 0.866025403784439*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
-    const double basisvalue1 = 2.73861278752583*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
-    const double basisvalue2 = 1.58113883008419*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
-    const double basisvalue3 = 1.11803398874989*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
-    const double basisvalue4 = 5.1234753829798*psitilde_a_2*scalings_y_2*psitilde_bs_2_0*scalings_z_2*psitilde_cs_20_0;
-    const double basisvalue5 = 3.96862696659689*psitilde_a_1*scalings_y_1*psitilde_bs_1_1*scalings_z_2*psitilde_cs_11_0;
-    const double basisvalue6 = 2.29128784747792*psitilde_a_0*scalings_y_0*psitilde_bs_0_2*scalings_z_2*psitilde_cs_02_0;
-    const double basisvalue7 = 3.24037034920393*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_1;
-    const double basisvalue8 = 1.87082869338697*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_1;
-    const double basisvalue9 = 1.3228756555323*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_2;
-    
-    // Table(s) of coefficients
-    static const double coefficients0[10][10] = \
-    {{-0.0577350269189626, -0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, 0.0503952630678969, 0.0290957186981323, 0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
-    {-0.0577350269189625, 0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, -0.050395263067897, 0.0290957186981323, -0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
-    {-0.0577350269189625, 0, 0.0702728368926306, -0.0248451997499977, 0, 0, 0.0872871560943969, 0, -0.0475131096733199, 0.0167984210226323},
-    {-0.0577350269189626, 0, 0, 0.074535599249993, 0, 0, 0, 0, 0, 0.100790526135794},
-    {0.23094010767585, 0, 0.140545673785261, 0.0993807989999906, 0, 0, 0, 0, 0.1187827741833, -0.0671936840905293},
-    {0.230940107675851, 0.121716123890037, -0.0702728368926306, 0.0993807989999907, 0, 0, 0, 0.102868899974728, -0.0593913870916499, -0.0671936840905293},
-    {0.23094010767585, 0.121716123890037, 0.0702728368926307, -0.0993807989999907, 0, 0.100790526135794, -0.087287156094397, -0.0205737799949456, -0.01187827741833, 0.0167984210226323},
-    {0.23094010767585, -0.121716123890037, -0.0702728368926307, 0.0993807989999906, 0, 0, 0, -0.102868899974728, -0.0593913870916499, -0.0671936840905293},
-    {0.23094010767585, -0.121716123890037, 0.0702728368926306, -0.0993807989999906, 0, -0.100790526135794, -0.0872871560943969, 0.0205737799949456, -0.01187827741833, 0.0167984210226323},
-    {0.23094010767585, 0, -0.140545673785261, -0.0993807989999906, -0.130120009726471, 0, 0.0290957186981323, 0, 0.02375655483666, 0.0167984210226323}};
-    
-    // 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];
-    const double coeff0_6 = coefficients0[dof][6];
-    const double coeff0_7 = coefficients0[dof][7];
-    const double coeff0_8 = coefficients0[dof][8];
-    const double coeff0_9 = coefficients0[dof][9];
-    
-    // Compute value(s)
-    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5 + coeff0_6*basisvalue6 + coeff0_7*basisvalue7 + coeff0_8*basisvalue8 + coeff0_9*basisvalue9;
-}
-
-/// Evaluate all basis functions at given point in cell
-void solitarywave3d_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 solitarywave3d_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_02 = element_coordinates[3][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];
-    const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
-    const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
-    const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
-    const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
-    
-    // Compute sub determinants
-    const double d00 = J_11*J_22 - J_12*J_21;
-    const double d01 = J_12*J_20 - J_10*J_22;
-    const double d02 = J_10*J_21 - J_11*J_20;
-    
-    const double d10 = J_02*J_21 - J_01*J_22;
-    const double d11 = J_00*J_22 - J_02*J_20;
-    const double d12 = J_01*J_20 - J_00*J_21;
-    
-    const double d20 = J_01*J_12 - J_02*J_11;
-    const double d21 = J_02*J_10 - J_00*J_12;
-    const double d22 = J_00*J_11 - J_01*J_10;
-    
-    // Compute determinant of Jacobian
-    double detJ = J_00*d00 + J_10*d10 + J_20*d20;
-    
-    // Compute inverse of Jacobian
-    
-    // Compute constants
-    const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
-                    + d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
-                    + d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
-    
-    const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
-                    + d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
-                    + d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
-    
-    const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
-                    + d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
-                    + d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
-    
-    // Get coordinates and map to the UFC reference element
-    double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
-    double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
-    double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
-    
-    // Map coordinates to the reference cube
-    if (std::abs(y + z - 1.0) < 1e-14)
-      x = 1.0;
-    else
-      x = -2.0 * x/(y + z - 1.0) - 1.0;
-    if (std::abs(z - 1.0) < 1e-14)
-      y = -1.0;
-    else
-      y = 2.0 * y/(1.0 - z) - 1.0;
-    z = 2.0 * z - 1.0;
-    
-    // Compute number of derivatives
-    unsigned int num_derivatives = 1;
-    
-    for (unsigned int j = 0; j < n; j++)
-      num_derivatives *= 3;
-    
-    
-    // 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 > 2)
-            combinations[row][col] = 0;
-          else
-          {
-            combinations[row][col] += 1;
-            break;
-          }
-        }
-      }
-    }
-    
-    // Compute inverse of Jacobian
-    const double Jinv[3][3] ={{d00 / detJ, d10 / detJ, d20 / detJ}, {d01 / detJ, d11 / detJ, d21 / detJ}, {d02 / detJ, d12 / detJ, d22 / 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);
-    const double scalings_z_0 = 1;
-    const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
-    const double scalings_z_2 = scalings_z_1*(0.5 - 0.5*z);
-    
-    // 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 psitilde_cs
-    const double psitilde_cs_00_0 = 1;
-    const double psitilde_cs_00_1 = 2*z + 1;
-    const double psitilde_cs_00_2 = 0.3125*psitilde_cs_00_1 + 1.875*z*psitilde_cs_00_1 - 0.5625*psitilde_cs_00_0;
-    const double psitilde_cs_01_0 = 1;
-    const double psitilde_cs_01_1 = 3*z + 2;
-    const double psitilde_cs_02_0 = 1;
-    const double psitilde_cs_10_0 = 1;
-    const double psitilde_cs_10_1 = 3*z + 2;
-    const double psitilde_cs_11_0 = 1;
-    const double psitilde_cs_20_0 = 1;
-    
-    // Compute basisvalues
-    const double basisvalue0 = 0.866025403784439*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
-    const double basisvalue1 = 2.73861278752583*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
-    const double basisvalue2 = 1.58113883008419*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
-    const double basisvalue3 = 1.11803398874989*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
-    const double basisvalue4 = 5.1234753829798*psitilde_a_2*scalings_y_2*psitilde_bs_2_0*scalings_z_2*psitilde_cs_20_0;
-    const double basisvalue5 = 3.96862696659689*psitilde_a_1*scalings_y_1*psitilde_bs_1_1*scalings_z_2*psitilde_cs_11_0;
-    const double basisvalue6 = 2.29128784747792*psitilde_a_0*scalings_y_0*psitilde_bs_0_2*scalings_z_2*psitilde_cs_02_0;
-    const double basisvalue7 = 3.24037034920393*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_1;
-    const double basisvalue8 = 1.87082869338697*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_1;
-    const double basisvalue9 = 1.3228756555323*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_2;
-    
-    // Table(s) of coefficients
-    static const double coefficients0[10][10] = \
-    {{-0.0577350269189626, -0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, 0.0503952630678969, 0.0290957186981323, 0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
-    {-0.0577350269189625, 0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, -0.050395263067897, 0.0290957186981323, -0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
-    {-0.0577350269189625, 0, 0.0702728368926306, -0.0248451997499977, 0, 0, 0.0872871560943969, 0, -0.0475131096733199, 0.0167984210226323},
-    {-0.0577350269189626, 0, 0, 0.074535599249993, 0, 0, 0, 0, 0, 0.100790526135794},
-    {0.23094010767585, 0, 0.140545673785261, 0.0993807989999906, 0, 0, 0, 0, 0.1187827741833, -0.0671936840905293},
-    {0.230940107675851, 0.121716123890037, -0.0702728368926306, 0.0993807989999907, 0, 0, 0, 0.102868899974728, -0.0593913870916499, -0.0671936840905293},
-    {0.23094010767585, 0.121716123890037, 0.0702728368926307, -0.0993807989999907, 0, 0.100790526135794, -0.087287156094397, -0.0205737799949456, -0.01187827741833, 0.0167984210226323},
-    {0.23094010767585, -0.121716123890037, -0.0702728368926307, 0.0993807989999906, 0, 0, 0, -0.102868899974728, -0.0593913870916499, -0.0671936840905293},
-    {0.23094010767585, -0.121716123890037, 0.0702728368926306, -0.0993807989999906, 0, -0.100790526135794, -0.0872871560943969, 0.0205737799949456, -0.01187827741833, 0.0167984210226323},
-    {0.23094010767585, 0, -0.140545673785261, -0.0993807989999906, -0.130120009726471, 0, 0.0290957186981323, 0, 0.02375655483666, 0.0167984210226323}};
-    
-    // Interesting (new) part
-    // Tables of derivatives of the polynomial base (transpose)
-    static const double dmats0[10][10] = \
-    {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-    {6.32455532033676, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-    {0, 11.2249721603218, 0, 0, 0, 0, 0, 0, 0, 0},
-    {4.58257569495584, 0, 8.36660026534076, -1.18321595661992, 0, 0, 0, 0, 0, 0},
-    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-    {3.74165738677394, 0, 0, 8.69482604771366, 0, 0, 0, 0, 0, 0},
-    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
-    
-    static const double dmats1[10][10] = \
-    {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-    {3.16227766016838, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-    {5.47722557505166, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-    {2.95803989154981, 5.61248608016091, -1.08012344973464, -0.763762615825974, 0, 0, 0, 0, 0, 0},
-    {2.29128784747792, 7.24568837309472, 4.18330013267038, -0.591607978309962, 0, 0, 0, 0, 0, 0},
-    {-2.64575131106459, 0, 9.66091783079296, 0.683130051063974, 0, 0, 0, 0, 0, 0},
-    {1.87082869338697, 0, 0, 4.34741302385683, 0, 0, 0, 0, 0, 0},
-    {3.24037034920393, 0, 0, 7.52994023880668, 0, 0, 0, 0, 0, 0},
-    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
-    
-    static const double dmats2[10][10] = \
-    {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-    {3.16227766016838, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-    {1.82574185835055, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-    {5.16397779494322, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-    {2.95803989154981, 5.61248608016091, -1.08012344973464, -0.763762615825974, 0, 0, 0, 0, 0, 0},
-    {2.29128784747792, 1.44913767461894, 4.18330013267038, -0.591607978309962, 0, 0, 0, 0, 0, 0},
-    {1.32287565553229, 0, 3.86436713231718, -0.341565025531986, 0, 0, 0, 0, 0, 0},
-    {1.87082869338697, 7.09929573971954, 0, 4.34741302385683, 0, 0, 0, 0, 0, 0},
-    {1.08012344973464, 0, 7.09929573971954, 2.50998007960223, 0, 0, 0, 0, 0, 0},
-    {-3.81881307912987, 0, 0, 8.87411967464942, 0, 0, 0, 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;
-    double coeff0_6 = 0;
-    double coeff0_7 = 0;
-    double coeff0_8 = 0;
-    double coeff0_9 = 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;
-    double new_coeff0_6 = 0;
-    double new_coeff0_7 = 0;
-    double new_coeff0_8 = 0;
-    double new_coeff0_9 = 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];
-      new_coeff0_6 = coefficients0[dof][6];
-      new_coeff0_7 = coefficients0[dof][7];
-      new_coeff0_8 = coefficients0[dof][8];
-      new_coeff0_9 = coefficients0[dof][9];
-    
-      // 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;
-        coeff0_6 = new_coeff0_6;
-        coeff0_7 = new_coeff0_7;
-        coeff0_8 = new_coeff0_8;
-        coeff0_9 = new_coeff0_9;
-    
-        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] + coeff0_6*dmats0[6][0] + coeff0_7*dmats0[7][0] + coeff0_8*dmats0[8][0] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][1] + coeff0_7*dmats0[7][1] + coeff0_8*dmats0[8][1] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][2] + coeff0_7*dmats0[7][2] + coeff0_8*dmats0[8][2] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][3] + coeff0_7*dmats0[7][3] + coeff0_8*dmats0[8][3] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][4] + coeff0_7*dmats0[7][4] + coeff0_8*dmats0[8][4] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][5] + coeff0_7*dmats0[7][5] + coeff0_8*dmats0[8][5] + coeff0_9*dmats0[9][5];
-          new_coeff0_6 = coeff0_0*dmats0[0][6] + coeff0_1*dmats0[1][6] + coeff0_2*dmats0[2][6] + coeff0_3*dmats0[3][6] + coeff0_4*dmats0[4][6] + coeff0_5*dmats0[5][6] + coeff0_6*dmats0[6][6] + coeff0_7*dmats0[7][6] + coeff0_8*dmats0[8][6] + coeff0_9*dmats0[9][6];
-          new_coeff0_7 = coeff0_0*dmats0[0][7] + coeff0_1*dmats0[1][7] + coeff0_2*dmats0[2][7] + coeff0_3*dmats0[3][7] + coeff0_4*dmats0[4][7] + coeff0_5*dmats0[5][7] + coeff0_6*dmats0[6][7] + coeff0_7*dmats0[7][7] + coeff0_8*dmats0[8][7] + coeff0_9*dmats0[9][7];
-          new_coeff0_8 = coeff0_0*dmats0[0][8] + coeff0_1*dmats0[1][8] + coeff0_2*dmats0[2][8] + coeff0_3*dmats0[3][8] + coeff0_4*dmats0[4][8] + coeff0_5*dmats0[5][8] + coeff0_6*dmats0[6][8] + coeff0_7*dmats0[7][8] + coeff0_8*dmats0[8][8] + coeff0_9*dmats0[9][8];
-          new_coeff0_9 = coeff0_0*dmats0[0][9] + coeff0_1*dmats0[1][9] + coeff0_2*dmats0[2][9] + coeff0_3*dmats0[3][9] + coeff0_4*dmats0[4][9] + coeff0_5*dmats0[5][9] + coeff0_6*dmats0[6][9] + coeff0_7*dmats0[7][9] + coeff0_8*dmats0[8][9] + coeff0_9*dmats0[9][9];
-        }
-        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] + coeff0_6*dmats1[6][0] + coeff0_7*dmats1[7][0] + coeff0_8*dmats1[8][0] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][1] + coeff0_7*dmats1[7][1] + coeff0_8*dmats1[8][1] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][2] + coeff0_7*dmats1[7][2] + coeff0_8*dmats1[8][2] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][3] + coeff0_7*dmats1[7][3] + coeff0_8*dmats1[8][3] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][4] + coeff0_7*dmats1[7][4] + coeff0_8*dmats1[8][4] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][5] + coeff0_7*dmats1[7][5] + coeff0_8*dmats1[8][5] + coeff0_9*dmats1[9][5];
-          new_coeff0_6 = coeff0_0*dmats1[0][6] + coeff0_1*dmats1[1][6] + coeff0_2*dmats1[2][6] + coeff0_3*dmats1[3][6] + coeff0_4*dmats1[4][6] + coeff0_5*dmats1[5][6] + coeff0_6*dmats1[6][6] + coeff0_7*dmats1[7][6] + coeff0_8*dmats1[8][6] + coeff0_9*dmats1[9][6];
-          new_coeff0_7 = coeff0_0*dmats1[0][7] + coeff0_1*dmats1[1][7] + coeff0_2*dmats1[2][7] + coeff0_3*dmats1[3][7] + coeff0_4*dmats1[4][7] + coeff0_5*dmats1[5][7] + coeff0_6*dmats1[6][7] + coeff0_7*dmats1[7][7] + coeff0_8*dmats1[8][7] + coeff0_9*dmats1[9][7];
-          new_coeff0_8 = coeff0_0*dmats1[0][8] + coeff0_1*dmats1[1][8] + coeff0_2*dmats1[2][8] + coeff0_3*dmats1[3][8] + coeff0_4*dmats1[4][8] + coeff0_5*dmats1[5][8] + coeff0_6*dmats1[6][8] + coeff0_7*dmats1[7][8] + coeff0_8*dmats1[8][8] + coeff0_9*dmats1[9][8];
-          new_coeff0_9 = coeff0_0*dmats1[0][9] + coeff0_1*dmats1[1][9] + coeff0_2*dmats1[2][9] + coeff0_3*dmats1[3][9] + coeff0_4*dmats1[4][9] + coeff0_5*dmats1[5][9] + coeff0_6*dmats1[6][9] + coeff0_7*dmats1[7][9] + coeff0_8*dmats1[8][9] + coeff0_9*dmats1[9][9];
-        }
-        if(combinations[deriv_num][j] == 2)
-        {
-          new_coeff0_0 = coeff0_0*dmats2[0][0] + coeff0_1*dmats2[1][0] + coeff0_2*dmats2[2][0] + coeff0_3*dmats2[3][0] + coeff0_4*dmats2[4][0] + coeff0_5*dmats2[5][0] + coeff0_6*dmats2[6][0] + coeff0_7*dmats2[7][0] + coeff0_8*dmats2[8][0] + coeff0_9*dmats2[9][0];
-          new_coeff0_1 = coeff0_0*dmats2[0][1] + coeff0_1*dmats2[1][1] + coeff0_2*dmats2[2][1] + coeff0_3*dmats2[3][1] + coeff0_4*dmats2[4][1] + coeff0_5*dmats2[5][1] + coeff0_6*dmats2[6][1] + coeff0_7*dmats2[7][1] + coeff0_8*dmats2[8][1] + coeff0_9*dmats2[9][1];
-          new_coeff0_2 = coeff0_0*dmats2[0][2] + coeff0_1*dmats2[1][2] + coeff0_2*dmats2[2][2] + coeff0_3*dmats2[3][2] + coeff0_4*dmats2[4][2] + coeff0_5*dmats2[5][2] + coeff0_6*dmats2[6][2] + coeff0_7*dmats2[7][2] + coeff0_8*dmats2[8][2] + coeff0_9*dmats2[9][2];
-          new_coeff0_3 = coeff0_0*dmats2[0][3] + coeff0_1*dmats2[1][3] + coeff0_2*dmats2[2][3] + coeff0_3*dmats2[3][3] + coeff0_4*dmats2[4][3] + coeff0_5*dmats2[5][3] + coeff0_6*dmats2[6][3] + coeff0_7*dmats2[7][3] + coeff0_8*dmats2[8][3] + coeff0_9*dmats2[9][3];
-          new_coeff0_4 = coeff0_0*dmats2[0][4] + coeff0_1*dmats2[1][4] + coeff0_2*dmats2[2][4] + coeff0_3*dmats2[3][4] + coeff0_4*dmats2[4][4] + coeff0_5*dmats2[5][4] + coeff0_6*dmats2[6][4] + coeff0_7*dmats2[7][4] + coeff0_8*dmats2[8][4] + coeff0_9*dmats2[9][4];
-          new_coeff0_5 = coeff0_0*dmats2[0][5] + coeff0_1*dmats2[1][5] + coeff0_2*dmats2[2][5] + coeff0_3*dmats2[3][5] + coeff0_4*dmats2[4][5] + coeff0_5*dmats2[5][5] + coeff0_6*dmats2[6][5] + coeff0_7*dmats2[7][5] + coeff0_8*dmats2[8][5] + coeff0_9*dmats2[9][5];
-          new_coeff0_6 = coeff0_0*dmats2[0][6] + coeff0_1*dmats2[1][6] + coeff0_2*dmats2[2][6] + coeff0_3*dmats2[3][6] + coeff0_4*dmats2[4][6] + coeff0_5*dmats2[5][6] + coeff0_6*dmats2[6][6] + coeff0_7*dmats2[7][6] + coeff0_8*dmats2[8][6] + coeff0_9*dmats2[9][6];
-          new_coeff0_7 = coeff0_0*dmats2[0][7] + coeff0_1*dmats2[1][7] + coeff0_2*dmats2[2][7] + coeff0_3*dmats2[3][7] + coeff0_4*dmats2[4][7] + coeff0_5*dmats2[5][7] + coeff0_6*dmats2[6][7] + coeff0_7*dmats2[7][7] + coeff0_8*dmats2[8][7] + coeff0_9*dmats2[9][7];
-          new_coeff0_8 = coeff0_0*dmats2[0][8] + coeff0_1*dmats2[1][8] + coeff0_2*dmats2[2][8] + coeff0_3*dmats2[3][8] + coeff0_4*dmats2[4][8] + coeff0_5*dmats2[5][8] + coeff0_6*dmats2[6][8] + coeff0_7*dmats2[7][8] + coeff0_8*dmats2[8][8] + coeff0_9*dmats2[9][8];
-          new_coeff0_9 = coeff0_0*dmats2[0][9] + coeff0_1*dmats2[1][9] + coeff0_2*dmats2[2][9] + coeff0_3*dmats2[3][9] + coeff0_4*dmats2[4][9] + coeff0_5*dmats2[5][9] + coeff0_6*dmats2[6][9] + coeff0_7*dmats2[7][9] + coeff0_8*dmats2[8][9] + coeff0_9*dmats2[9][9];
-        }
-    
-      }
-      // 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 + new_coeff0_6*basisvalue6 + new_coeff0_7*basisvalue7 + new_coeff0_8*basisvalue8 + new_coeff0_9*basisvalue9;
-    }
-    
-    // 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 solitarywave3d_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 solitarywave3d_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[10][1][3] = {{{0, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 0, 1}}, {{0, 0.5, 0.5}}, {{0.5, 0, 0.5}}, {{0.5, 0.5, 0}}, {{0, 0, 0.5}}, {{0, 0.5, 0}}, {{0.5, 0, 0}}};
-    static const double W[10][1] = {{1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}};
-    static const double D[10][1][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] - X[i][0][2];
-    const double w1 = X[i][0][0];
-    const double w2 = X[i][0][1];
-    const double w3 = X[i][0][2];
-    
-    // Compute affine mapping y = F(X)
-    double y[3];
-    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0] + w3*x[3][0];
-    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1] + w3*x[3][1];
-    y[2] = w0*x[0][2] + w1*x[1][2] + w2*x[2][2] + w3*x[3][2];
-    
-    // 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 solitarywave3d_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 solitarywave3d_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];
-    vertex_values[3] = dof_values[3];
-}
-
-/// Return the number of sub elements (for a mixed element)
-unsigned int solitarywave3d_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* solitarywave3d_1_finite_element_1_1::create_sub_element(unsigned int i) const
-{
-    return new solitarywave3d_1_finite_element_1_1();
-}
-
-
-/// Constructor
-solitarywave3d_1_finite_element_1::solitarywave3d_1_finite_element_1() : ufc::finite_element()
-{
-    // Do nothing
-}
-
-/// Destructor
-solitarywave3d_1_finite_element_1::~solitarywave3d_1_finite_element_1()
-{
-    // Do nothing
-}
-
-/// Return a string identifying the finite element
-const char* solitarywave3d_1_finite_element_1::signature() const
-{
-    return "MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) })";
-}
-
-/// Return the cell shape
-ufc::shape solitarywave3d_1_finite_element_1::cell_shape() const
-{
-    return ufc::tetrahedron;
-}
-
-/// Return the dimension of the finite element function space
-unsigned int solitarywave3d_1_finite_element_1::space_dimension() const
-{
-    return 20;
-}
-
-/// Return the rank of the value space
-unsigned int solitarywave3d_1_finite_element_1::value_rank() const
-{
-    return 1;
-}
-
-/// Return the dimension of the value space for axis i
-unsigned int solitarywave3d_1_finite_element_1::value_dimension(unsigned int i) const
-{
-    return 2;
-}
-
-/// Evaluate basis function i at given point in cell
-void solitarywave3d_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_02 = element_coordinates[3][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];
-    const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
-    const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
-    const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
-    const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
-    
-    // Compute sub determinants
-    const double d00 = J_11*J_22 - J_12*J_21;
-    const double d01 = J_12*J_20 - J_10*J_22;
-    const double d02 = J_10*J_21 - J_11*J_20;
-    
-    const double d10 = J_02*J_21 - J_01*J_22;
-    const double d11 = J_00*J_22 - J_02*J_20;
-    const double d12 = J_01*J_20 - J_00*J_21;
-    
-    const double d20 = J_01*J_12 - J_02*J_11;
-    const double d21 = J_02*J_10 - J_00*J_12;
-    const double d22 = J_00*J_11 - J_01*J_10;
-    
-    // Compute determinant of Jacobian
-    double detJ = J_00*d00 + J_10*d10 + J_20*d20;
-    
-    // Compute inverse of Jacobian
-    
-    // Compute constants
-    const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
-                    + d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
-                    + d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
-    
-    const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
-                    + d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
-                    + d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
-    
-    const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
-                    + d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
-                    + d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
-    
-    // Get coordinates and map to the UFC reference element
-    double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
-    double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
-    double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
-    
-    // Map coordinates to the reference cube
-    if (std::abs(y + z - 1.0) < 1e-14)
-      x = 1.0;
-    else
-      x = -2.0 * x/(y + z - 1.0) - 1.0;
-    if (std::abs(z - 1.0) < 1e-14)
-      y = -1.0;
-    else
-      y = 2.0 * y/(1.0 - z) - 1.0;
-    z = 2.0 * z - 1.0;
-    
-    // Reset values
-    values[0] = 0;
-    values[1] = 0;
-    
-    if (0 <= i && i <= 9)
-    {
-      // 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);
-      const double scalings_z_0 = 1;
-      const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
-      const double scalings_z_2 = scalings_z_1*(0.5 - 0.5*z);
-    
-      // 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 psitilde_cs
-      const double psitilde_cs_00_0 = 1;
-      const double psitilde_cs_00_1 = 2*z + 1;
-      const double psitilde_cs_00_2 = 0.3125*psitilde_cs_00_1 + 1.875*z*psitilde_cs_00_1 - 0.5625*psitilde_cs_00_0;
-      const double psitilde_cs_01_0 = 1;
-      const double psitilde_cs_01_1 = 3*z + 2;
-      const double psitilde_cs_02_0 = 1;
-      const double psitilde_cs_10_0 = 1;
-      const double psitilde_cs_10_1 = 3*z + 2;
-      const double psitilde_cs_11_0 = 1;
-      const double psitilde_cs_20_0 = 1;
-    
-      // Compute basisvalues
-      const double basisvalue0 = 0.866025403784439*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
-      const double basisvalue1 = 2.73861278752583*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
-      const double basisvalue2 = 1.58113883008419*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
-      const double basisvalue3 = 1.11803398874989*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
-      const double basisvalue4 = 5.1234753829798*psitilde_a_2*scalings_y_2*psitilde_bs_2_0*scalings_z_2*psitilde_cs_20_0;
-      const double basisvalue5 = 3.96862696659689*psitilde_a_1*scalings_y_1*psitilde_bs_1_1*scalings_z_2*psitilde_cs_11_0;
-      const double basisvalue6 = 2.29128784747792*psitilde_a_0*scalings_y_0*psitilde_bs_0_2*scalings_z_2*psitilde_cs_02_0;
-      const double basisvalue7 = 3.24037034920393*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_1;
-      const double basisvalue8 = 1.87082869338697*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_1;
-      const double basisvalue9 = 1.3228756555323*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_2;
-    
-      // Table(s) of coefficients
-      static const double coefficients0[10][10] =   \
-      {{-0.0577350269189626, -0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, 0.0503952630678969, 0.0290957186981323, 0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
-      {-0.0577350269189625, 0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, -0.050395263067897, 0.0290957186981323, -0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
-      {-0.0577350269189625, 0, 0.0702728368926306, -0.0248451997499977, 0, 0, 0.0872871560943969, 0, -0.0475131096733199, 0.0167984210226323},
-      {-0.0577350269189626, 0, 0, 0.074535599249993, 0, 0, 0, 0, 0, 0.100790526135794},
-      {0.23094010767585, 0, 0.140545673785261, 0.0993807989999906, 0, 0, 0, 0, 0.1187827741833, -0.0671936840905293},
-      {0.230940107675851, 0.121716123890037, -0.0702728368926306, 0.0993807989999907, 0, 0, 0, 0.102868899974728, -0.0593913870916499, -0.0671936840905293},
-      {0.23094010767585, 0.121716123890037, 0.0702728368926307, -0.0993807989999907, 0, 0.100790526135794, -0.087287156094397, -0.0205737799949456, -0.01187827741833, 0.0167984210226323},
-      {0.23094010767585, -0.121716123890037, -0.0702728368926307, 0.0993807989999906, 0, 0, 0, -0.102868899974728, -0.0593913870916499, -0.0671936840905293},
-      {0.23094010767585, -0.121716123890037, 0.0702728368926306, -0.0993807989999906, 0, -0.100790526135794, -0.0872871560943969, 0.0205737799949456, -0.01187827741833, 0.0167984210226323},
-      {0.23094010767585, 0, -0.140545673785261, -0.0993807989999906, -0.130120009726471, 0, 0.0290957186981323, 0, 0.02375655483666, 0.0167984210226323}};
-    
-      // 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];
-      const double coeff0_6 =   coefficients0[dof][6];
-      const double coeff0_7 =   coefficients0[dof][7];
-      const double coeff0_8 =   coefficients0[dof][8];
-      const double coeff0_9 =   coefficients0[dof][9];
-    
-      // Compute value(s)
-      values[0] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5 + coeff0_6*basisvalue6 + coeff0_7*basisvalue7 + coeff0_8*basisvalue8 + coeff0_9*basisvalue9;
-    }
-    
-    if (10 <= i && i <= 19)
-    {
-      // Map degree of freedom to element degree of freedom
-      const unsigned int dof = i - 10;
-    
-      // 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);
-      const double scalings_z_0 = 1;
-      const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
-      const double scalings_z_2 = scalings_z_1*(0.5 - 0.5*z);
-    
-      // 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 psitilde_cs
-      const double psitilde_cs_00_0 = 1;
-      const double psitilde_cs_00_1 = 2*z + 1;
-      const double psitilde_cs_00_2 = 0.3125*psitilde_cs_00_1 + 1.875*z*psitilde_cs_00_1 - 0.5625*psitilde_cs_00_0;
-      const double psitilde_cs_01_0 = 1;
-      const double psitilde_cs_01_1 = 3*z + 2;
-      const double psitilde_cs_02_0 = 1;
-      const double psitilde_cs_10_0 = 1;
-      const double psitilde_cs_10_1 = 3*z + 2;
-      const double psitilde_cs_11_0 = 1;
-      const double psitilde_cs_20_0 = 1;
-    
-      // Compute basisvalues
-      const double basisvalue0 = 0.866025403784439*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
-      const double basisvalue1 = 2.73861278752583*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
-      const double basisvalue2 = 1.58113883008419*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
-      const double basisvalue3 = 1.11803398874989*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
-      const double basisvalue4 = 5.1234753829798*psitilde_a_2*scalings_y_2*psitilde_bs_2_0*scalings_z_2*psitilde_cs_20_0;
-      const double basisvalue5 = 3.96862696659689*psitilde_a_1*scalings_y_1*psitilde_bs_1_1*scalings_z_2*psitilde_cs_11_0;
-      const double basisvalue6 = 2.29128784747792*psitilde_a_0*scalings_y_0*psitilde_bs_0_2*scalings_z_2*psitilde_cs_02_0;
-      const double basisvalue7 = 3.24037034920393*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_1;
-      const double basisvalue8 = 1.87082869338697*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_1;
-      const double basisvalue9 = 1.3228756555323*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_2;
-    
-      // Table(s) of coefficients
-      static const double coefficients0[10][10] =   \
-      {{-0.0577350269189626, -0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, 0.0503952630678969, 0.0290957186981323, 0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
-      {-0.0577350269189625, 0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, -0.050395263067897, 0.0290957186981323, -0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
-      {-0.0577350269189625, 0, 0.0702728368926306, -0.0248451997499977, 0, 0, 0.0872871560943969, 0, -0.0475131096733199, 0.0167984210226323},
-      {-0.0577350269189626, 0, 0, 0.074535599249993, 0, 0, 0, 0, 0, 0.100790526135794},
-      {0.23094010767585, 0, 0.140545673785261, 0.0993807989999906, 0, 0, 0, 0, 0.1187827741833, -0.0671936840905293},
-      {0.230940107675851, 0.121716123890037, -0.0702728368926306, 0.0993807989999907, 0, 0, 0, 0.102868899974728, -0.0593913870916499, -0.0671936840905293},
-      {0.23094010767585, 0.121716123890037, 0.0702728368926307, -0.0993807989999907, 0, 0.100790526135794, -0.087287156094397, -0.0205737799949456, -0.01187827741833, 0.0167984210226323},
-      {0.23094010767585, -0.121716123890037, -0.0702728368926307, 0.0993807989999906, 0, 0, 0, -0.102868899974728, -0.0593913870916499, -0.0671936840905293},
-      {0.23094010767585, -0.121716123890037, 0.0702728368926306, -0.0993807989999906, 0, -0.100790526135794, -0.0872871560943969, 0.0205737799949456, -0.01187827741833, 0.0167984210226323},
-      {0.23094010767585, 0, -0.140545673785261, -0.0993807989999906, -0.130120009726471, 0, 0.0290957186981323, 0, 0.02375655483666, 0.0167984210226323}};
-    
-      // 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];
-      const double coeff0_6 =   coefficients0[dof][6];
-      const double coeff0_7 =   coefficients0[dof][7];
-      const double coeff0_8 =   coefficients0[dof][8];
-      const double coeff0_9 =   coefficients0[dof][9];
-    
-      // Compute value(s)
-      values[1] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5 + coeff0_6*basisvalue6 + coeff0_7*basisvalue7 + coeff0_8*basisvalue8 + coeff0_9*basisvalue9;
-    }
-    
-}
-
-/// Evaluate all basis functions at given point in cell
-void solitarywave3d_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 solitarywave3d_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_02 = element_coordinates[3][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];
-    const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
-    const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
-    const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
-    const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
-    
-    // Compute sub determinants
-    const double d00 = J_11*J_22 - J_12*J_21;
-    const double d01 = J_12*J_20 - J_10*J_22;
-    const double d02 = J_10*J_21 - J_11*J_20;
-    
-    const double d10 = J_02*J_21 - J_01*J_22;
-    const double d11 = J_00*J_22 - J_02*J_20;
-    const double d12 = J_01*J_20 - J_00*J_21;
-    
-    const double d20 = J_01*J_12 - J_02*J_11;
-    const double d21 = J_02*J_10 - J_00*J_12;
-    const double d22 = J_00*J_11 - J_01*J_10;
-    
-    // Compute determinant of Jacobian
-    double detJ = J_00*d00 + J_10*d10 + J_20*d20;
-    
-    // Compute inverse of Jacobian
-    
-    // Compute constants
-    const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
-                    + d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
-                    + d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
-    
-    const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
-                    + d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
-                    + d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
-    
-    const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
-                    + d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
-                    + d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
-    
-    // Get coordinates and map to the UFC reference element
-    double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
-    double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
-    double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
-    
-    // Map coordinates to the reference cube
-    if (std::abs(y + z - 1.0) < 1e-14)
-      x = 1.0;
-    else
-      x = -2.0 * x/(y + z - 1.0) - 1.0;
-    if (std::abs(z - 1.0) < 1e-14)
-      y = -1.0;
-    else
-      y = 2.0 * y/(1.0 - z) - 1.0;
-    z = 2.0 * z - 1.0;
-    
-    // Compute number of derivatives
-    unsigned int num_derivatives = 1;
-    
-    for (unsigned int j = 0; j < n; j++)
-      num_derivatives *= 3;
-    
-    
-    // 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 > 2)
-            combinations[row][col] = 0;
-          else
-          {
-            combinations[row][col] += 1;
-            break;
-          }
-        }
-      }
-    }
-    
-    // Compute inverse of Jacobian
-    const double Jinv[3][3] ={{d00 / detJ, d10 / detJ, d20 / detJ}, {d01 / detJ, d11 / detJ, d21 / detJ}, {d02 / detJ, d12 / detJ, d22 / 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 <= 9)
-    {
-      // 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);
-      const double scalings_z_0 = 1;
-      const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
-      const double scalings_z_2 = scalings_z_1*(0.5 - 0.5*z);
-    
-      // 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 psitilde_cs
-      const double psitilde_cs_00_0 = 1;
-      const double psitilde_cs_00_1 = 2*z + 1;
-      const double psitilde_cs_00_2 = 0.3125*psitilde_cs_00_1 + 1.875*z*psitilde_cs_00_1 - 0.5625*psitilde_cs_00_0;
-      const double psitilde_cs_01_0 = 1;
-      const double psitilde_cs_01_1 = 3*z + 2;
-      const double psitilde_cs_02_0 = 1;
-      const double psitilde_cs_10_0 = 1;
-      const double psitilde_cs_10_1 = 3*z + 2;
-      const double psitilde_cs_11_0 = 1;
-      const double psitilde_cs_20_0 = 1;
-    
-      // Compute basisvalues
-      const double basisvalue0 = 0.866025403784439*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
-      const double basisvalue1 = 2.73861278752583*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
-      const double basisvalue2 = 1.58113883008419*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
-      const double basisvalue3 = 1.11803398874989*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
-      const double basisvalue4 = 5.1234753829798*psitilde_a_2*scalings_y_2*psitilde_bs_2_0*scalings_z_2*psitilde_cs_20_0;
-      const double basisvalue5 = 3.96862696659689*psitilde_a_1*scalings_y_1*psitilde_bs_1_1*scalings_z_2*psitilde_cs_11_0;
-      const double basisvalue6 = 2.29128784747792*psitilde_a_0*scalings_y_0*psitilde_bs_0_2*scalings_z_2*psitilde_cs_02_0;
-      const double basisvalue7 = 3.24037034920393*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_1;
-      const double basisvalue8 = 1.87082869338697*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_1;
-      const double basisvalue9 = 1.3228756555323*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_2;
-    
-      // Table(s) of coefficients
-      static const double coefficients0[10][10] =   \
-      {{-0.0577350269189626, -0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, 0.0503952630678969, 0.0290957186981323, 0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
-      {-0.0577350269189625, 0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, -0.050395263067897, 0.0290957186981323, -0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
-      {-0.0577350269189625, 0, 0.0702728368926306, -0.0248451997499977, 0, 0, 0.0872871560943969, 0, -0.0475131096733199, 0.0167984210226323},
-      {-0.0577350269189626, 0, 0, 0.074535599249993, 0, 0, 0, 0, 0, 0.100790526135794},
-      {0.23094010767585, 0, 0.140545673785261, 0.0993807989999906, 0, 0, 0, 0, 0.1187827741833, -0.0671936840905293},
-      {0.230940107675851, 0.121716123890037, -0.0702728368926306, 0.0993807989999907, 0, 0, 0, 0.102868899974728, -0.0593913870916499, -0.0671936840905293},
-      {0.23094010767585, 0.121716123890037, 0.0702728368926307, -0.0993807989999907, 0, 0.100790526135794, -0.087287156094397, -0.0205737799949456, -0.01187827741833, 0.0167984210226323},
-      {0.23094010767585, -0.121716123890037, -0.0702728368926307, 0.0993807989999906, 0, 0, 0, -0.102868899974728, -0.0593913870916499, -0.0671936840905293},
-      {0.23094010767585, -0.121716123890037, 0.0702728368926306, -0.0993807989999906, 0, -0.100790526135794, -0.0872871560943969, 0.0205737799949456, -0.01187827741833, 0.0167984210226323},
-      {0.23094010767585, 0, -0.140545673785261, -0.0993807989999906, -0.130120009726471, 0, 0.0290957186981323, 0, 0.02375655483666, 0.0167984210226323}};
-    
-      // Interesting (new) part
-      // Tables of derivatives of the polynomial base (transpose)
-      static const double dmats0[10][10] =   \
-      {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-      {6.32455532033676, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-      {0, 11.2249721603218, 0, 0, 0, 0, 0, 0, 0, 0},
-      {4.58257569495584, 0, 8.36660026534076, -1.18321595661992, 0, 0, 0, 0, 0, 0},
-      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-      {3.74165738677394, 0, 0, 8.69482604771366, 0, 0, 0, 0, 0, 0},
-      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
-    
-      static const double dmats1[10][10] =   \
-      {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-      {3.16227766016838, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-      {5.47722557505166, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-      {2.95803989154981, 5.61248608016091, -1.08012344973464, -0.763762615825974, 0, 0, 0, 0, 0, 0},
-      {2.29128784747792, 7.24568837309472, 4.18330013267038, -0.591607978309962, 0, 0, 0, 0, 0, 0},
-      {-2.64575131106459, 0, 9.66091783079296, 0.683130051063974, 0, 0, 0, 0, 0, 0},
-      {1.87082869338697, 0, 0, 4.34741302385683, 0, 0, 0, 0, 0, 0},
-      {3.24037034920393, 0, 0, 7.52994023880668, 0, 0, 0, 0, 0, 0},
-      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
-    
-      static const double dmats2[10][10] =   \
-      {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-      {3.16227766016838, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-      {1.82574185835055, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-      {5.16397779494322, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-      {2.95803989154981, 5.61248608016091, -1.08012344973464, -0.763762615825974, 0, 0, 0, 0, 0, 0},
-      {2.29128784747792, 1.44913767461894, 4.18330013267038, -0.591607978309962, 0, 0, 0, 0, 0, 0},
-      {1.32287565553229, 0, 3.86436713231718, -0.341565025531986, 0, 0, 0, 0, 0, 0},
-      {1.87082869338697, 7.09929573971954, 0, 4.34741302385683, 0, 0, 0, 0, 0, 0},
-      {1.08012344973464, 0, 7.09929573971954, 2.50998007960223, 0, 0, 0, 0, 0, 0},
-      {-3.81881307912987, 0, 0, 8.87411967464942, 0, 0, 0, 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;
-      double coeff0_6 = 0;
-      double coeff0_7 = 0;
-      double coeff0_8 = 0;
-      double coeff0_9 = 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;
-      double new_coeff0_6 = 0;
-      double new_coeff0_7 = 0;
-      double new_coeff0_8 = 0;
-      double new_coeff0_9 = 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];
-        new_coeff0_6 = coefficients0[dof][6];
-        new_coeff0_7 = coefficients0[dof][7];
-        new_coeff0_8 = coefficients0[dof][8];
-        new_coeff0_9 = coefficients0[dof][9];
-    
-        // 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;
-          coeff0_6 = new_coeff0_6;
-          coeff0_7 = new_coeff0_7;
-          coeff0_8 = new_coeff0_8;
-          coeff0_9 = new_coeff0_9;
-    
-          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] + coeff0_6*dmats0[6][0] + coeff0_7*dmats0[7][0] + coeff0_8*dmats0[8][0] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][1] + coeff0_7*dmats0[7][1] + coeff0_8*dmats0[8][1] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][2] + coeff0_7*dmats0[7][2] + coeff0_8*dmats0[8][2] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][3] + coeff0_7*dmats0[7][3] + coeff0_8*dmats0[8][3] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][4] + coeff0_7*dmats0[7][4] + coeff0_8*dmats0[8][4] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][5] + coeff0_7*dmats0[7][5] + coeff0_8*dmats0[8][5] + coeff0_9*dmats0[9][5];
-            new_coeff0_6 = coeff0_0*dmats0[0][6] + coeff0_1*dmats0[1][6] + coeff0_2*dmats0[2][6] + coeff0_3*dmats0[3][6] + coeff0_4*dmats0[4][6] + coeff0_5*dmats0[5][6] + coeff0_6*dmats0[6][6] + coeff0_7*dmats0[7][6] + coeff0_8*dmats0[8][6] + coeff0_9*dmats0[9][6];
-            new_coeff0_7 = coeff0_0*dmats0[0][7] + coeff0_1*dmats0[1][7] + coeff0_2*dmats0[2][7] + coeff0_3*dmats0[3][7] + coeff0_4*dmats0[4][7] + coeff0_5*dmats0[5][7] + coeff0_6*dmats0[6][7] + coeff0_7*dmats0[7][7] + coeff0_8*dmats0[8][7] + coeff0_9*dmats0[9][7];
-            new_coeff0_8 = coeff0_0*dmats0[0][8] + coeff0_1*dmats0[1][8] + coeff0_2*dmats0[2][8] + coeff0_3*dmats0[3][8] + coeff0_4*dmats0[4][8] + coeff0_5*dmats0[5][8] + coeff0_6*dmats0[6][8] + coeff0_7*dmats0[7][8] + coeff0_8*dmats0[8][8] + coeff0_9*dmats0[9][8];
-            new_coeff0_9 = coeff0_0*dmats0[0][9] + coeff0_1*dmats0[1][9] + coeff0_2*dmats0[2][9] + coeff0_3*dmats0[3][9] + coeff0_4*dmats0[4][9] + coeff0_5*dmats0[5][9] + coeff0_6*dmats0[6][9] + coeff0_7*dmats0[7][9] + coeff0_8*dmats0[8][9] + coeff0_9*dmats0[9][9];
-          }
-          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] + coeff0_6*dmats1[6][0] + coeff0_7*dmats1[7][0] + coeff0_8*dmats1[8][0] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][1] + coeff0_7*dmats1[7][1] + coeff0_8*dmats1[8][1] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][2] + coeff0_7*dmats1[7][2] + coeff0_8*dmats1[8][2] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][3] + coeff0_7*dmats1[7][3] + coeff0_8*dmats1[8][3] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][4] + coeff0_7*dmats1[7][4] + coeff0_8*dmats1[8][4] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][5] + coeff0_7*dmats1[7][5] + coeff0_8*dmats1[8][5] + coeff0_9*dmats1[9][5];
-            new_coeff0_6 = coeff0_0*dmats1[0][6] + coeff0_1*dmats1[1][6] + coeff0_2*dmats1[2][6] + coeff0_3*dmats1[3][6] + coeff0_4*dmats1[4][6] + coeff0_5*dmats1[5][6] + coeff0_6*dmats1[6][6] + coeff0_7*dmats1[7][6] + coeff0_8*dmats1[8][6] + coeff0_9*dmats1[9][6];
-            new_coeff0_7 = coeff0_0*dmats1[0][7] + coeff0_1*dmats1[1][7] + coeff0_2*dmats1[2][7] + coeff0_3*dmats1[3][7] + coeff0_4*dmats1[4][7] + coeff0_5*dmats1[5][7] + coeff0_6*dmats1[6][7] + coeff0_7*dmats1[7][7] + coeff0_8*dmats1[8][7] + coeff0_9*dmats1[9][7];
-            new_coeff0_8 = coeff0_0*dmats1[0][8] + coeff0_1*dmats1[1][8] + coeff0_2*dmats1[2][8] + coeff0_3*dmats1[3][8] + coeff0_4*dmats1[4][8] + coeff0_5*dmats1[5][8] + coeff0_6*dmats1[6][8] + coeff0_7*dmats1[7][8] + coeff0_8*dmats1[8][8] + coeff0_9*dmats1[9][8];
-            new_coeff0_9 = coeff0_0*dmats1[0][9] + coeff0_1*dmats1[1][9] + coeff0_2*dmats1[2][9] + coeff0_3*dmats1[3][9] + coeff0_4*dmats1[4][9] + coeff0_5*dmats1[5][9] + coeff0_6*dmats1[6][9] + coeff0_7*dmats1[7][9] + coeff0_8*dmats1[8][9] + coeff0_9*dmats1[9][9];
-          }
-          if(combinations[deriv_num][j] == 2)
-          {
-            new_coeff0_0 = coeff0_0*dmats2[0][0] + coeff0_1*dmats2[1][0] + coeff0_2*dmats2[2][0] + coeff0_3*dmats2[3][0] + coeff0_4*dmats2[4][0] + coeff0_5*dmats2[5][0] + coeff0_6*dmats2[6][0] + coeff0_7*dmats2[7][0] + coeff0_8*dmats2[8][0] + coeff0_9*dmats2[9][0];
-            new_coeff0_1 = coeff0_0*dmats2[0][1] + coeff0_1*dmats2[1][1] + coeff0_2*dmats2[2][1] + coeff0_3*dmats2[3][1] + coeff0_4*dmats2[4][1] + coeff0_5*dmats2[5][1] + coeff0_6*dmats2[6][1] + coeff0_7*dmats2[7][1] + coeff0_8*dmats2[8][1] + coeff0_9*dmats2[9][1];
-            new_coeff0_2 = coeff0_0*dmats2[0][2] + coeff0_1*dmats2[1][2] + coeff0_2*dmats2[2][2] + coeff0_3*dmats2[3][2] + coeff0_4*dmats2[4][2] + coeff0_5*dmats2[5][2] + coeff0_6*dmats2[6][2] + coeff0_7*dmats2[7][2] + coeff0_8*dmats2[8][2] + coeff0_9*dmats2[9][2];
-            new_coeff0_3 = coeff0_0*dmats2[0][3] + coeff0_1*dmats2[1][3] + coeff0_2*dmats2[2][3] + coeff0_3*dmats2[3][3] + coeff0_4*dmats2[4][3] + coeff0_5*dmats2[5][3] + coeff0_6*dmats2[6][3] + coeff0_7*dmats2[7][3] + coeff0_8*dmats2[8][3] + coeff0_9*dmats2[9][3];
-            new_coeff0_4 = coeff0_0*dmats2[0][4] + coeff0_1*dmats2[1][4] + coeff0_2*dmats2[2][4] + coeff0_3*dmats2[3][4] + coeff0_4*dmats2[4][4] + coeff0_5*dmats2[5][4] + coeff0_6*dmats2[6][4] + coeff0_7*dmats2[7][4] + coeff0_8*dmats2[8][4] + coeff0_9*dmats2[9][4];
-            new_coeff0_5 = coeff0_0*dmats2[0][5] + coeff0_1*dmats2[1][5] + coeff0_2*dmats2[2][5] + coeff0_3*dmats2[3][5] + coeff0_4*dmats2[4][5] + coeff0_5*dmats2[5][5] + coeff0_6*dmats2[6][5] + coeff0_7*dmats2[7][5] + coeff0_8*dmats2[8][5] + coeff0_9*dmats2[9][5];
-            new_coeff0_6 = coeff0_0*dmats2[0][6] + coeff0_1*dmats2[1][6] + coeff0_2*dmats2[2][6] + coeff0_3*dmats2[3][6] + coeff0_4*dmats2[4][6] + coeff0_5*dmats2[5][6] + coeff0_6*dmats2[6][6] + coeff0_7*dmats2[7][6] + coeff0_8*dmats2[8][6] + coeff0_9*dmats2[9][6];
-            new_coeff0_7 = coeff0_0*dmats2[0][7] + coeff0_1*dmats2[1][7] + coeff0_2*dmats2[2][7] + coeff0_3*dmats2[3][7] + coeff0_4*dmats2[4][7] + coeff0_5*dmats2[5][7] + coeff0_6*dmats2[6][7] + coeff0_7*dmats2[7][7] + coeff0_8*dmats2[8][7] + coeff0_9*dmats2[9][7];
-            new_coeff0_8 = coeff0_0*dmats2[0][8] + coeff0_1*dmats2[1][8] + coeff0_2*dmats2[2][8] + coeff0_3*dmats2[3][8] + coeff0_4*dmats2[4][8] + coeff0_5*dmats2[5][8] + coeff0_6*dmats2[6][8] + coeff0_7*dmats2[7][8] + coeff0_8*dmats2[8][8] + coeff0_9*dmats2[9][8];
-            new_coeff0_9 = coeff0_0*dmats2[0][9] + coeff0_1*dmats2[1][9] + coeff0_2*dmats2[2][9] + coeff0_3*dmats2[3][9] + coeff0_4*dmats2[4][9] + coeff0_5*dmats2[5][9] + coeff0_6*dmats2[6][9] + coeff0_7*dmats2[7][9] + coeff0_8*dmats2[8][9] + coeff0_9*dmats2[9][9];
-          }
-    
-        }
-        // 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 + new_coeff0_6*basisvalue6 + new_coeff0_7*basisvalue7 + new_coeff0_8*basisvalue8 + new_coeff0_9*basisvalue9;
-      }
-    
-      // 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 (10 <= i && i <= 19)
-    {
-      // Map degree of freedom to element degree of freedom
-      const unsigned int dof = i - 10;
-    
-      // 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);
-      const double scalings_z_0 = 1;
-      const double scalings_z_1 = scalings_z_0*(0.5 - 0.5*z);
-      const double scalings_z_2 = scalings_z_1*(0.5 - 0.5*z);
-    
-      // 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 psitilde_cs
-      const double psitilde_cs_00_0 = 1;
-      const double psitilde_cs_00_1 = 2*z + 1;
-      const double psitilde_cs_00_2 = 0.3125*psitilde_cs_00_1 + 1.875*z*psitilde_cs_00_1 - 0.5625*psitilde_cs_00_0;
-      const double psitilde_cs_01_0 = 1;
-      const double psitilde_cs_01_1 = 3*z + 2;
-      const double psitilde_cs_02_0 = 1;
-      const double psitilde_cs_10_0 = 1;
-      const double psitilde_cs_10_1 = 3*z + 2;
-      const double psitilde_cs_11_0 = 1;
-      const double psitilde_cs_20_0 = 1;
-    
-      // Compute basisvalues
-      const double basisvalue0 = 0.866025403784439*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
-      const double basisvalue1 = 2.73861278752583*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_0;
-      const double basisvalue2 = 1.58113883008419*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_0;
-      const double basisvalue3 = 1.11803398874989*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_1;
-      const double basisvalue4 = 5.1234753829798*psitilde_a_2*scalings_y_2*psitilde_bs_2_0*scalings_z_2*psitilde_cs_20_0;
-      const double basisvalue5 = 3.96862696659689*psitilde_a_1*scalings_y_1*psitilde_bs_1_1*scalings_z_2*psitilde_cs_11_0;
-      const double basisvalue6 = 2.29128784747792*psitilde_a_0*scalings_y_0*psitilde_bs_0_2*scalings_z_2*psitilde_cs_02_0;
-      const double basisvalue7 = 3.24037034920393*psitilde_a_1*scalings_y_1*psitilde_bs_1_0*scalings_z_1*psitilde_cs_10_1;
-      const double basisvalue8 = 1.87082869338697*psitilde_a_0*scalings_y_0*psitilde_bs_0_1*scalings_z_1*psitilde_cs_01_1;
-      const double basisvalue9 = 1.3228756555323*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_2;
-    
-      // Table(s) of coefficients
-      static const double coefficients0[10][10] =   \
-      {{-0.0577350269189626, -0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, 0.0503952630678969, 0.0290957186981323, 0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
-      {-0.0577350269189625, 0.0608580619450185, -0.0351364184463153, -0.0248451997499977, 0.0650600048632355, -0.050395263067897, 0.0290957186981323, -0.0411475599898912, 0.0237565548366599, 0.0167984210226323},
-      {-0.0577350269189625, 0, 0.0702728368926306, -0.0248451997499977, 0, 0, 0.0872871560943969, 0, -0.0475131096733199, 0.0167984210226323},
-      {-0.0577350269189626, 0, 0, 0.074535599249993, 0, 0, 0, 0, 0, 0.100790526135794},
-      {0.23094010767585, 0, 0.140545673785261, 0.0993807989999906, 0, 0, 0, 0, 0.1187827741833, -0.0671936840905293},
-      {0.230940107675851, 0.121716123890037, -0.0702728368926306, 0.0993807989999907, 0, 0, 0, 0.102868899974728, -0.0593913870916499, -0.0671936840905293},
-      {0.23094010767585, 0.121716123890037, 0.0702728368926307, -0.0993807989999907, 0, 0.100790526135794, -0.087287156094397, -0.0205737799949456, -0.01187827741833, 0.0167984210226323},
-      {0.23094010767585, -0.121716123890037, -0.0702728368926307, 0.0993807989999906, 0, 0, 0, -0.102868899974728, -0.0593913870916499, -0.0671936840905293},
-      {0.23094010767585, -0.121716123890037, 0.0702728368926306, -0.0993807989999906, 0, -0.100790526135794, -0.0872871560943969, 0.0205737799949456, -0.01187827741833, 0.0167984210226323},
-      {0.23094010767585, 0, -0.140545673785261, -0.0993807989999906, -0.130120009726471, 0, 0.0290957186981323, 0, 0.02375655483666, 0.0167984210226323}};
-    
-      // Interesting (new) part
-      // Tables of derivatives of the polynomial base (transpose)
-      static const double dmats0[10][10] =   \
-      {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-      {6.32455532033676, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-      {0, 11.2249721603218, 0, 0, 0, 0, 0, 0, 0, 0},
-      {4.58257569495584, 0, 8.36660026534076, -1.18321595661992, 0, 0, 0, 0, 0, 0},
-      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-      {3.74165738677394, 0, 0, 8.69482604771366, 0, 0, 0, 0, 0, 0},
-      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
-    
-      static const double dmats1[10][10] =   \
-      {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-      {3.16227766016838, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-      {5.47722557505166, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-      {2.95803989154981, 5.61248608016091, -1.08012344973464, -0.763762615825974, 0, 0, 0, 0, 0, 0},
-      {2.29128784747792, 7.24568837309472, 4.18330013267038, -0.591607978309962, 0, 0, 0, 0, 0, 0},
-      {-2.64575131106459, 0, 9.66091783079296, 0.683130051063974, 0, 0, 0, 0, 0, 0},
-      {1.87082869338697, 0, 0, 4.34741302385683, 0, 0, 0, 0, 0, 0},
-      {3.24037034920393, 0, 0, 7.52994023880668, 0, 0, 0, 0, 0, 0},
-      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
-    
-      static const double dmats2[10][10] =   \
-      {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-      {3.16227766016838, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-      {1.82574185835055, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-      {5.16397779494322, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-      {2.95803989154981, 5.61248608016091, -1.08012344973464, -0.763762615825974, 0, 0, 0, 0, 0, 0},
-      {2.29128784747792, 1.44913767461894, 4.18330013267038, -0.591607978309962, 0, 0, 0, 0, 0, 0},
-      {1.32287565553229, 0, 3.86436713231718, -0.341565025531986, 0, 0, 0, 0, 0, 0},
-      {1.87082869338697, 7.09929573971954, 0, 4.34741302385683, 0, 0, 0, 0, 0, 0},
-      {1.08012344973464, 0, 7.09929573971954, 2.50998007960223, 0, 0, 0, 0, 0, 0},
-      {-3.81881307912987, 0, 0, 8.87411967464942, 0, 0, 0, 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;
-      double coeff0_6 = 0;
-      double coeff0_7 = 0;
-      double coeff0_8 = 0;
-      double coeff0_9 = 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;
-      double new_coeff0_6 = 0;
-      double new_coeff0_7 = 0;
-      double new_coeff0_8 = 0;
-      double new_coeff0_9 = 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];
-        new_coeff0_6 = coefficients0[dof][6];
-        new_coeff0_7 = coefficients0[dof][7];
-        new_coeff0_8 = coefficients0[dof][8];
-        new_coeff0_9 = coefficients0[dof][9];
-    
-        // 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;
-          coeff0_6 = new_coeff0_6;
-          coeff0_7 = new_coeff0_7;
-          coeff0_8 = new_coeff0_8;
-          coeff0_9 = new_coeff0_9;
-    
-          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] + coeff0_6*dmats0[6][0] + coeff0_7*dmats0[7][0] + coeff0_8*dmats0[8][0] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][1] + coeff0_7*dmats0[7][1] + coeff0_8*dmats0[8][1] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][2] + coeff0_7*dmats0[7][2] + coeff0_8*dmats0[8][2] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][3] + coeff0_7*dmats0[7][3] + coeff0_8*dmats0[8][3] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][4] + coeff0_7*dmats0[7][4] + coeff0_8*dmats0[8][4] + coeff0_9*dmats0[9][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] + coeff0_6*dmats0[6][5] + coeff0_7*dmats0[7][5] + coeff0_8*dmats0[8][5] + coeff0_9*dmats0[9][5];
-            new_coeff0_6 = coeff0_0*dmats0[0][6] + coeff0_1*dmats0[1][6] + coeff0_2*dmats0[2][6] + coeff0_3*dmats0[3][6] + coeff0_4*dmats0[4][6] + coeff0_5*dmats0[5][6] + coeff0_6*dmats0[6][6] + coeff0_7*dmats0[7][6] + coeff0_8*dmats0[8][6] + coeff0_9*dmats0[9][6];
-            new_coeff0_7 = coeff0_0*dmats0[0][7] + coeff0_1*dmats0[1][7] + coeff0_2*dmats0[2][7] + coeff0_3*dmats0[3][7] + coeff0_4*dmats0[4][7] + coeff0_5*dmats0[5][7] + coeff0_6*dmats0[6][7] + coeff0_7*dmats0[7][7] + coeff0_8*dmats0[8][7] + coeff0_9*dmats0[9][7];
-            new_coeff0_8 = coeff0_0*dmats0[0][8] + coeff0_1*dmats0[1][8] + coeff0_2*dmats0[2][8] + coeff0_3*dmats0[3][8] + coeff0_4*dmats0[4][8] + coeff0_5*dmats0[5][8] + coeff0_6*dmats0[6][8] + coeff0_7*dmats0[7][8] + coeff0_8*dmats0[8][8] + coeff0_9*dmats0[9][8];
-            new_coeff0_9 = coeff0_0*dmats0[0][9] + coeff0_1*dmats0[1][9] + coeff0_2*dmats0[2][9] + coeff0_3*dmats0[3][9] + coeff0_4*dmats0[4][9] + coeff0_5*dmats0[5][9] + coeff0_6*dmats0[6][9] + coeff0_7*dmats0[7][9] + coeff0_8*dmats0[8][9] + coeff0_9*dmats0[9][9];
-          }
-          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] + coeff0_6*dmats1[6][0] + coeff0_7*dmats1[7][0] + coeff0_8*dmats1[8][0] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][1] + coeff0_7*dmats1[7][1] + coeff0_8*dmats1[8][1] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][2] + coeff0_7*dmats1[7][2] + coeff0_8*dmats1[8][2] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][3] + coeff0_7*dmats1[7][3] + coeff0_8*dmats1[8][3] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][4] + coeff0_7*dmats1[7][4] + coeff0_8*dmats1[8][4] + coeff0_9*dmats1[9][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] + coeff0_6*dmats1[6][5] + coeff0_7*dmats1[7][5] + coeff0_8*dmats1[8][5] + coeff0_9*dmats1[9][5];
-            new_coeff0_6 = coeff0_0*dmats1[0][6] + coeff0_1*dmats1[1][6] + coeff0_2*dmats1[2][6] + coeff0_3*dmats1[3][6] + coeff0_4*dmats1[4][6] + coeff0_5*dmats1[5][6] + coeff0_6*dmats1[6][6] + coeff0_7*dmats1[7][6] + coeff0_8*dmats1[8][6] + coeff0_9*dmats1[9][6];
-            new_coeff0_7 = coeff0_0*dmats1[0][7] + coeff0_1*dmats1[1][7] + coeff0_2*dmats1[2][7] + coeff0_3*dmats1[3][7] + coeff0_4*dmats1[4][7] + coeff0_5*dmats1[5][7] + coeff0_6*dmats1[6][7] + coeff0_7*dmats1[7][7] + coeff0_8*dmats1[8][7] + coeff0_9*dmats1[9][7];
-            new_coeff0_8 = coeff0_0*dmats1[0][8] + coeff0_1*dmats1[1][8] + coeff0_2*dmats1[2][8] + coeff0_3*dmats1[3][8] + coeff0_4*dmats1[4][8] + coeff0_5*dmats1[5][8] + coeff0_6*dmats1[6][8] + coeff0_7*dmats1[7][8] + coeff0_8*dmats1[8][8] + coeff0_9*dmats1[9][8];
-            new_coeff0_9 = coeff0_0*dmats1[0][9] + coeff0_1*dmats1[1][9] + coeff0_2*dmats1[2][9] + coeff0_3*dmats1[3][9] + coeff0_4*dmats1[4][9] + coeff0_5*dmats1[5][9] + coeff0_6*dmats1[6][9] + coeff0_7*dmats1[7][9] + coeff0_8*dmats1[8][9] + coeff0_9*dmats1[9][9];
-          }
-          if(combinations[deriv_num][j] == 2)
-          {
-            new_coeff0_0 = coeff0_0*dmats2[0][0] + coeff0_1*dmats2[1][0] + coeff0_2*dmats2[2][0] + coeff0_3*dmats2[3][0] + coeff0_4*dmats2[4][0] + coeff0_5*dmats2[5][0] + coeff0_6*dmats2[6][0] + coeff0_7*dmats2[7][0] + coeff0_8*dmats2[8][0] + coeff0_9*dmats2[9][0];
-            new_coeff0_1 = coeff0_0*dmats2[0][1] + coeff0_1*dmats2[1][1] + coeff0_2*dmats2[2][1] + coeff0_3*dmats2[3][1] + coeff0_4*dmats2[4][1] + coeff0_5*dmats2[5][1] + coeff0_6*dmats2[6][1] + coeff0_7*dmats2[7][1] + coeff0_8*dmats2[8][1] + coeff0_9*dmats2[9][1];
-            new_coeff0_2 = coeff0_0*dmats2[0][2] + coeff0_1*dmats2[1][2] + coeff0_2*dmats2[2][2] + coeff0_3*dmats2[3][2] + coeff0_4*dmats2[4][2] + coeff0_5*dmats2[5][2] + coeff0_6*dmats2[6][2] + coeff0_7*dmats2[7][2] + coeff0_8*dmats2[8][2] + coeff0_9*dmats2[9][2];
-            new_coeff0_3 = coeff0_0*dmats2[0][3] + coeff0_1*dmats2[1][3] + coeff0_2*dmats2[2][3] + coeff0_3*dmats2[3][3] + coeff0_4*dmats2[4][3] + coeff0_5*dmats2[5][3] + coeff0_6*dmats2[6][3] + coeff0_7*dmats2[7][3] + coeff0_8*dmats2[8][3] + coeff0_9*dmats2[9][3];
-            new_coeff0_4 = coeff0_0*dmats2[0][4] + coeff0_1*dmats2[1][4] + coeff0_2*dmats2[2][4] + coeff0_3*dmats2[3][4] + coeff0_4*dmats2[4][4] + coeff0_5*dmats2[5][4] + coeff0_6*dmats2[6][4] + coeff0_7*dmats2[7][4] + coeff0_8*dmats2[8][4] + coeff0_9*dmats2[9][4];
-            new_coeff0_5 = coeff0_0*dmats2[0][5] + coeff0_1*dmats2[1][5] + coeff0_2*dmats2[2][5] + coeff0_3*dmats2[3][5] + coeff0_4*dmats2[4][5] + coeff0_5*dmats2[5][5] + coeff0_6*dmats2[6][5] + coeff0_7*dmats2[7][5] + coeff0_8*dmats2[8][5] + coeff0_9*dmats2[9][5];
-            new_coeff0_6 = coeff0_0*dmats2[0][6] + coeff0_1*dmats2[1][6] + coeff0_2*dmats2[2][6] + coeff0_3*dmats2[3][6] + coeff0_4*dmats2[4][6] + coeff0_5*dmats2[5][6] + coeff0_6*dmats2[6][6] + coeff0_7*dmats2[7][6] + coeff0_8*dmats2[8][6] + coeff0_9*dmats2[9][6];
-            new_coeff0_7 = coeff0_0*dmats2[0][7] + coeff0_1*dmats2[1][7] + coeff0_2*dmats2[2][7] + coeff0_3*dmats2[3][7] + coeff0_4*dmats2[4][7] + coeff0_5*dmats2[5][7] + coeff0_6*dmats2[6][7] + coeff0_7*dmats2[7][7] + coeff0_8*dmats2[8][7] + coeff0_9*dmats2[9][7];
-            new_coeff0_8 = coeff0_0*dmats2[0][8] + coeff0_1*dmats2[1][8] + coeff0_2*dmats2[2][8] + coeff0_3*dmats2[3][8] + coeff0_4*dmats2[4][8] + coeff0_5*dmats2[5][8] + coeff0_6*dmats2[6][8] + coeff0_7*dmats2[7][8] + coeff0_8*dmats2[8][8] + coeff0_9*dmats2[9][8];
-            new_coeff0_9 = coeff0_0*dmats2[0][9] + coeff0_1*dmats2[1][9] + coeff0_2*dmats2[2][9] + coeff0_3*dmats2[3][9] + coeff0_4*dmats2[4][9] + coeff0_5*dmats2[5][9] + coeff0_6*dmats2[6][9] + coeff0_7*dmats2[7][9] + coeff0_8*dmats2[8][9] + coeff0_9*dmats2[9][9];
-          }
-    
-        }
-        // 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 + new_coeff0_6*basisvalue6 + new_coeff0_7*basisvalue7 + new_coeff0_8*basisvalue8 + new_coeff0_9*basisvalue9;
-      }
-    
-      // 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 solitarywave3d_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 solitarywave3d_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[20][1][3] = {{{0, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 0, 1}}, {{0, 0.5, 0.5}}, {{0.5, 0, 0.5}}, {{0.5, 0.5, 0}}, {{0, 0, 0.5}}, {{0, 0.5, 0}}, {{0.5, 0, 0}}, {{0, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 0, 1}}, {{0, 0.5, 0.5}}, {{0.5, 0, 0.5}}, {{0.5, 0.5, 0}}, {{0, 0, 0.5}}, {{0, 0.5, 0}}, {{0.5, 0, 0}}};
-    static const double W[20][1] = {{1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}};
-    static const double D[20][1][2] = {{{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{0, 1}}, {{0, 1}}, {{0, 1}}, {{0, 1}}, {{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] - X[i][0][2];
-    const double w1 = X[i][0][0];
-    const double w2 = X[i][0][1];
-    const double w3 = X[i][0][2];
-    
-    // Compute affine mapping y = F(X)
-    double y[3];
-    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0] + w3*x[3][0];
-    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1] + w3*x[3][1];
-    y[2] = w0*x[0][2] + w1*x[1][2] + w2*x[2][2] + w3*x[3][2];
-    
-    // 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 solitarywave3d_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 solitarywave3d_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];
-    vertex_values[6] = dof_values[3];
-    // Evaluate at vertices and use affine mapping
-    vertex_values[1] = dof_values[10];
-    vertex_values[3] = dof_values[11];
-    vertex_values[5] = dof_values[12];
-    vertex_values[7] = dof_values[13];
-}
-
-/// Return the number of sub elements (for a mixed element)
-unsigned int solitarywave3d_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* solitarywave3d_1_finite_element_1::create_sub_element(unsigned int i) const
-{
-    switch ( i )
-    {
-    case 0:
-      return new solitarywave3d_1_finite_element_1_0();
-      break;
-    case 1:
-      return new solitarywave3d_1_finite_element_1_1();
-      break;
-    }
-    return 0;
-}
-
-
-/// Constructor
-solitarywave3d_1_finite_element_2::solitarywave3d_1_finite_element_2() : ufc::finite_element()
-{
-    // Do nothing
-}
-
-/// Destructor
-solitarywave3d_1_finite_element_2::~solitarywave3d_1_finite_element_2()
-{
-    // Do nothing
-}
-
-/// Return a string identifying the finite element
-const char* solitarywave3d_1_finite_element_2::signature() const
-{
-    return "FiniteElement('Discontinuous Lagrange', Cell('tetrahedron', 1, Space(3)), 0)";
-}
-
-/// Return the cell shape
-ufc::shape solitarywave3d_1_finite_element_2::cell_shape() const
-{
-    return ufc::tetrahedron;
-}
-
-/// Return the dimension of the finite element function space
-unsigned int solitarywave3d_1_finite_element_2::space_dimension() const
-{
-    return 1;
-}
-
-/// Return the rank of the value space
-unsigned int solitarywave3d_1_finite_element_2::value_rank() const
-{
-    return 0;
-}
-
-/// Return the dimension of the value space for axis i
-unsigned int solitarywave3d_1_finite_element_2::value_dimension(unsigned int i) const
-{
-    return 1;
-}
-
-/// Evaluate basis function i at given point in cell
-void solitarywave3d_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_02 = element_coordinates[3][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];
-    const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
-    const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
-    const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
-    const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
-    
-    // Compute sub determinants
-    const double d00 = J_11*J_22 - J_12*J_21;
-    const double d01 = J_12*J_20 - J_10*J_22;
-    const double d02 = J_10*J_21 - J_11*J_20;
-    
-    const double d10 = J_02*J_21 - J_01*J_22;
-    const double d11 = J_00*J_22 - J_02*J_20;
-    const double d12 = J_01*J_20 - J_00*J_21;
-    
-    const double d20 = J_01*J_12 - J_02*J_11;
-    const double d21 = J_02*J_10 - J_00*J_12;
-    const double d22 = J_00*J_11 - J_01*J_10;
-    
-    // Compute determinant of Jacobian
-    double detJ = J_00*d00 + J_10*d10 + J_20*d20;
-    
-    // Compute inverse of Jacobian
-    
-    // Compute constants
-    const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
-                    + d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
-                    + d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
-    
-    const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
-                    + d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
-                    + d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
-    
-    const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
-                    + d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
-                    + d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
-    
-    // Get coordinates and map to the UFC reference element
-    double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
-    double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
-    double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
-    
-    // Map coordinates to the reference cube
-    if (std::abs(y + z - 1.0) < 1e-14)
-      x = 1.0;
-    else
-      x = -2.0 * x/(y + z - 1.0) - 1.0;
-    if (std::abs(z - 1.0) < 1e-14)
-      y = -1.0;
-    else
-      y = 2.0 * y/(1.0 - z) - 1.0;
-    z = 2.0 * z - 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_z_0 = 1;
-    
-    // Compute psitilde_a
-    const double psitilde_a_0 = 1;
-    
-    // Compute psitilde_bs
-    const double psitilde_bs_0_0 = 1;
-    
-    // Compute psitilde_cs
-    const double psitilde_cs_00_0 = 1;
-    
-    // Compute basisvalues
-    const double basisvalue0 = 0.866025403784439*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
-    
-    // Table(s) of coefficients
-    static const double coefficients0[1][1] = \
-    {{1.15470053837925}};
-    
-    // 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 solitarywave3d_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 solitarywave3d_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_02 = element_coordinates[3][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];
-    const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
-    const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
-    const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
-    const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
-    
-    // Compute sub determinants
-    const double d00 = J_11*J_22 - J_12*J_21;
-    const double d01 = J_12*J_20 - J_10*J_22;
-    const double d02 = J_10*J_21 - J_11*J_20;
-    
-    const double d10 = J_02*J_21 - J_01*J_22;
-    const double d11 = J_00*J_22 - J_02*J_20;
-    const double d12 = J_01*J_20 - J_00*J_21;
-    
-    const double d20 = J_01*J_12 - J_02*J_11;
-    const double d21 = J_02*J_10 - J_00*J_12;
-    const double d22 = J_00*J_11 - J_01*J_10;
-    
-    // Compute determinant of Jacobian
-    double detJ = J_00*d00 + J_10*d10 + J_20*d20;
-    
-    // Compute inverse of Jacobian
-    
-    // Compute constants
-    const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
-                    + d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
-                    + d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
-    
-    const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
-                    + d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
-                    + d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
-    
-    const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
-                    + d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
-                    + d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
-    
-    // Get coordinates and map to the UFC reference element
-    double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
-    double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
-    double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
-    
-    // Map coordinates to the reference cube
-    if (std::abs(y + z - 1.0) < 1e-14)
-      x = 1.0;
-    else
-      x = -2.0 * x/(y + z - 1.0) - 1.0;
-    if (std::abs(z - 1.0) < 1e-14)
-      y = -1.0;
-    else
-      y = 2.0 * y/(1.0 - z) - 1.0;
-    z = 2.0 * z - 1.0;
-    
-    // Compute number of derivatives
-    unsigned int num_derivatives = 1;
-    
-    for (unsigned int j = 0; j < n; j++)
-      num_derivatives *= 3;
-    
-    
-    // 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 > 2)
-            combinations[row][col] = 0;
-          else
-          {
-            combinations[row][col] += 1;
-            break;
-          }
-        }
-      }
-    }
-    
-    // Compute inverse of Jacobian
-    const double Jinv[3][3] ={{d00 / detJ, d10 / detJ, d20 / detJ}, {d01 / detJ, d11 / detJ, d21 / detJ}, {d02 / detJ, d12 / detJ, d22 / 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_z_0 = 1;
-    
-    // Compute psitilde_a
-    const double psitilde_a_0 = 1;
-    
-    // Compute psitilde_bs
-    const double psitilde_bs_0_0 = 1;
-    
-    // Compute psitilde_cs
-    const double psitilde_cs_00_0 = 1;
-    
-    // Compute basisvalues
-    const double basisvalue0 = 0.866025403784439*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
-    
-    // Table(s) of coefficients
-    static const double coefficients0[1][1] = \
-    {{1.15470053837925}};
-    
-    // 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}};
-    
-    static const double dmats2[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];
-        }
-        if(combinations[deriv_num][j] == 2)
-        {
-          new_coeff0_0 = coeff0_0*dmats2[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 solitarywave3d_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 solitarywave3d_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][3] = {{{0.25, 0.25, 0.25}}};
-    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] - X[i][0][2];
-    const double w1 = X[i][0][0];
-    const double w2 = X[i][0][1];
-    const double w3 = X[i][0][2];
-    
-    // Compute affine mapping y = F(X)
-    double y[3];
-    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0] + w3*x[3][0];
-    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1] + w3*x[3][1];
-    y[2] = w0*x[0][2] + w1*x[1][2] + w2*x[2][2] + w3*x[3][2];
-    
-    // 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 solitarywave3d_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 solitarywave3d_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];
-    vertex_values[3] = dof_values[0];
-}
-
-/// Return the number of sub elements (for a mixed element)
-unsigned int solitarywave3d_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* solitarywave3d_1_finite_element_2::create_sub_element(unsigned int i) const
-{
-    return new solitarywave3d_1_finite_element_2();
-}
-
-
-/// Constructor
-solitarywave3d_1_finite_element_3::solitarywave3d_1_finite_element_3() : ufc::finite_element()
-{
-    // Do nothing
-}
-
-/// Destructor
-solitarywave3d_1_finite_element_3::~solitarywave3d_1_finite_element_3()
-{
-    // Do nothing
-}
-
-/// Return a string identifying the finite element
-const char* solitarywave3d_1_finite_element_3::signature() const
-{
-    return "FiniteElement('Discontinuous Lagrange', Cell('tetrahedron', 1, Space(3)), 0)";
-}
-
-/// Return the cell shape
-ufc::shape solitarywave3d_1_finite_element_3::cell_shape() const
-{
-    return ufc::tetrahedron;
-}
-
-/// Return the dimension of the finite element function space
-unsigned int solitarywave3d_1_finite_element_3::space_dimension() const
-{
-    return 1;
-}
-
-/// Return the rank of the value space
-unsigned int solitarywave3d_1_finite_element_3::value_rank() const
-{
-    return 0;
-}
-
-/// Return the dimension of the value space for axis i
-unsigned int solitarywave3d_1_finite_element_3::value_dimension(unsigned int i) const
-{
-    return 1;
-}
-
-/// Evaluate basis function i at given point in cell
-void solitarywave3d_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_02 = element_coordinates[3][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];
-    const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
-    const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
-    const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
-    const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
-    
-    // Compute sub determinants
-    const double d00 = J_11*J_22 - J_12*J_21;
-    const double d01 = J_12*J_20 - J_10*J_22;
-    const double d02 = J_10*J_21 - J_11*J_20;
-    
-    const double d10 = J_02*J_21 - J_01*J_22;
-    const double d11 = J_00*J_22 - J_02*J_20;
-    const double d12 = J_01*J_20 - J_00*J_21;
-    
-    const double d20 = J_01*J_12 - J_02*J_11;
-    const double d21 = J_02*J_10 - J_00*J_12;
-    const double d22 = J_00*J_11 - J_01*J_10;
-    
-    // Compute determinant of Jacobian
-    double detJ = J_00*d00 + J_10*d10 + J_20*d20;
-    
-    // Compute inverse of Jacobian
-    
-    // Compute constants
-    const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
-                    + d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
-                    + d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
-    
-    const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
-                    + d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
-                    + d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
-    
-    const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
-                    + d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
-                    + d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
-    
-    // Get coordinates and map to the UFC reference element
-    double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
-    double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
-    double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
-    
-    // Map coordinates to the reference cube
-    if (std::abs(y + z - 1.0) < 1e-14)
-      x = 1.0;
-    else
-      x = -2.0 * x/(y + z - 1.0) - 1.0;
-    if (std::abs(z - 1.0) < 1e-14)
-      y = -1.0;
-    else
-      y = 2.0 * y/(1.0 - z) - 1.0;
-    z = 2.0 * z - 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_z_0 = 1;
-    
-    // Compute psitilde_a
-    const double psitilde_a_0 = 1;
-    
-    // Compute psitilde_bs
-    const double psitilde_bs_0_0 = 1;
-    
-    // Compute psitilde_cs
-    const double psitilde_cs_00_0 = 1;
-    
-    // Compute basisvalues
-    const double basisvalue0 = 0.866025403784439*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
-    
-    // Table(s) of coefficients
-    static const double coefficients0[1][1] = \
-    {{1.15470053837925}};
-    
-    // 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 solitarywave3d_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 solitarywave3d_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_02 = element_coordinates[3][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];
-    const double J_12 = element_coordinates[3][1] - element_coordinates[0][1];
-    const double J_20 = element_coordinates[1][2] - element_coordinates[0][2];
-    const double J_21 = element_coordinates[2][2] - element_coordinates[0][2];
-    const double J_22 = element_coordinates[3][2] - element_coordinates[0][2];
-    
-    // Compute sub determinants
-    const double d00 = J_11*J_22 - J_12*J_21;
-    const double d01 = J_12*J_20 - J_10*J_22;
-    const double d02 = J_10*J_21 - J_11*J_20;
-    
-    const double d10 = J_02*J_21 - J_01*J_22;
-    const double d11 = J_00*J_22 - J_02*J_20;
-    const double d12 = J_01*J_20 - J_00*J_21;
-    
-    const double d20 = J_01*J_12 - J_02*J_11;
-    const double d21 = J_02*J_10 - J_00*J_12;
-    const double d22 = J_00*J_11 - J_01*J_10;
-    
-    // Compute determinant of Jacobian
-    double detJ = J_00*d00 + J_10*d10 + J_20*d20;
-    
-    // Compute inverse of Jacobian
-    
-    // Compute constants
-    const double C0 = d00*(element_coordinates[0][0] - element_coordinates[2][0] - element_coordinates[3][0]) \
-                    + d10*(element_coordinates[0][1] - element_coordinates[2][1] - element_coordinates[3][1]) \
-                    + d20*(element_coordinates[0][2] - element_coordinates[2][2] - element_coordinates[3][2]);
-    
-    const double C1 = d01*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[3][0]) \
-                    + d11*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[3][1]) \
-                    + d21*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[3][2]);
-    
-    const double C2 = d02*(element_coordinates[0][0] - element_coordinates[1][0] - element_coordinates[2][0]) \
-                    + d12*(element_coordinates[0][1] - element_coordinates[1][1] - element_coordinates[2][1]) \
-                    + d22*(element_coordinates[0][2] - element_coordinates[1][2] - element_coordinates[2][2]);
-    
-    // Get coordinates and map to the UFC reference element
-    double x = (C0 + d00*coordinates[0] + d10*coordinates[1] + d20*coordinates[2]) / detJ;
-    double y = (C1 + d01*coordinates[0] + d11*coordinates[1] + d21*coordinates[2]) / detJ;
-    double z = (C2 + d02*coordinates[0] + d12*coordinates[1] + d22*coordinates[2]) / detJ;
-    
-    // Map coordinates to the reference cube
-    if (std::abs(y + z - 1.0) < 1e-14)
-      x = 1.0;
-    else
-      x = -2.0 * x/(y + z - 1.0) - 1.0;
-    if (std::abs(z - 1.0) < 1e-14)
-      y = -1.0;
-    else
-      y = 2.0 * y/(1.0 - z) - 1.0;
-    z = 2.0 * z - 1.0;
-    
-    // Compute number of derivatives
-    unsigned int num_derivatives = 1;
-    
-    for (unsigned int j = 0; j < n; j++)
-      num_derivatives *= 3;
-    
-    
-    // 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 > 2)
-            combinations[row][col] = 0;
-          else
-          {
-            combinations[row][col] += 1;
-            break;
-          }
-        }
-      }
-    }
-    
-    // Compute inverse of Jacobian
-    const double Jinv[3][3] ={{d00 / detJ, d10 / detJ, d20 / detJ}, {d01 / detJ, d11 / detJ, d21 / detJ}, {d02 / detJ, d12 / detJ, d22 / 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_z_0 = 1;
-    
-    // Compute psitilde_a
-    const double psitilde_a_0 = 1;
-    
-    // Compute psitilde_bs
-    const double psitilde_bs_0_0 = 1;
-    
-    // Compute psitilde_cs
-    const double psitilde_cs_00_0 = 1;
-    
-    // Compute basisvalues
-    const double basisvalue0 = 0.866025403784439*psitilde_a_0*scalings_y_0*psitilde_bs_0_0*scalings_z_0*psitilde_cs_00_0;
-    
-    // Table(s) of coefficients
-    static const double coefficients0[1][1] = \
-    {{1.15470053837925}};
-    
-    // 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}};
-    
-    static const double dmats2[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];
-        }
-        if(combinations[deriv_num][j] == 2)
-        {
-          new_coeff0_0 = coeff0_0*dmats2[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 solitarywave3d_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 solitarywave3d_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][3] = {{{0.25, 0.25, 0.25}}};
-    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] - X[i][0][2];
-    const double w1 = X[i][0][0];
-    const double w2 = X[i][0][1];
-    const double w3 = X[i][0][2];
-    
-    // Compute affine mapping y = F(X)
-    double y[3];
-    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0] + w3*x[3][0];
-    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1] + w3*x[3][1];
-    y[2] = w0*x[0][2] + w1*x[1][2] + w2*x[2][2] + w3*x[3][2];
-    
-    // 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 solitarywave3d_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 solitarywave3d_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];
-    vertex_values[3] = dof_values[0];
-}
-
-/// Return the number of sub elements (for a mixed element)
-unsigned int solitarywave3d_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* solitarywave3d_1_finite_element_3::create_sub_element(unsigned int i) const
-{
-    return new solitarywave3d_1_finite_element_3();
-}
-
-/// Constructor
-solitarywave3d_1_dof_map_0_0::solitarywave3d_1_dof_map_0_0() : ufc::dof_map()
-{
-    __global_dimension = 0;
-}
-
-/// Destructor
-solitarywave3d_1_dof_map_0_0::~solitarywave3d_1_dof_map_0_0()
-{
-    // Do nothing
-}
-
-/// Return a string identifying the dof map
-const char* solitarywave3d_1_dof_map_0_0::signature() const
-{
-    return "FFC dof map for FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)";
-}
-
-/// Return true iff mesh entities of topological dimension d are needed
-bool solitarywave3d_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;
-    case 3:
-      return false;
-      break;
-    }
-    return false;
-}
-
-/// Initialize dof map for mesh (return true iff init_cell() is needed)
-bool solitarywave3d_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 solitarywave3d_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 solitarywave3d_1_dof_map_0_0::init_cell_finalize()
-{
-    // Do nothing
-}
-
-/// Return the dimension of the global finite element function space
-unsigned int solitarywave3d_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 solitarywave3d_1_dof_map_0_0::local_dimension(const ufc::cell& c) const
-{
-    return 10;
-}
-
-/// Return the maximum dimension of the local finite element function space
-unsigned int solitarywave3d_1_dof_map_0_0::max_local_dimension() const
-{
-    return 10;
-}
-
-// Return the geometric dimension of the coordinates this dof map provides
-unsigned int solitarywave3d_1_dof_map_0_0::geometric_dimension() const
-{
-    return 3;
-}
-
-/// Return the number of dofs on each cell facet
-unsigned int solitarywave3d_1_dof_map_0_0::num_facet_dofs() const
-{
-    return 6;
-}
-
-/// Return the number of dofs associated with each cell entity of dimension d
-unsigned int solitarywave3d_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 solitarywave3d_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];
-    dofs[3] = c.entity_indices[0][3];
-    unsigned int offset = m.num_entities[0];
-    dofs[4] = offset + c.entity_indices[1][0];
-    dofs[5] = offset + c.entity_indices[1][1];
-    dofs[6] = offset + c.entity_indices[1][2];
-    dofs[7] = offset + c.entity_indices[1][3];
-    dofs[8] = offset + c.entity_indices[1][4];
-    dofs[9] = offset + c.entity_indices[1][5];
-}
-
-/// Tabulate the local-to-local mapping from facet dofs to cell dofs
-void solitarywave3d_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;
-      dofs[3] = 4;
-      dofs[4] = 5;
-      dofs[5] = 6;
-      break;
-    case 1:
-      dofs[0] = 0;
-      dofs[1] = 2;
-      dofs[2] = 3;
-      dofs[3] = 4;
-      dofs[4] = 7;
-      dofs[5] = 8;
-      break;
-    case 2:
-      dofs[0] = 0;
-      dofs[1] = 1;
-      dofs[2] = 3;
-      dofs[3] = 5;
-      dofs[4] = 7;
-      dofs[5] = 9;
-      break;
-    case 3:
-      dofs[0] = 0;
-      dofs[1] = 1;
-      dofs[2] = 2;
-      dofs[3] = 6;
-      dofs[4] = 8;
-      dofs[5] = 9;
-      break;
-    }
-}
-
-/// Tabulate the local-to-local mapping of dofs on entity (d, i)
-void solitarywave3d_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 solitarywave3d_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[0][2] = x[0][2];
-    coordinates[1][0] = x[1][0];
-    coordinates[1][1] = x[1][1];
-    coordinates[1][2] = x[1][2];
-    coordinates[2][0] = x[2][0];
-    coordinates[2][1] = x[2][1];
-    coordinates[2][2] = x[2][2];
-    coordinates[3][0] = x[3][0];
-    coordinates[3][1] = x[3][1];
-    coordinates[3][2] = x[3][2];
-    coordinates[4][0] = 0.5*x[2][0] + 0.5*x[3][0];
-    coordinates[4][1] = 0.5*x[2][1] + 0.5*x[3][1];
-    coordinates[4][2] = 0.5*x[2][2] + 0.5*x[3][2];
-    coordinates[5][0] = 0.5*x[1][0] + 0.5*x[3][0];
-    coordinates[5][1] = 0.5*x[1][1] + 0.5*x[3][1];
-    coordinates[5][2] = 0.5*x[1][2] + 0.5*x[3][2];
-    coordinates[6][0] = 0.5*x[1][0] + 0.5*x[2][0];
-    coordinates[6][1] = 0.5*x[1][1] + 0.5*x[2][1];
-    coordinates[6][2] = 0.5*x[1][2] + 0.5*x[2][2];
-    coordinates[7][0] = 0.5*x[0][0] + 0.5*x[3][0];
-    coordinates[7][1] = 0.5*x[0][1] + 0.5*x[3][1];
-    coordinates[7][2] = 0.5*x[0][2] + 0.5*x[3][2];
-    coordinates[8][0] = 0.5*x[0][0] + 0.5*x[2][0];
-    coordinates[8][1] = 0.5*x[0][1] + 0.5*x[2][1];
-    coordinates[8][2] = 0.5*x[0][2] + 0.5*x[2][2];
-    coordinates[9][0] = 0.5*x[0][0] + 0.5*x[1][0];
-    coordinates[9][1] = 0.5*x[0][1] + 0.5*x[1][1];
-    coordinates[9][2] = 0.5*x[0][2] + 0.5*x[1][2];
-}
-
-/// Return the number of sub dof maps (for a mixed element)
-unsigned int solitarywave3d_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* solitarywave3d_1_dof_map_0_0::create_sub_dof_map(unsigned int i) const
-{
-    return new solitarywave3d_1_dof_map_0_0();
-}
-
-
-/// Constructor
-solitarywave3d_1_dof_map_0_1::solitarywave3d_1_dof_map_0_1() : ufc::dof_map()
-{
-    __global_dimension = 0;
-}
-
-/// Destructor
-solitarywave3d_1_dof_map_0_1::~solitarywave3d_1_dof_map_0_1()
-{
-    // Do nothing
-}
-
-/// Return a string identifying the dof map
-const char* solitarywave3d_1_dof_map_0_1::signature() const
-{
-    return "FFC dof map for FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)";
-}
-
-/// Return true iff mesh entities of topological dimension d are needed
-bool solitarywave3d_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;
-    case 3:
-      return false;
-      break;
-    }
-    return false;
-}
-
-/// Initialize dof map for mesh (return true iff init_cell() is needed)
-bool solitarywave3d_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 solitarywave3d_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 solitarywave3d_1_dof_map_0_1::init_cell_finalize()
-{
-    // Do nothing
-}
-
-/// Return the dimension of the global finite element function space
-unsigned int solitarywave3d_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 solitarywave3d_1_dof_map_0_1::local_dimension(const ufc::cell& c) const
-{
-    return 10;
-}
-
-/// Return the maximum dimension of the local finite element function space
-unsigned int solitarywave3d_1_dof_map_0_1::max_local_dimension() const
-{
-    return 10;
-}
-
-// Return the geometric dimension of the coordinates this dof map provides
-unsigned int solitarywave3d_1_dof_map_0_1::geometric_dimension() const
-{
-    return 3;
-}
-
-/// Return the number of dofs on each cell facet
-unsigned int solitarywave3d_1_dof_map_0_1::num_facet_dofs() const
-{
-    return 6;
-}
-
-/// Return the number of dofs associated with each cell entity of dimension d
-unsigned int solitarywave3d_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 solitarywave3d_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];
-    dofs[3] = c.entity_indices[0][3];
-    unsigned int offset = m.num_entities[0];
-    dofs[4] = offset + c.entity_indices[1][0];
-    dofs[5] = offset + c.entity_indices[1][1];
-    dofs[6] = offset + c.entity_indices[1][2];
-    dofs[7] = offset + c.entity_indices[1][3];
-    dofs[8] = offset + c.entity_indices[1][4];
-    dofs[9] = offset + c.entity_indices[1][5];
-}
-
-/// Tabulate the local-to-local mapping from facet dofs to cell dofs
-void solitarywave3d_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;
-      dofs[3] = 4;
-      dofs[4] = 5;
-      dofs[5] = 6;
-      break;
-    case 1:
-      dofs[0] = 0;
-      dofs[1] = 2;
-      dofs[2] = 3;
-      dofs[3] = 4;
-      dofs[4] = 7;
-      dofs[5] = 8;
-      break;
-    case 2:
-      dofs[0] = 0;
-      dofs[1] = 1;
-      dofs[2] = 3;
-      dofs[3] = 5;
-      dofs[4] = 7;
-      dofs[5] = 9;
-      break;
-    case 3:
-      dofs[0] = 0;
-      dofs[1] = 1;
-      dofs[2] = 2;
-      dofs[3] = 6;
-      dofs[4] = 8;
-      dofs[5] = 9;
-      break;
-    }
-}
-
-/// Tabulate the local-to-local mapping of dofs on entity (d, i)
-void solitarywave3d_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 solitarywave3d_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[0][2] = x[0][2];
-    coordinates[1][0] = x[1][0];
-    coordinates[1][1] = x[1][1];
-    coordinates[1][2] = x[1][2];
-    coordinates[2][0] = x[2][0];
-    coordinates[2][1] = x[2][1];
-    coordinates[2][2] = x[2][2];
-    coordinates[3][0] = x[3][0];
-    coordinates[3][1] = x[3][1];
-    coordinates[3][2] = x[3][2];
-    coordinates[4][0] = 0.5*x[2][0] + 0.5*x[3][0];
-    coordinates[4][1] = 0.5*x[2][1] + 0.5*x[3][1];
-    coordinates[4][2] = 0.5*x[2][2] + 0.5*x[3][2];
-    coordinates[5][0] = 0.5*x[1][0] + 0.5*x[3][0];
-    coordinates[5][1] = 0.5*x[1][1] + 0.5*x[3][1];
-    coordinates[5][2] = 0.5*x[1][2] + 0.5*x[3][2];
-    coordinates[6][0] = 0.5*x[1][0] + 0.5*x[2][0];
-    coordinates[6][1] = 0.5*x[1][1] + 0.5*x[2][1];
-    coordinates[6][2] = 0.5*x[1][2] + 0.5*x[2][2];
-    coordinates[7][0] = 0.5*x[0][0] + 0.5*x[3][0];
-    coordinates[7][1] = 0.5*x[0][1] + 0.5*x[3][1];
-    coordinates[7][2] = 0.5*x[0][2] + 0.5*x[3][2];
-    coordinates[8][0] = 0.5*x[0][0] + 0.5*x[2][0];
-    coordinates[8][1] = 0.5*x[0][1] + 0.5*x[2][1];
-    coordinates[8][2] = 0.5*x[0][2] + 0.5*x[2][2];
-    coordinates[9][0] = 0.5*x[0][0] + 0.5*x[1][0];
-    coordinates[9][1] = 0.5*x[0][1] + 0.5*x[1][1];
-    coordinates[9][2] = 0.5*x[0][2] + 0.5*x[1][2];
-}
-
-/// Return the number of sub dof maps (for a mixed element)
-unsigned int solitarywave3d_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* solitarywave3d_1_dof_map_0_1::create_sub_dof_map(unsigned int i) const
-{
-    return new solitarywave3d_1_dof_map_0_1();
-}
-
-
-/// Constructor
-solitarywave3d_1_dof_map_0::solitarywave3d_1_dof_map_0() : ufc::dof_map()
-{
-    __global_dimension = 0;
-}
-
-/// Destructor
-solitarywave3d_1_dof_map_0::~solitarywave3d_1_dof_map_0()
-{
-    // Do nothing
-}
-
-/// Return a string identifying the dof map
-const char* solitarywave3d_1_dof_map_0::signature() const
-{
-    return "FFC dof map for MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) })";
-}
-
-/// Return true iff mesh entities of topological dimension d are needed
-bool solitarywave3d_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;
-    case 3:
-      return false;
-      break;
-    }
-    return false;
-}
-
-/// Initialize dof map for mesh (return true iff init_cell() is needed)
-bool solitarywave3d_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 solitarywave3d_1_dof_map_0::init_cell(const ufc::mesh& m,
-                              const ufc::cell& c)
-{
-    // Do nothing
-}
-
-/// Finish initialization of dof map for cells
-void solitarywave3d_1_dof_map_0::init_cell_finalize()
-{
-    // Do nothing
-}
-
-/// Return the dimension of the global finite element function space
-unsigned int solitarywave3d_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 solitarywave3d_1_dof_map_0::local_dimension(const ufc::cell& c) const
-{
-    return 20;
-}
-
-/// Return the maximum dimension of the local finite element function space
-unsigned int solitarywave3d_1_dof_map_0::max_local_dimension() const
-{
-    return 20;
-}
-
-// Return the geometric dimension of the coordinates this dof map provides
-unsigned int solitarywave3d_1_dof_map_0::geometric_dimension() const
-{
-    return 3;
-}
-
-/// Return the number of dofs on each cell facet
-unsigned int solitarywave3d_1_dof_map_0::num_facet_dofs() const
-{
-    return 12;
-}
-
-/// Return the number of dofs associated with each cell entity of dimension d
-unsigned int solitarywave3d_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 solitarywave3d_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];
-    dofs[3] = c.entity_indices[0][3];
-    unsigned int offset = m.num_entities[0];
-    dofs[4] = offset + c.entity_indices[1][0];
-    dofs[5] = offset + c.entity_indices[1][1];
-    dofs[6] = offset + c.entity_indices[1][2];
-    dofs[7] = offset + c.entity_indices[1][3];
-    dofs[8] = offset + c.entity_indices[1][4];
-    dofs[9] = offset + c.entity_indices[1][5];
-    offset = offset + m.num_entities[1];
-    dofs[10] = offset + c.entity_indices[0][0];
-    dofs[11] = offset + c.entity_indices[0][1];
-    dofs[12] = offset + c.entity_indices[0][2];
-    dofs[13] = offset + c.entity_indices[0][3];
-    offset = offset + m.num_entities[0];
-    dofs[14] = offset + c.entity_indices[1][0];
-    dofs[15] = offset + c.entity_indices[1][1];
-    dofs[16] = offset + c.entity_indices[1][2];
-    dofs[17] = offset + c.entity_indices[1][3];
-    dofs[18] = offset + c.entity_indices[1][4];
-    dofs[19] = offset + c.entity_indices[1][5];
-}
-
-/// Tabulate the local-to-local mapping from facet dofs to cell dofs
-void solitarywave3d_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] = 4;
-      dofs[4] = 5;
-      dofs[5] = 6;
-      dofs[6] = 11;
-      dofs[7] = 12;
-      dofs[8] = 13;
-      dofs[9] = 14;
-      dofs[10] = 15;
-      dofs[11] = 16;
-      break;
-    case 1:
-      dofs[0] = 0;
-      dofs[1] = 2;
-      dofs[2] = 3;
-      dofs[3] = 4;
-      dofs[4] = 7;
-      dofs[5] = 8;
-      dofs[6] = 10;
-      dofs[7] = 12;
-      dofs[8] = 13;
-      dofs[9] = 14;
-      dofs[10] = 17;
-      dofs[11] = 18;
-      break;
-    case 2:
-      dofs[0] = 0;
-      dofs[1] = 1;
-      dofs[2] = 3;
-      dofs[3] = 5;
-      dofs[4] = 7;
-      dofs[5] = 9;
-      dofs[6] = 10;
-      dofs[7] = 11;
-      dofs[8] = 13;
-      dofs[9] = 15;
-      dofs[10] = 17;
-      dofs[11] = 19;
-      break;
-    case 3:
-      dofs[0] = 0;
-      dofs[1] = 1;
-      dofs[2] = 2;
-      dofs[3] = 6;
-      dofs[4] = 8;
-      dofs[5] = 9;
-      dofs[6] = 10;
-      dofs[7] = 11;
-      dofs[8] = 12;
-      dofs[9] = 16;
-      dofs[10] = 18;
-      dofs[11] = 19;
-      break;
-    }
-}
-
-/// Tabulate the local-to-local mapping of dofs on entity (d, i)
-void solitarywave3d_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 solitarywave3d_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[0][2] = x[0][2];
-    coordinates[1][0] = x[1][0];
-    coordinates[1][1] = x[1][1];
-    coordinates[1][2] = x[1][2];
-    coordinates[2][0] = x[2][0];
-    coordinates[2][1] = x[2][1];
-    coordinates[2][2] = x[2][2];
-    coordinates[3][0] = x[3][0];
-    coordinates[3][1] = x[3][1];
-    coordinates[3][2] = x[3][2];
-    coordinates[4][0] = 0.5*x[2][0] + 0.5*x[3][0];
-    coordinates[4][1] = 0.5*x[2][1] + 0.5*x[3][1];
-    coordinates[4][2] = 0.5*x[2][2] + 0.5*x[3][2];
-    coordinates[5][0] = 0.5*x[1][0] + 0.5*x[3][0];
-    coordinates[5][1] = 0.5*x[1][1] + 0.5*x[3][1];
-    coordinates[5][2] = 0.5*x[1][2] + 0.5*x[3][2];
-    coordinates[6][0] = 0.5*x[1][0] + 0.5*x[2][0];
-    coordinates[6][1] = 0.5*x[1][1] + 0.5*x[2][1];
-    coordinates[6][2] = 0.5*x[1][2] + 0.5*x[2][2];
-    coordinates[7][0] = 0.5*x[0][0] + 0.5*x[3][0];
-    coordinates[7][1] = 0.5*x[0][1] + 0.5*x[3][1];
-    coordinates[7][2] = 0.5*x[0][2] + 0.5*x[3][2];
-    coordinates[8][0] = 0.5*x[0][0] + 0.5*x[2][0];
-    coordinates[8][1] = 0.5*x[0][1] + 0.5*x[2][1];
-    coordinates[8][2] = 0.5*x[0][2] + 0.5*x[2][2];
-    coordinates[9][0] = 0.5*x[0][0] + 0.5*x[1][0];
-    coordinates[9][1] = 0.5*x[0][1] + 0.5*x[1][1];
-    coordinates[9][2] = 0.5*x[0][2] + 0.5*x[1][2];
-    coordinates[10][0] = x[0][0];
-    coordinates[10][1] = x[0][1];
-    coordinates[10][2] = x[0][2];
-    coordinates[11][0] = x[1][0];
-    coordinates[11][1] = x[1][1];
-    coordinates[11][2] = x[1][2];
-    coordinates[12][0] = x[2][0];
-    coordinates[12][1] = x[2][1];
-    coordinates[12][2] = x[2][2];
-    coordinates[13][0] = x[3][0];
-    coordinates[13][1] = x[3][1];
-    coordinates[13][2] = x[3][2];
-    coordinates[14][0] = 0.5*x[2][0] + 0.5*x[3][0];
-    coordinates[14][1] = 0.5*x[2][1] + 0.5*x[3][1];
-    coordinates[14][2] = 0.5*x[2][2] + 0.5*x[3][2];
-    coordinates[15][0] = 0.5*x[1][0] + 0.5*x[3][0];
-    coordinates[15][1] = 0.5*x[1][1] + 0.5*x[3][1];
-    coordinates[15][2] = 0.5*x[1][2] + 0.5*x[3][2];
-    coordinates[16][0] = 0.5*x[1][0] + 0.5*x[2][0];
-    coordinates[16][1] = 0.5*x[1][1] + 0.5*x[2][1];
-    coordinates[16][2] = 0.5*x[1][2] + 0.5*x[2][2];
-    coordinates[17][0] = 0.5*x[0][0] + 0.5*x[3][0];
-    coordinates[17][1] = 0.5*x[0][1] + 0.5*x[3][1];
-    coordinates[17][2] = 0.5*x[0][2] + 0.5*x[3][2];
-    coordinates[18][0] = 0.5*x[0][0] + 0.5*x[2][0];
-    coordinates[18][1] = 0.5*x[0][1] + 0.5*x[2][1];
-    coordinates[18][2] = 0.5*x[0][2] + 0.5*x[2][2];
-    coordinates[19][0] = 0.5*x[0][0] + 0.5*x[1][0];
-    coordinates[19][1] = 0.5*x[0][1] + 0.5*x[1][1];
-    coordinates[19][2] = 0.5*x[0][2] + 0.5*x[1][2];
-}
-
-/// Return the number of sub dof maps (for a mixed element)
-unsigned int solitarywave3d_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* solitarywave3d_1_dof_map_0::create_sub_dof_map(unsigned int i) const
-{
-    switch ( i )
-    {
-    case 0:
-      return new solitarywave3d_1_dof_map_0_0();
-      break;
-    case 1:
-      return new solitarywave3d_1_dof_map_0_1();
-      break;
-    }
-    return 0;
-}
-
-
-/// Constructor
-solitarywave3d_1_dof_map_1_0::solitarywave3d_1_dof_map_1_0() : ufc::dof_map()
-{
-    __global_dimension = 0;
-}
-
-/// Destructor
-solitarywave3d_1_dof_map_1_0::~solitarywave3d_1_dof_map_1_0()
-{
-    // Do nothing
-}
-
-/// Return a string identifying the dof map
-const char* solitarywave3d_1_dof_map_1_0::signature() const
-{
-    return "FFC dof map for FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)";
-}
-
-/// Return true iff mesh entities of topological dimension d are needed
-bool solitarywave3d_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;
-    case 3:
-      return false;
-      break;
-    }
-    return false;
-}
-
-/// Initialize dof map for mesh (return true iff init_cell() is needed)
-bool solitarywave3d_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 solitarywave3d_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 solitarywave3d_1_dof_map_1_0::init_cell_finalize()
-{
-    // Do nothing
-}
-
-/// Return the dimension of the global finite element function space
-unsigned int solitarywave3d_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 solitarywave3d_1_dof_map_1_0::local_dimension(const ufc::cell& c) const
-{
-    return 10;
-}
-
-/// Return the maximum dimension of the local finite element function space
-unsigned int solitarywave3d_1_dof_map_1_0::max_local_dimension() const
-{
-    return 10;
-}
-
-// Return the geometric dimension of the coordinates this dof map provides
-unsigned int solitarywave3d_1_dof_map_1_0::geometric_dimension() const
-{
-    return 3;
-}
-
-/// Return the number of dofs on each cell facet
-unsigned int solitarywave3d_1_dof_map_1_0::num_facet_dofs() const
-{
-    return 6;
-}
-
-/// Return the number of dofs associated with each cell entity of dimension d
-unsigned int solitarywave3d_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 solitarywave3d_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];
-    dofs[3] = c.entity_indices[0][3];
-    unsigned int offset = m.num_entities[0];
-    dofs[4] = offset + c.entity_indices[1][0];
-    dofs[5] = offset + c.entity_indices[1][1];
-    dofs[6] = offset + c.entity_indices[1][2];
-    dofs[7] = offset + c.entity_indices[1][3];
-    dofs[8] = offset + c.entity_indices[1][4];
-    dofs[9] = offset + c.entity_indices[1][5];
-}
-
-/// Tabulate the local-to-local mapping from facet dofs to cell dofs
-void solitarywave3d_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;
-      dofs[3] = 4;
-      dofs[4] = 5;
-      dofs[5] = 6;
-      break;
-    case 1:
-      dofs[0] = 0;
-      dofs[1] = 2;
-      dofs[2] = 3;
-      dofs[3] = 4;
-      dofs[4] = 7;
-      dofs[5] = 8;
-      break;
-    case 2:
-      dofs[0] = 0;
-      dofs[1] = 1;
-      dofs[2] = 3;
-      dofs[3] = 5;
-      dofs[4] = 7;
-      dofs[5] = 9;
-      break;
-    case 3:
-      dofs[0] = 0;
-      dofs[1] = 1;
-      dofs[2] = 2;
-      dofs[3] = 6;
-      dofs[4] = 8;
-      dofs[5] = 9;
-      break;
-    }
-}
-
-/// Tabulate the local-to-local mapping of dofs on entity (d, i)
-void solitarywave3d_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 solitarywave3d_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[0][2] = x[0][2];
-    coordinates[1][0] = x[1][0];
-    coordinates[1][1] = x[1][1];
-    coordinates[1][2] = x[1][2];
-    coordinates[2][0] = x[2][0];
-    coordinates[2][1] = x[2][1];
-    coordinates[2][2] = x[2][2];
-    coordinates[3][0] = x[3][0];
-    coordinates[3][1] = x[3][1];
-    coordinates[3][2] = x[3][2];
-    coordinates[4][0] = 0.5*x[2][0] + 0.5*x[3][0];
-    coordinates[4][1] = 0.5*x[2][1] + 0.5*x[3][1];
-    coordinates[4][2] = 0.5*x[2][2] + 0.5*x[3][2];
-    coordinates[5][0] = 0.5*x[1][0] + 0.5*x[3][0];
-    coordinates[5][1] = 0.5*x[1][1] + 0.5*x[3][1];
-    coordinates[5][2] = 0.5*x[1][2] + 0.5*x[3][2];
-    coordinates[6][0] = 0.5*x[1][0] + 0.5*x[2][0];
-    coordinates[6][1] = 0.5*x[1][1] + 0.5*x[2][1];
-    coordinates[6][2] = 0.5*x[1][2] + 0.5*x[2][2];
-    coordinates[7][0] = 0.5*x[0][0] + 0.5*x[3][0];
-    coordinates[7][1] = 0.5*x[0][1] + 0.5*x[3][1];
-    coordinates[7][2] = 0.5*x[0][2] + 0.5*x[3][2];
-    coordinates[8][0] = 0.5*x[0][0] + 0.5*x[2][0];
-    coordinates[8][1] = 0.5*x[0][1] + 0.5*x[2][1];
-    coordinates[8][2] = 0.5*x[0][2] + 0.5*x[2][2];
-    coordinates[9][0] = 0.5*x[0][0] + 0.5*x[1][0];
-    coordinates[9][1] = 0.5*x[0][1] + 0.5*x[1][1];
-    coordinates[9][2] = 0.5*x[0][2] + 0.5*x[1][2];
-}
-
-/// Return the number of sub dof maps (for a mixed element)
-unsigned int solitarywave3d_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* solitarywave3d_1_dof_map_1_0::create_sub_dof_map(unsigned int i) const
-{
-    return new solitarywave3d_1_dof_map_1_0();
-}
-
-
-/// Constructor
-solitarywave3d_1_dof_map_1_1::solitarywave3d_1_dof_map_1_1() : ufc::dof_map()
-{
-    __global_dimension = 0;
-}
-
-/// Destructor
-solitarywave3d_1_dof_map_1_1::~solitarywave3d_1_dof_map_1_1()
-{
-    // Do nothing
-}
-
-/// Return a string identifying the dof map
-const char* solitarywave3d_1_dof_map_1_1::signature() const
-{
-    return "FFC dof map for FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)";
-}
-
-/// Return true iff mesh entities of topological dimension d are needed
-bool solitarywave3d_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;
-    case 3:
-      return false;
-      break;
-    }
-    return false;
-}
-
-/// Initialize dof map for mesh (return true iff init_cell() is needed)
-bool solitarywave3d_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 solitarywave3d_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 solitarywave3d_1_dof_map_1_1::init_cell_finalize()
-{
-    // Do nothing
-}
-
-/// Return the dimension of the global finite element function space
-unsigned int solitarywave3d_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 solitarywave3d_1_dof_map_1_1::local_dimension(const ufc::cell& c) const
-{
-    return 10;
-}
-
-/// Return the maximum dimension of the local finite element function space
-unsigned int solitarywave3d_1_dof_map_1_1::max_local_dimension() const
-{
-    return 10;
-}
-
-// Return the geometric dimension of the coordinates this dof map provides
-unsigned int solitarywave3d_1_dof_map_1_1::geometric_dimension() const
-{
-    return 3;
-}
-
-/// Return the number of dofs on each cell facet
-unsigned int solitarywave3d_1_dof_map_1_1::num_facet_dofs() const
-{
-    return 6;
-}
-
-/// Return the number of dofs associated with each cell entity of dimension d
-unsigned int solitarywave3d_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 solitarywave3d_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];
-    dofs[3] = c.entity_indices[0][3];
-    unsigned int offset = m.num_entities[0];
-    dofs[4] = offset + c.entity_indices[1][0];
-    dofs[5] = offset + c.entity_indices[1][1];
-    dofs[6] = offset + c.entity_indices[1][2];
-    dofs[7] = offset + c.entity_indices[1][3];
-    dofs[8] = offset + c.entity_indices[1][4];
-    dofs[9] = offset + c.entity_indices[1][5];
-}
-
-/// Tabulate the local-to-local mapping from facet dofs to cell dofs
-void solitarywave3d_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;
-      dofs[3] = 4;
-      dofs[4] = 5;
-      dofs[5] = 6;
-      break;
-    case 1:
-      dofs[0] = 0;
-      dofs[1] = 2;
-      dofs[2] = 3;
-      dofs[3] = 4;
-      dofs[4] = 7;
-      dofs[5] = 8;
-      break;
-    case 2:
-      dofs[0] = 0;
-      dofs[1] = 1;
-      dofs[2] = 3;
-      dofs[3] = 5;
-      dofs[4] = 7;
-      dofs[5] = 9;
-      break;
-    case 3:
-      dofs[0] = 0;
-      dofs[1] = 1;
-      dofs[2] = 2;
-      dofs[3] = 6;
-      dofs[4] = 8;
-      dofs[5] = 9;
-      break;
-    }
-}
-
-/// Tabulate the local-to-local mapping of dofs on entity (d, i)
-void solitarywave3d_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 solitarywave3d_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[0][2] = x[0][2];
-    coordinates[1][0] = x[1][0];
-    coordinates[1][1] = x[1][1];
-    coordinates[1][2] = x[1][2];
-    coordinates[2][0] = x[2][0];
-    coordinates[2][1] = x[2][1];
-    coordinates[2][2] = x[2][2];
-    coordinates[3][0] = x[3][0];
-    coordinates[3][1] = x[3][1];
-    coordinates[3][2] = x[3][2];
-    coordinates[4][0] = 0.5*x[2][0] + 0.5*x[3][0];
-    coordinates[4][1] = 0.5*x[2][1] + 0.5*x[3][1];
-    coordinates[4][2] = 0.5*x[2][2] + 0.5*x[3][2];
-    coordinates[5][0] = 0.5*x[1][0] + 0.5*x[3][0];
-    coordinates[5][1] = 0.5*x[1][1] + 0.5*x[3][1];
-    coordinates[5][2] = 0.5*x[1][2] + 0.5*x[3][2];
-    coordinates[6][0] = 0.5*x[1][0] + 0.5*x[2][0];
-    coordinates[6][1] = 0.5*x[1][1] + 0.5*x[2][1];
-    coordinates[6][2] = 0.5*x[1][2] + 0.5*x[2][2];
-    coordinates[7][0] = 0.5*x[0][0] + 0.5*x[3][0];
-    coordinates[7][1] = 0.5*x[0][1] + 0.5*x[3][1];
-    coordinates[7][2] = 0.5*x[0][2] + 0.5*x[3][2];
-    coordinates[8][0] = 0.5*x[0][0] + 0.5*x[2][0];
-    coordinates[8][1] = 0.5*x[0][1] + 0.5*x[2][1];
-    coordinates[8][2] = 0.5*x[0][2] + 0.5*x[2][2];
-    coordinates[9][0] = 0.5*x[0][0] + 0.5*x[1][0];
-    coordinates[9][1] = 0.5*x[0][1] + 0.5*x[1][1];
-    coordinates[9][2] = 0.5*x[0][2] + 0.5*x[1][2];
-}
-
-/// Return the number of sub dof maps (for a mixed element)
-unsigned int solitarywave3d_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* solitarywave3d_1_dof_map_1_1::create_sub_dof_map(unsigned int i) const
-{
-    return new solitarywave3d_1_dof_map_1_1();
-}
-
-
-/// Constructor
-solitarywave3d_1_dof_map_1::solitarywave3d_1_dof_map_1() : ufc::dof_map()
-{
-    __global_dimension = 0;
-}
-
-/// Destructor
-solitarywave3d_1_dof_map_1::~solitarywave3d_1_dof_map_1()
-{
-    // Do nothing
-}
-
-/// Return a string identifying the dof map
-const char* solitarywave3d_1_dof_map_1::signature() const
-{
-    return "FFC dof map for MixedElement(*[FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2), FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 2)], **{'value_shape': (2,) })";
-}
-
-/// Return true iff mesh entities of topological dimension d are needed
-bool solitarywave3d_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;
-    case 3:
-      return false;
-      break;
-    }
-    return false;
-}
-
-/// Initialize dof map for mesh (return true iff init_cell() is needed)
-bool solitarywave3d_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 solitarywave3d_1_dof_map_1::init_cell(const ufc::mesh& m,
-                              const ufc::cell& c)
-{
-    // Do nothing
-}
-
-/// Finish initialization of dof map for cells
-void solitarywave3d_1_dof_map_1::init_cell_finalize()
-{
-    // Do nothing
-}
-
-/// Return the dimension of the global finite element function space
-unsigned int solitarywave3d_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 solitarywave3d_1_dof_map_1::local_dimension(const ufc::cell& c) const
-{
-    return 20;
-}
-
-/// Return the maximum dimension of the local finite element function space
-unsigned int solitarywave3d_1_dof_map_1::max_local_dimension() const
-{
-    return 20;
-}
-
-// Return the geometric dimension of the coordinates this dof map provides
-unsigned int solitarywave3d_1_dof_map_1::geometric_dimension() const
-{
-    return 3;
-}
-
-/// Return the number of dofs on each cell facet
-unsigned int solitarywave3d_1_dof_map_1::num_facet_dofs() const
-{
-    return 12;
-}
-
-/// Return the number of dofs associated with each cell entity of dimension d
-unsigned int solitarywave3d_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 solitarywave3d_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];
-    dofs[3] = c.entity_indices[0][3];
-    unsigned int offset = m.num_entities[0];
-    dofs[4] = offset + c.entity_indices[1][0];
-    dofs[5] = offset + c.entity_indices[1][1];
-    dofs[6] = offset + c.entity_indices[1][2];
-    dofs[7] = offset + c.entity_indices[1][3];
-    dofs[8] = offset + c.entity_indices[1][4];
-    dofs[9] = offset + c.entity_indices[1][5];
-    offset = offset + m.num_entities[1];
-    dofs[10] = offset + c.entity_indices[0][0];
-    dofs[11] = offset + c.entity_indices[0][1];
-    dofs[12] = offset + c.entity_indices[0][2];
-    dofs[13] = offset + c.entity_indices[0][3];
-    offset = offset + m.num_entities[0];
-    dofs[14] = offset + c.entity_indices[1][0];
-    dofs[15] = offset + c.entity_indices[1][1];
-    dofs[16] = offset + c.entity_indices[1][2];
-    dofs[17] = offset + c.entity_indices[1][3];
-    dofs[18] = offset + c.entity_indices[1][4];
-    dofs[19] = offset + c.entity_indices[1][5];
-}
-
-/// Tabulate the local-to-local mapping from facet dofs to cell dofs
-void solitarywave3d_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] = 4;
-      dofs[4] = 5;
-      dofs[5] = 6;
-      dofs[6] = 11;
-      dofs[7] = 12;
-      dofs[8] = 13;
-      dofs[9] = 14;
-      dofs[10] = 15;
-      dofs[11] = 16;
-      break;
-    case 1:
-      dofs[0] = 0;
-      dofs[1] = 2;
-      dofs[2] = 3;
-      dofs[3] = 4;
-      dofs[4] = 7;
-      dofs[5] = 8;
-      dofs[6] = 10;
-      dofs[7] = 12;
-      dofs[8] = 13;
-      dofs[9] = 14;
-      dofs[10] = 17;
-      dofs[11] = 18;
-      break;
-    case 2:
-      dofs[0] = 0;
-      dofs[1] = 1;
-      dofs[2] = 3;
-      dofs[3] = 5;
-      dofs[4] = 7;
-      dofs[5] = 9;
-      dofs[6] = 10;
-      dofs[7] = 11;
-      dofs[8] = 13;
-      dofs[9] = 15;
-      dofs[10] = 17;
-      dofs[11] = 19;
-      break;
-    case 3:
-      dofs[0] = 0;
-      dofs[1] = 1;
-      dofs[2] = 2;
-      dofs[3] = 6;
-      dofs[4] = 8;
-      dofs[5] = 9;
-      dofs[6] = 10;
-      dofs[7] = 11;
-      dofs[8] = 12;
-      dofs[9] = 16;
-      dofs[10] = 18;
-      dofs[11] = 19;
-      break;
-    }
-}
-
-/// Tabulate the local-to-local mapping of dofs on entity (d, i)
-void solitarywave3d_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 solitarywave3d_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[0][2] = x[0][2];
-    coordinates[1][0] = x[1][0];
-    coordinates[1][1] = x[1][1];
-    coordinates[1][2] = x[1][2];
-    coordinates[2][0] = x[2][0];
-    coordinates[2][1] = x[2][1];
-    coordinates[2][2] = x[2][2];
-    coordinates[3][0] = x[3][0];
-    coordinates[3][1] = x[3][1];
-    coordinates[3][2] = x[3][2];
-    coordinates[4][0] = 0.5*x[2][0] + 0.5*x[3][0];
-    coordinates[4][1] = 0.5*x[2][1] + 0.5*x[3][1];
-    coordinates[4][2] = 0.5*x[2][2] + 0.5*x[3][2];
-    coordinates[5][0] = 0.5*x[1][0] + 0.5*x[3][0];
-    coordinates[5][1] = 0.5*x[1][1] + 0.5*x[3][1];
-    coordinates[5][2] = 0.5*x[1][2] + 0.5*x[3][2];
-    coordinates[6][0] = 0.5*x[1][0] + 0.5*x[2][0];
-    coordinates[6][1] = 0.5*x[1][1] + 0.5*x[2][1];
-    coordinates[6][2] = 0.5*x[1][2] + 0.5*x[2][2];
-    coordinates[7][0] = 0.5*x[0][0] + 0.5*x[3][0];
-    coordinates[7][1] = 0.5*x[0][1] + 0.5*x[3][1];
-    coordinates[7][2] = 0.5*x[0][2] + 0.5*x[3][2];
-    coordinates[8][0] = 0.5*x[0][0] + 0.5*x[2][0];
-    coordinates[8][1] = 0.5*x[0][1] + 0.5*x[2][1];
-    coordinates[8][2] = 0.5*x[0][2] + 0.5*x[2][2];
-    coordinates[9][0] = 0.5*x[0][0] + 0.5*x[1][0];
-    coordinates[9][1] = 0.5*x[0][1] + 0.5*x[1][1];
-    coordinates[9][2] = 0.5*x[0][2] + 0.5*x[1][2];
-    coordinates[10][0] = x[0][0];
-    coordinates[10][1] = x[0][1];
-    coordinates[10][2] = x[0][2];
-    coordinates[11][0] = x[1][0];
-    coordinates[11][1] = x[1][1];
-    coordinates[11][2] = x[1][2];
-    coordinates[12][0] = x[2][0];
-    coordinates[12][1] = x[2][1];
-    coordinates[12][2] = x[2][2];
-    coordinates[13][0] = x[3][0];
-    coordinates[13][1] = x[3][1];
-    coordinates[13][2] = x[3][2];
-    coordinates[14][0] = 0.5*x[2][0] + 0.5*x[3][0];
-    coordinates[14][1] = 0.5*x[2][1] + 0.5*x[3][1];
-    coordinates[14][2] = 0.5*x[2][2] + 0.5*x[3][2];
-    coordinates[15][0] = 0.5*x[1][0] + 0.5*x[3][0];
-    coordinates[15][1] = 0.5*x[1][1] + 0.5*x[3][1];
-    coordinates[15][2] = 0.5*x[1][2] + 0.5*x[3][2];
-    coordinates[16][0] = 0.5*x[1][0] + 0.5*x[2][0];
-    coordinates[16][1] = 0.5*x[1][1] + 0.5*x[2][1];
-    coordinates[16][2] = 0.5*x[1][2] + 0.5*x[2][2];
-    coordinates[17][0] = 0.5*x[0][0] + 0.5*x[3][0];
-    coordinates[17][1] = 0.5*x[0][1] + 0.5*x[3][1];
-    coordinates[17][2] = 0.5*x[0][2] + 0.5*x[3][2];
-    coordinates[18][0] = 0.5*x[0][0] + 0.5*x[2][0];
-    coordinates[18][1] = 0.5*x[0][1] + 0.5*x[2][1];
-    coordinates[18][2] = 0.5*x[0][2] + 0.5*x[2][2];
-    coordinates[19][0] = 0.5*x[0][0] + 0.5*x[1][0];
-    coordinates[19][1] = 0.5*x[0][1] + 0.5*x[1][1];
-    coordinates[19][2] = 0.5*x[0][2] + 0.5*x[1][2];
-}
-
-/// Return the number of sub dof maps (for a mixed element)
-unsigned int solitarywave3d_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* solitarywave3d_1_dof_map_1::create_sub_dof_map(unsigned int i) const
-{
-    switch ( i )
-    {
-    case 0:
-      return new solitarywave3d_1_dof_map_1_0();
-      break;
-    case 1:
-      return new solitarywave3d_1_dof_map_1_1();
-      break;
-    }
-    return 0;
-}
-
-
-/// Constructor
-solitarywave3d_1_dof_map_2::solitarywave3d_1_dof_map_2() : ufc::dof_map()
-{
-    __global_dimension = 0;
-}
-
-/// Destructor
-solitarywave3d_1_dof_map_2::~solitarywave3d_1_dof_map_2()
-{
-    // Do nothing
-}
-
-/// Return a string identifying the dof map
-const char* solitarywave3d_1_dof_map_2::signature() const
-{
-    return "FFC dof map for FiniteElement('Discontinuous Lagrange', Cell('tetrahedron', 1, Space(3)), 0)";
-}
-
-/// Return true iff mesh entities of topological dimension d are needed
-bool solitarywave3d_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 false;
-      break;
-    case 3:
-      return true;
-      break;
-    }
-    return false;
-}
-
-/// Initialize dof map for mesh (return true iff init_cell() is needed)
-bool solitarywave3d_1_dof_map_2::init_mesh(const ufc::mesh& m)
-{
-    __global_dimension = m.num_entities[3];
-    return false;
-}
-
-/// Initialize dof map for given cell
-void solitarywave3d_1_dof_map_2::init_cell(const ufc::mesh& m,
-                              const ufc::cell& c)
-{
-    // Do nothing
-}
-
-/// Finish initialization of dof map for cells
-void solitarywave3d_1_dof_map_2::init_cell_finalize()
-{
-    // Do nothing
-}
-
-/// Return the dimension of the global finite element function space
-unsigned int solitarywave3d_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 solitarywave3d_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 solitarywave3d_1_dof_map_2::max_local_dimension() const
-{
-    return 1;
-}
-
-// Return the geometric dimension of the coordinates this dof map provides
-unsigned int solitarywave3d_1_dof_map_2::geometric_dimension() const
-{
-    return 3;
-}
-
-/// Return the number of dofs on each cell facet
-unsigned int solitarywave3d_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 solitarywave3d_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 solitarywave3d_1_dof_map_2::tabulate_dofs(unsigned int* dofs,
-                                  const ufc::mesh& m,
-                                  const ufc::cell& c) const
-{
-    dofs[0] = c.entity_indices[3][0];
-}
-
-/// Tabulate the local-to-local mapping from facet dofs to cell dofs
-void solitarywave3d_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;
-    case 3:
-      
-      break;
-    }
-}
-
-/// Tabulate the local-to-local mapping of dofs on entity (d, i)
-void solitarywave3d_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 solitarywave3d_1_dof_map_2::tabulate_coordinates(double** coordinates,
-                                         const ufc::cell& c) const
-{
-    const double * const * x = c.coordinates;
-    coordinates[0][0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0] + 0.25*x[3][0];
-    coordinates[0][1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1] + 0.25*x[3][1];
-    coordinates[0][2] = 0.25*x[0][2] + 0.25*x[1][2] + 0.25*x[2][2] + 0.25*x[3][2];
-}
-
-/// Return the number of sub dof maps (for a mixed element)
-unsigned int solitarywave3d_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* solitarywave3d_1_dof_map_2::create_sub_dof_map(unsigned int i) const
-{
-    return new solitarywave3d_1_dof_map_2();
-}
-
-
-/// Constructor
-solitarywave3d_1_dof_map_3::solitarywave3d_1_dof_map_3() : ufc::dof_map()
-{
-    __global_dimension = 0;
-}
-
-/// Destructor
-solitarywave3d_1_dof_map_3::~solitarywave3d_1_dof_map_3()
-{
-    // Do nothing
-}
-
-/// Return a string identifying the dof map
-const char* solitarywave3d_1_dof_map_3::signature() const
-{
-    return "FFC dof map for FiniteElement('Discontinuous Lagrange', Cell('tetrahedron', 1, Space(3)), 0)";
-}
-
-/// Return true iff mesh entities of topological dimension d are needed
-bool solitarywave3d_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 false;
-      break;
-    case 3:
-      return true;
-      break;
-    }
-    return false;
-}
-
-/// Initialize dof map for mesh (return true iff init_cell() is needed)
-bool solitarywave3d_1_dof_map_3::init_mesh(const ufc::mesh& m)
-{
-    __global_dimension = m.num_entities[3];
-    return false;
-}
-
-/// Initialize dof map for given cell
-void solitarywave3d_1_dof_map_3::init_cell(const ufc::mesh& m,
-                              const ufc::cell& c)
-{
-    // Do nothing
-}
-
-/// Finish initialization of dof map for cells
-void solitarywave3d_1_dof_map_3::init_cell_finalize()
-{
-    // Do nothing
-}
-
-/// Return the dimension of the global finite element function space
-unsigned int solitarywave3d_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 solitarywave3d_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 solitarywave3d_1_dof_map_3::max_local_dimension() const
-{
-    return 1;
-}
-
-// Return the geometric dimension of the coordinates this dof map provides
-unsigned int solitarywave3d_1_dof_map_3::geometric_dimension() const
-{
-    return 3;
-}
-
-/// Return the number of dofs on each cell facet
-unsigned int solitarywave3d_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 solitarywave3d_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 solitarywave3d_1_dof_map_3::tabulate_dofs(unsigned int* dofs,
-                                  const ufc::mesh& m,
-                                  const ufc::cell& c) const
-{
-    dofs[0] = c.entity_indices[3][0];
-}
-
-/// Tabulate the local-to-local mapping from facet dofs to cell dofs
-void solitarywave3d_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;
-    case 3:
-      
-      break;
-    }
-}
-
-/// Tabulate the local-to-local mapping of dofs on entity (d, i)
-void solitarywave3d_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 solitarywave3d_1_dof_map_3::tabulate_coordinates(double** coordinates,
-                                         const ufc::cell& c) const
-{
-    const double * const * x = c.coordinates;
-    coordinates[0][0] = 0.25*x[0][0] + 0.25*x[1][0] + 0.25*x[2][0] + 0.25*x[3][0];
-    coordinates[0][1] = 0.25*x[0][1] + 0.25*x[1][1] + 0.25*x[2][1] + 0.25*x[3][1];
-    coordinates[0][2] = 0.25*x[0][2] + 0.25*x[1][2] + 0.25*x[2][2] + 0.25*x[3][2];
-}
-
-/// Return the number of sub dof maps (for a mixed element)
-unsigned int solitarywave3d_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* solitarywave3d_1_dof_map_3::create_sub_dof_map(unsigned int i) const
-{
-    return new solitarywave3d_1_dof_map_3();
-}
-
-
-/// Constructor
-solitarywave3d_1_cell_integral_0_quadrature::solitarywave3d_1_cell_integral_0_quadrature() : ufc::cell_integral()
-{
-    // Do nothing
-}
-
-/// Destructor
-solitarywave3d_1_cell_integral_0_quadrature::~solitarywave3d_1_cell_integral_0_quadrature()
-{
-    // Do nothing
-}
-
-/// Tabulate the tensor for the contribution from a local cell
-void solitarywave3d_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_02 = x[3][0] - x[0][0];
-    const double J_10 = x[1][1] - x[0][1];
-    const double J_11 = x[2][1] - x[0][1];
-    const double J_12 = x[3][1] - x[0][1];
-    const double J_20 = x[1][2] - x[0][2];
-    const double J_21 = x[2][2] - x[0][2];
-    const double J_22 = x[3][2] - x[0][2];
-    
-    // Compute sub determinants
-    const double d_00 = J_11*J_22 - J_12*J_21;
-    const double d_01 = J_12*J_20 - J_10*J_22;
-    const double d_02 = J_10*J_21 - J_11*J_20;
-    
-    const double d_10 = J_02*J_21 - J_01*J_22;
-    const double d_11 = J_00*J_22 - J_02*J_20;
-    const double d_12 = J_01*J_20 - J_00*J_21;
-    
-    const double d_20 = J_01*J_12 - J_02*J_11;
-    const double d_21 = J_02*J_10 - J_00*J_12;
-    const double d_22 = J_00*J_11 - J_01*J_10;
-    
-    // Compute determinant of Jacobian
-    double detJ = J_00*d_00 + J_10*d_10 + J_20*d_20;
-    
-    // Compute inverse of Jacobian
-    const double Jinv_00 = d_00 / detJ;
-    const double Jinv_01 = d_10 / detJ;
-    const double Jinv_02 = d_20 / detJ;
-    const double Jinv_10 = d_01 / detJ;
-    const double Jinv_11 = d_11 / detJ;
-    const double Jinv_12 = d_21 / detJ;
-    const double Jinv_20 = d_02 / detJ;
-    const double Jinv_21 = d_12 / detJ;
-    const double Jinv_22 = d_22 / detJ;
-    
-    // Set scale factor
-    const double det = std::abs(detJ);
-    
-    
-    // Array of quadrature weights
-    static const double W125[125] = {0.000937439821766984, 0.00144688123847004, 0.00102268701578053, 0.000367520038007324, 4.71653365059364e-05, 0.00161927658526931, 0.00249925473264391, 0.00176652740822439, 0.000634831781565251, 8.1470536312884e-05, 0.00141792453255091, 0.00218848010941898, 0.00154686516950305, 0.000555892406098532, 7.13399262170554e-05, 0.000715891501943862, 0.00110493490770459, 0.000780991938624509, 0.000280662785913662, 3.60185932012982e-05, 0.000152536470498617, 0.000235430746830112, 0.000166407554052789, 5.9801395389292e-05, 7.67455552179798e-06, 0.00189377231486028, 0.00292292216383614, 0.00206598473020027, 0.000742446882427904, 9.52812185081393e-05, 0.00327118722298822, 0.00504887813656484, 0.00356865648488397, 0.00128245763045954, 0.000164582987156811, 0.00286442517370845, 0.00442106570107946, 0.00312490504969682, 0.00112298797668544, 0.000144117599953649, 0.00144621070637857, 0.0022321380949974, 0.00157772357985427, 0.000566981902660164, 7.27630862707133e-05, 0.000308147081155878, 0.000475606241660779, 0.000336168798819301, 0.000120807996789371, 1.55037800172006e-05, 0.00225090157446143, 0.00347412941301361, 0.00245558995953753, 0.00088245817276838, 0.000113249435042247, 0.00388807060532275, 0.00600100004508522, 0.00424163688396193, 0.00152430462570915, 0.00019562019257218, 0.0034046010087031, 0.0052547941847441, 0.00371420241029555, 0.00133476204345558, 0.000171295424533231, 0.00171893840164765, 0.00265307667295562, 0.00187525208922536, 0.000673903851785402, 8.64848134932762e-05, 0.000366257730507922, 0.000565296487744311, 0.00039956380849458, 0.000143590075769372, 1.8427496577589e-05, 0.00189377231486028, 0.00292292216383614, 0.00206598473020027, 0.000742446882427904, 9.52812185081393e-05, 0.00327118722298822, 0.00504887813656484, 0.00356865648488397, 0.00128245763045954, 0.000164582987156811, 0.00286442517370845, 0.00442106570107946, 0.00312490504969682, 0.00112298797668544, 0.000144117599953649, 0.00144621070637857, 0.0022321380949974, 0.00157772357985427, 0.000566981902660164, 7.27630862707133e-05, 0.000308147081155878, 0.000475606241660779, 0.000336168798819301, 0.000120807996789371, 1.55037800172006e-05, 0.000937439821766984, 0.00144688123847004, 0.00102268701578053, 0.000367520038007324, 4.71653365059364e-05, 0.00161927658526931, 0.00249925473264391, 0.00176652740822439, 0.000634831781565252, 8.1470536312884e-05, 0.00141792453255091, 0.00218848010941898, 0.00154686516950305, 0.000555892406098532, 7.13399262170554e-05, 0.000715891501943862, 0.00110493490770459, 0.000780991938624509, 0.000280662785913662, 3.60185932012982e-05, 0.000152536470498617, 0.000235430746830112, 0.000166407554052789, 5.9801395389292e-05, 7.67455552179798e-06};
-    // Quadrature points on the UFC reference element: (0.0434850684329929, 0.0384332743963333, 0.034578939918215), (0.0372285899889251, 0.0329036302803046, 0.173480320771696), (0.0274810994988124, 0.0242885357160768, 0.389886387065519), (0.0164705687743685, 0.0145571321830714, 0.634333472630887), (0.0067089045501621, 0.00592951049099777, 0.851054212947016), (0.0363203493206216, 0.191166323793956, 0.034578939918215), (0.0310947054204484, 0.163661986623795, 0.173480320771696), (0.0229532381913956, 0.120810681788372, 0.389886387065519), (0.0137568327003139, 0.0724068788863314, 0.634333472630887), (0.00560352704046152, 0.0294932643722359, 0.851054212947016), (0.025452983470971, 0.42283010559815, 0.034578939918215), (0.0217908978824722, 0.361994799675747, 0.173480320771696), (0.0160854287808059, 0.267214393854326, 0.389886387065519), (0.00964066816216436, 0.160152727938308, 0.634333472630887), (0.00392690279162666, 0.0652345028216781, 0.851054212947016), (0.0137918067694829, 0.671415856030076, 0.034578939918215), (0.0118074902013492, 0.574814908126993, 0.173480320771696), (0.00871595763232119, 0.42431222048264, 0.389886387065519), (0.00522383682733774, 0.254308005746508, 0.634333472630887), (0.00212780888992548, 0.103586473561889, 0.851054212947016), (0.00446245462992895, 0.870293213094632, 0.034578939918215), (0.00382041237943087, 0.745078491721125, 0.173480320771696), (0.00282012111543484, 0.54999601573695, 0.389886387065519), (0.00169021617151183, 0.329635544721039, 0.634333472630887), (0.000688470393412244, 0.134269401146344, 0.851054212947016), (0.213916656125506, 0.0384332743963333, 0.034578939918215), (0.183139081291086, 0.0329036302803046, 0.173480320771696), (0.135188126023001, 0.0242885357160768, 0.389886387065519), (0.0810238806942951, 0.0145571321830714, 0.634333472630887), (0.0330032003938849, 0.00592951049099777, 0.851054212947016), (0.178671161296432, 0.191166323793956, 0.034578939918215), (0.152964584084757, 0.163661986623795, 0.173480320771696), (0.112914159689587, 0.120810681788372, 0.389886387065519), (0.0676741639412116, 0.0724068788863314, 0.634333472630887), (0.027565502601231, 0.0294932643722359, 0.851054212947016), (0.125211188776624, 0.42283010559815, 0.034578939918215), (0.107196244066483, 0.361994799675747, 0.173480320771696), (0.0791292565731431, 0.267214393854326, 0.389886387065519), (0.0474254628170509, 0.160152727938308, 0.634333472630887), (0.0193176633816068, 0.0652345028216781, 0.851054212947016), (0.0678462123292524, 0.671415856030076, 0.034578939918215), (0.0580847383280397, 0.574814908126993, 0.173480320771696), (0.0428765224208113, 0.42431222048264, 0.389886387065519), (0.0256976876550462, 0.254308005746508, 0.634333472630887), (0.0104673576243388, 0.103586473561889, 0.851054212947016), (0.0219522104240708, 0.870293213094632, 0.034578939918215), (0.0187938037280005, 0.745078491721125, 0.173480320771696), (0.0138730580546826, 0.54999601573695, 0.389886387065519), (0.00831470213956798, 0.329635544721039, 0.634333472630887), (0.00338680125632329, 0.134269401146344, 0.851054212947016), (0.463493892842726, 0.0384332743963333, 0.034578939918215), (0.396808024474, 0.0329036302803046, 0.173480320771696), (0.292912538609202, 0.0242885357160768, 0.389886387065519), (0.175554697593021, 0.0145571321830714, 0.634333472630887), (0.0715081382809929, 0.00592951049099777, 0.851054212947016), (0.387127368143914, 0.191166323793956, 0.034578939918215), (0.331428846302255, 0.163661986623795, 0.173480320771696), (0.244651465573054, 0.120810681788372, 0.389886387065519), (0.146629824241391, 0.0724068788863314, 0.634333472630887), (0.0597262613403738, 0.0294932643722359, 0.851054212947016), (0.271295477241817, 0.42283010559815, 0.034578939918215), (0.232262439776279, 0.361994799675747, 0.173480320771696), (0.171449609540077, 0.267214393854326, 0.389886387065519), (0.102756899715403, 0.160152727938308, 0.634333472630887), (0.0418556421156527, 0.0652345028216781, 0.851054212947016), (0.147002602025855, 0.671415856030076, 0.034578939918215), (0.125852385550656, 0.574814908126993, 0.173480320771696), (0.0929006962259202, 0.42431222048264, 0.389886387065519), (0.0556792608113027, 0.254308005746508, 0.634333472630887), (0.0226796567455474, 0.103586473561889, 0.851054212947016), (0.0475639234935763, 0.870293213094632, 0.034578939918215), (0.0407205937535897, 0.745078491721125, 0.173480320771696), (0.0300587985987655, 0.54999601573695, 0.389886387065519), (0.0180154913240372, 0.329635544721039, 0.634333472630887), (0.00733819295331972, 0.134269401146344, 0.851054212947016), (0.713071129559946, 0.0384332743963333, 0.034578939918215), (0.610476967656914, 0.0329036302803046, 0.173480320771696), (0.450636951195403, 0.0242885357160768, 0.389886387065519), (0.270085514491747, 0.0145571321830714, 0.634333472630887), (0.110013076168101, 0.00592951049099777, 0.851054212947016), (0.595583574991397, 0.191166323793956, 0.034578939918215), (0.509893108519752, 0.163661986623795, 0.173480320771696), (0.376388771456521, 0.120810681788372, 0.389886387065519), (0.22558548454157, 0.0724068788863314, 0.634333472630887), (0.0918870200795167, 0.0294932643722359, 0.851054212947016), (0.417379765707011, 0.42283010559815, 0.034578939918215), (0.357328635486074, 0.361994799675747, 0.173480320771696), (0.263769962507011, 0.267214393854326, 0.389886387065519), (0.158088336613754, 0.160152727938308, 0.634333472630887), (0.0643936208496987, 0.0652345028216781, 0.851054212947016), (0.226158991722457, 0.671415856030076, 0.034578939918215), (0.193620032773272, 0.574814908126993, 0.173480320771696), (0.142924870031029, 0.42431222048264, 0.389886387065519), (0.0856608339675592, 0.254308005746508, 0.634333472630887), (0.0348919558667561, 0.103586473561889, 0.851054212947016), (0.0731756365630818, 0.870293213094632, 0.034578939918215), (0.062647383779179, 0.745078491721125, 0.173480320771696), (0.0462445391428484, 0.54999601573695, 0.389886387065519), (0.0277162805085065, 0.329635544721039, 0.634333472630887), (0.0112895846503162, 0.134269401146344, 0.851054212947016), (0.883502717252459, 0.0384332743963333, 0.034578939918215), (0.756387458959075, 0.0329036302803046, 0.173480320771696), (0.558343977719591, 0.0242885357160768, 0.389886387065519), (0.334638826411673, 0.0145571321830714, 0.634333472630887), (0.136307372011824, 0.00592951049099777, 0.851054212947016), (0.737934386967207, 0.191166323793956, 0.034578939918215), (0.631762987184061, 0.163661986623795, 0.173480320771696), (0.466349692954713, 0.120810681788372, 0.389886387065519), (0.279502815782468, 0.0724068788863314, 0.634333472630887), (0.113848995640286, 0.0294932643722359, 0.851054212947016), (0.517137971012664, 0.42283010559815, 0.034578939918215), (0.442733981670085, 0.361994799675747, 0.173480320771696), (0.326813790299348, 0.267214393854326, 0.389886387065519), (0.195873131268641, 0.160152727938308, 0.634333472630887), (0.0797843814396788, 0.0652345028216781, 0.851054212947016), (0.280213397282226, 0.671415856030076, 0.034578939918215), (0.239897280899962, 0.574814908126993, 0.173480320771696), (0.177085434819519, 0.42431222048264, 0.389886387065519), (0.106134684795268, 0.254308005746508, 0.634333472630887), (0.0432315046011695, 0.103586473561889, 0.851054212947016), (0.0906653923572237, 0.870293213094632, 0.034578939918215), (0.0776207751277486, 0.745078491721125, 0.173480320771696), (0.0572974760820962, 0.54999601573695, 0.389886387065519), (0.0343407664765626, 0.329635544721039, 0.634333472630887), (0.0139879155132272, 0.134269401146344, 0.851054212947016)
-    
-    // Value of basis functions at quadrature points.
-    static const double FE1_C0[125][10] = \
-    {{0.677651385532498, -0.0397031660797488, -0.0354790412346856, -0.03218753374648, 0.00531592754484438, 0.00601467027473595, 0.00668509426891429, 0.12220234950981, 0.135823609448279, 0.153676704481833},
-    {0.387856517182057, -0.0344566541637981, -0.0307383325090586, -0.113289477381595, 0.0228325293423221, 0.0258337109326268, 0.00489982304341057, 0.524873356031632, 0.0995515731929938, 0.112636954329409},
-    {0.0651520171918798, -0.0259706778394852, -0.0231086697816145, -0.0858635974275114, 0.0378790777498121, 0.0428580263847204, 0.00266990266677583, 0.870762864851529, 0.0542454305787948, 0.0613756256250992},
-    {-0.110672538127309, -0.015928009502866, -0.0141333119882805, 0.170424436369033, 0.036936304836938, 0.0417913323474042, 0.000959056987115393, 0.849090435339365, 0.0194855265186504, 0.0220467672199497},
-    {-0.0991479726822843, -0.00661888574963566, -0.00585919230167206, 0.597532333802715, 0.0201853395363087, 0.0228385659266996, 0.000159122079653143, 0.464019852825595, 0.00323294396937779, 0.0036578925932431},
-    {0.351159931970128, -0.0336820137710776, -0.118077197088165, -0.03218753374648, 0.026441315299429, 0.0050236767078656, 0.0277729106341423, 0.102067955322095, 0.564272815830671, 0.107208138841391},
-    {0.166485956767395, -0.0291609440100794, -0.1100914948925, -0.113289477381595, 0.113568535750516, 0.0215772778825633, 0.0203560850503691, 0.438393782673502, 0.413582342231706, 0.0785779359281236},
-    {-0.0313856207168029, -0.0218995359044537, -0.0916202401200295, -0.0858635974275114, 0.188409760965562, 0.0357966204395903, 0.0110919854206136, 0.727293587580909, 0.225360097430627, 0.0428169423314949},
-    {-0.123259167721812, -0.013378331808425, -0.0619213666662117, 0.170424436369033, 0.183720427705323, 0.0349056778367692, 0.00398435727676459, 0.709191966981616, 0.080951706122999, 0.0153802939039443},
-    {-0.0879258080236823, -0.00554072800987512, -0.0277535590855747, 0.597532333802715, 0.100401467590206, 0.0190756211805894, 0.000661065217685219, 0.387566669517808, 0.01343111410773, 0.00255182370239899},
-    {0.0177253911135257, -0.0241572747358239, -0.0652595091978644, -0.03218753374648, 0.0584840672683638, 0.0035205487447283, 0.0430491507552746, 0.071528331316298, 0.874646011568391, 0.0526508169135872},
-    {-0.0507072246191906, -0.0208412114214236, -0.0999143296911785, -0.113289477381595, 0.251195895861737, 0.0151211678182184, 0.0315527668548808, 0.307222532626625, 0.641069596017233, 0.0385902839346927},
-    {-0.113199283239695, -0.0155679467426812, -0.124407329288456, -0.0858635974275114, 0.416733018367064, 0.0250859588469928, 0.0171930324062, 0.509680991772005, 0.349317395512301, 0.0210277597937817},
-    {-0.119140564162676, -0.00945478319693843, -0.108854935406145, 0.170424436369033, 0.406360944257666, 0.0244615940551512, 0.00617591722127442, 0.49699553421089, 0.125478465209964, 0.00755339144178017},
-    {-0.0670532863962545, -0.00389606166055687, -0.056723422104895, 0.597532333802715, 0.222072393823573, 0.0133680286585892, 0.00102467820496327, 0.271603335806442, 0.0208187778246103, 0.00125322204081482},
-    {-0.123174301249333, -0.0134113789015495, 0.230182647427123, -0.03218753374648, 0.0928673941832035, 0.00190762423058253, 0.0370401509933353, 0.038757928915604, 0.752558872029367, 0.0154585961181473},
-    {-0.124795870133571, -0.0115286565516393, 0.0860094490830938, -0.113289477381595, 0.398876298584894, 0.00819346875055506, 0.0271484855811957, 0.166469828971132, 0.551586133921709, 0.0113303391742265},
-    {-0.114366932369083, -0.00856402179742438, -0.0642304995808229, -0.0858635974275114, 0.661734234526899, 0.0135929329243276, 0.0147931493464113, 0.276172801534836, 0.300558056253616, 0.00617387658875252},
-    {-0.083605542162086, -0.00516925988494044, -0.124962882172976, 0.170424436369033, 0.645264321612071, 0.0132546182205693, 0.00531385410362168, 0.269299132691067, 0.107963600123275, 0.00221772110036569},
-    {-0.0394935786210076, -0.00211875374858136, -0.082126158551913, 0.597532333802715, 0.35263081891668, 0.00724352288046892, 0.00088164887728405, 0.147169416491454, 0.0179127964336388, 0.000367953519260986},
-    {-0.0742249656146451, -0.00442262762728059, 0.644527340422526, -0.03218753374648, 0.120375266907318, 0.000617227802144495, 0.0155345759126796, 0.0125404526199273, 0.315621902524215, 0.00161836079959531},
-    {-0.0655708056648836, -0.00379122127793308, 0.365205425929728, -0.113289477381595, 0.517025822975488, 0.00265106546025557, 0.0113860283736764, 0.0538627078708379, 0.23133428023363, 0.00118617348079641},
-    {-0.0507314745513395, -0.00280421494922342, 0.0549952189160882, -0.0858635974275114, 0.857743837904439, 0.00439810733113653, 0.00620422150953917, 0.0893580237504861, 0.126053534227744, 0.000646343288641082},
-    {-0.0319821899921671, -0.00168450251009896, -0.112316360033967, 0.170424436369033, 0.836395439141882, 0.0042886427742881, 0.00222862131357039, 0.0871339906075373, 0.0452797490545588, 0.000232173275363283},
-    {-0.0135965919524168, -0.000687522410446964, -0.0982128569779484, 0.597532333802715, 0.457082158061876, 0.00234370251521121, 0.000369762029721776, 0.0476178977115156, 0.00751259615698667, 3.85210627857485e-05},
-    {0.303869742063848, -0.12239598458967, -0.0354790412346856, -0.03218753374648, 0.00531592754484438, 0.0295880447986775, 0.0328860701712706, 0.0986289749858682, 0.109622633545923, 0.610151166460404},
-    {0.134887288422247, -0.1160592350988, -0.0307383325090586, -0.113289477381595, 0.0228325293423221, 0.127084106272845, 0.0241037624827062, 0.423622960691414, 0.0803476337536982, 0.447208764024221},
-    {-0.0444896276300268, -0.0986364671877792, -0.0231086697816145, -0.0858635974275114, 0.0378790777498121, 0.210832040117064, 0.0131340865091965, 0.702788851119186, 0.0437812467363741, 0.2436830597953},
-    {-0.124193144215204, -0.0678941422087684, -0.0141333119882805, 0.170424436369033, 0.036936304836938, 0.205584638427372, 0.004717901365009, 0.685297129259398, 0.0157266821407568, 0.0875335060137464},
-    {-0.0858073223121642, -0.030824777921407, -0.00585919230167206, 0.597532333802715, 0.0201853395363087, 0.112350050943802, 0.000782771291888182, 0.374508367808493, 0.00260929475714278, 0.0145231343948943},
-    {0.113856014607669, -0.114824393538401, -0.118077197088165, -0.03218753374648, 0.026441315299429, 0.0247130374063482, 0.136623636292144, 0.0823785946236127, 0.45542209017267, 0.425654435971174},
-    {0.0100888557121195, -0.106168256116312, -0.1100914948925, -0.113289477381595, 0.113568535750516, 0.106145380454931, 0.100137950857575, 0.353825680101135, 0.333800476424499, 0.311982349089632},
-    {-0.0930517568994226, -0.0874149447727761, -0.0916202401200295, -0.0858635974275114, 0.188409760965562, 0.17609477507965, 0.0545649464626408, 0.58699543294085, 0.1818871363886, 0.169998487382437},
-    {-0.12380786286986, -0.0585145790109275, -0.0619213666662117, 0.170424436369033, 0.183720427705323, 0.171711949680883, 0.0196002999689002, 0.572385695137502, 0.0653357634308634, 0.0610652362544955},
-    {-0.0750005711613296, -0.026045788733914, -0.0277535590855747, 0.597532333802715, 0.100401467590206, 0.0938389484831186, 0.00325198662308666, 0.312803342215279, 0.0108401927023285, 0.0101316475640852},
-    {-0.0689680280637322, -0.0938555051869132, -0.0652595091978644, -0.03218753374648, 0.0584840672683638, 0.0173186806951808, 0.211772240689959, 0.0577301993658455, 0.705922921633706, 0.209042466541935},
-    {-0.101961128009395, -0.084214174582561, -0.0999143296911785, -0.113289477381595, 0.251195895861737, 0.0743857552246981, 0.155217931587356, 0.247957945220146, 0.517404431284758, 0.153217150486034},
-    {-0.124620776265111, -0.0666063780815064, -0.124407329288456, -0.0858635974275114, 0.416733018367064, 0.123405679825933, 0.0845779053253436, 0.411361270793064, 0.281932522593157, 0.0834876841580225},
-    {-0.108104492267147, -0.0429271137702279, -0.108854935406145, 0.170424436369033, 0.406360944257666, 0.120334234079468, 0.03038126897555, 0.401122894186573, 0.101273113455689, 0.0299896501195402},
-    {-0.0561005440374291, -0.0185713191445566, -0.056723422104895, 0.597532333802715, 0.222072393823573, 0.0657615152208353, 0.00504071266550263, 0.219209849244195, 0.0168027433640709, 0.00497573716598929},
-    {-0.12386321264862, -0.0586399952744004, 0.230182647427123, -0.03218753374648, 0.0928673941832035, 0.00938420039924693, 0.182212090917773, 0.0312813527469397, 0.607386932104929, 0.0613761238902858},
-    {-0.118642598591026, -0.051337064674766, 0.0860094490830938, -0.113289477381595, 0.398876298584894, 0.0403062361483535, 0.13355189410245, 0.134357061573334, 0.445182725400454, 0.0449854757548079},
-    {-0.102069833084256, -0.0391997300710066, -0.0642304995808229, -0.0858635974275114, 0.661734234526899, 0.0668678896663356, 0.0727721297397925, 0.222897844792828, 0.242579075860235, 0.0245124855775079},
-    {-0.0709852770155237, -0.0243769453534135, -0.124962882172976, 0.170424436369033, 0.645264321612071, 0.0652036137952374, 0.0261405107994058, 0.217350137116399, 0.0871369434274908, 0.00880514142227651},
-    {-0.0324570586983408, -0.0102482264730672, -0.082126158551913, 0.597532333802715, 0.35263081891668, 0.0356331552184666, 0.00433710665526561, 0.118779784153456, 0.0144573386556573, 0.00146090632108002},
-    {-0.0624662889902574, -0.0209884113390654, 0.644527340422526, -0.03218753374648, 0.120375266907318, 0.00303633666130402, 0.0764194389779763, 0.0101213437607678, 0.254737039458918, 0.00642546788699245},
-    {-0.0547979943904275, -0.0180873896108673, 0.365205425929728, -0.113289477381595, 0.517025822975488, 0.0130414203970155, 0.0560114357414459, 0.043472352934078, 0.18670887286586, 0.00470953053927457},
-    {-0.0419674243417796, -0.0134881345751054, 0.0549952189160882, -0.0858635974275114, 0.857743837904439, 0.0216356659299618, 0.0305205066246512, 0.0721204651516608, 0.101737249112632, 0.00256621270496322},
-    {-0.0261798960980541, -0.00817643359622851, -0.112316360033967, 0.170424436369033, 0.836395439141882, 0.0210971755283347, 0.0109632854758787, 0.0703254578534908, 0.0365450848922505, 0.000921810467379901},
-    {-0.0110346752071629, -0.00336386041082359, -0.0982128569779484, 0.597532333802715, 0.457082158061876, 0.0115294059104329, 0.00181897510595286, 0.0384321943162941, 0.00606338308075562, 0.000152942317908342},
-    {-0.0338407154377174, -0.0338407154377172, -0.0354790412346856, -0.03218753374648, 0.00531592754484438, 0.0641085098922729, 0.0712543518585967, 0.0641085098922728, 0.0712543518585967, 0.859306354810017},
-    {-0.0818948079000829, -0.0818948079000828, -0.0307383325090586, -0.113289477381595, 0.0228325293423221, 0.27535353348213, 0.0522256981182022, 0.275353533482129, 0.0522256981182022, 0.629826433147834},
-    {-0.121317028060228, -0.121317028060227, -0.0231086697816145, -0.0858635974275114, 0.0378790777498121, 0.456810445618125, 0.0284576666227853, 0.456810445618125, 0.0284576666227853, 0.343191021097949},
-    {-0.113915793899067, -0.113915793899067, -0.0141333119882805, 0.170424436369033, 0.036936304836938, 0.445440883843385, 0.0102222917528829, 0.445440883843385, 0.0102222917528829, 0.123277807387908},
-    {-0.0612813106001657, -0.0612813106001656, -0.00585919230167206, 0.597532333802715, 0.0201853395363087, 0.243429209376147, 0.00169603302451547, 0.243429209376147, 0.00169603302451546, 0.0204536553616545},
-    {-0.0873921698118468, -0.0873921698118467, -0.118077197088165, -0.03218753374648, 0.026441315299429, 0.0535458160149806, 0.296022863232407, 0.0535458160149805, 0.296022863232407, 0.599470396664135},
-    {-0.111738685979768, -0.111738685979767, -0.1100914948925, -0.113289477381595, 0.113568535750516, 0.229985530278033, 0.216969213641037, 0.229985530278033, 0.216969213641037, 0.439380320644974},
-    {-0.124942786358968, -0.124942786358967, -0.0916202401200295, -0.0858635974275114, 0.188409760965562, 0.38154510401025, 0.118226041425621, 0.38154510401025, 0.118226041425621, 0.239417358428173},
-    {-0.103629213527269, -0.103629213527268, -0.0619213666662117, 0.170424436369033, 0.183720427705323, 0.372048822409193, 0.0424680316998818, 0.372048822409192, 0.0424680316998817, 0.0860012214282448},
-    {-0.0525918087529765, -0.0525918087529765, -0.0277535590855747, 0.597532333802715, 0.100401467590206, 0.203321145349199, 0.00704608966270762, 0.203321145349198, 0.00704608966270757, 0.0142689051747946},
-    {-0.124093005298086, -0.124093005298086, -0.0652595091978644, -0.03218753374648, 0.0584840672683638, 0.0375244400305132, 0.458847581161833, 0.037524440030513, 0.458847581161833, 0.294404943887462},
-    {-0.12437075791462, -0.12437075791462, -0.0999143296911785, -0.113289477381595, 0.251195895861737, 0.161171850222422, 0.336311181436057, 0.161171850222422, 0.336311181436057, 0.215783363723318},
-    {-0.112659672317187, -0.112659672317187, -0.124407329288456, -0.0858635974275114, 0.416733018367064, 0.267383475309499, 0.183255213959251, 0.267383475309499, 0.18325521395925, 0.11757987444578},
-    {-0.08163893883716, -0.0816389388371599, -0.108854935406145, 0.170424436369033, 0.406360944257666, 0.260728564133021, 0.0658271912156194, 0.26072856413302, 0.0658271912156194, 0.0422359217564853},
-    {-0.0383518525618255, -0.0383518525618255, -0.056723422104895, 0.597532333802715, 0.222072393823573, 0.142485682232515, 0.0109217280147868, 0.142485682232515, 0.0109217280147868, 0.00700757910765451},
-    {-0.103783072021111, -0.103783072021111, 0.230182647427123, -0.03218753374648, 0.0928673941832035, 0.0203327765730934, 0.394799511511351, 0.0203327765730932, 0.394799511511351, 0.0864390600094873},
-    {-0.094174739653074, -0.0941747396530738, 0.0860094490830938, -0.113289477381595, 0.398876298584894, 0.0873316488608436, 0.289367309751452, 0.0873316488608435, 0.289367309751452, 0.0633552917951636},
-    {-0.0756396175073989, -0.0756396175073988, -0.0642304995808229, -0.0858635974275114, 0.661734234526899, 0.144882867229582, 0.157675602800014, 0.144882867229582, 0.157675602800014, 0.0345221574370429},
-    {-0.0494789006423166, -0.0494789006423165, -0.124962882172976, 0.170424436369033, 0.645264321612071, 0.141276875455818, 0.0566387271134483, 0.141276875455818, 0.0566387271134482, 0.0124007203379724},
-    {-0.0216509230853557, -0.0216509230853557, -0.082126158551913, 0.597532333802715, 0.35263081891668, 0.0772064696859616, 0.00939722265546143, 0.0772064696859615, 0.00939722265546143, 0.00205746732038352},
-    {-0.0430392698573708, -0.0430392698573707, 0.644527340422526, -0.03218753374648, 0.120375266907318, 0.00657884021103599, 0.165578239218447, 0.00657884021103578, 0.165578239218447, 0.00904930727241116},
-    {-0.0374042602423, -0.0374042602422999, 0.365205425929728, -0.113289477381595, 0.517025822975488, 0.0282568866655468, 0.121360154303653, 0.0282568866655467, 0.121360154303653, 0.00663266702257968},
-    {-0.0282517358523633, -0.0282517358523632, 0.0549952189160882, -0.0858635974275114, 0.857743837904439, 0.0468780655408114, 0.0661288778686417, 0.0468780655408113, 0.0661288778686419, 0.0036141254928047},
-    {-0.0173663754687444, -0.0173663754687443, -0.112316360033967, 0.170424436369033, 0.836395439141882, 0.0457113166909128, 0.0237541851840646, 0.0457113166909126, 0.0237541851840646, 0.00129823171058596},
-    {-0.00723049480167941, -0.00723049480167938, -0.0982128569779484, 0.597532333802715, 0.457082158061876, 0.0249808001133636, 0.00394117909335424, 0.0249808001133633, 0.00394117909335422, 0.000215396303280713},
-    {-0.12239598458967, 0.303869742063848, -0.0354790412346856, -0.03218753374648, 0.00531592754484438, 0.0986289749858684, 0.109622633545923, 0.0295880447986773, 0.0328860701712705, 0.610151166460404},
-    {-0.1160592350988, 0.134887288422247, -0.0307383325090586, -0.113289477381595, 0.0228325293423221, 0.423622960691414, 0.0803476337536981, 0.127084106272845, 0.0241037624827062, 0.447208764024221},
-    {-0.0986364671877794, -0.0444896276300268, -0.0231086697816145, -0.0858635974275114, 0.0378790777498121, 0.702788851119186, 0.0437812467363741, 0.210832040117064, 0.0131340865091965, 0.2436830597953},
-    {-0.0678941422087684, -0.124193144215204, -0.0141333119882805, 0.170424436369033, 0.036936304836938, 0.685297129259398, 0.0157266821407568, 0.205584638427371, 0.00471790136500898, 0.0875335060137464},
-    {-0.030824777921407, -0.0858073223121641, -0.00585919230167206, 0.597532333802715, 0.0201853395363087, 0.374508367808493, 0.00260929475714279, 0.112350050943801, 0.000782771291888154, 0.0145231343948942},
-    {-0.114824393538401, 0.113856014607669, -0.118077197088165, -0.03218753374648, 0.026441315299429, 0.0823785946236129, 0.45542209017267, 0.0247130374063481, 0.136623636292144, 0.425654435971174},
-    {-0.106168256116312, 0.0100888557121194, -0.1100914948925, -0.113289477381595, 0.113568535750516, 0.353825680101135, 0.333800476424499, 0.106145380454931, 0.100137950857575, 0.311982349089632},
-    {-0.0874149447727762, -0.0930517568994225, -0.0916202401200295, -0.0858635974275114, 0.188409760965562, 0.58699543294085, 0.1818871363886, 0.17609477507965, 0.0545649464626407, 0.169998487382437},
-    {-0.0585145790109276, -0.12380786286986, -0.0619213666662117, 0.170424436369033, 0.183720427705323, 0.572385695137502, 0.0653357634308634, 0.171711949680883, 0.0196002999689001, 0.0610652362544955},
-    {-0.026045788733914, -0.0750005711613296, -0.0277535590855747, 0.597532333802715, 0.100401467590206, 0.312803342215279, 0.0108401927023285, 0.0938389484831182, 0.00325198662308662, 0.0101316475640852},
-    {-0.0938555051869133, -0.0689680280637323, -0.0652595091978644, -0.03218753374648, 0.0584840672683638, 0.0577301993658456, 0.705922921633706, 0.0173186806951807, 0.211772240689959, 0.209042466541935},
-    {-0.0842141745825612, -0.101961128009395, -0.0999143296911785, -0.113289477381595, 0.251195895861737, 0.247957945220146, 0.517404431284758, 0.0743857552246979, 0.155217931587356, 0.153217150486034},
-    {-0.0666063780815065, -0.124620776265111, -0.124407329288456, -0.0858635974275114, 0.416733018367064, 0.411361270793064, 0.281932522593158, 0.123405679825933, 0.0845779053253435, 0.0834876841580226},
-    {-0.042927113770228, -0.108104492267147, -0.108854935406145, 0.170424436369033, 0.406360944257666, 0.401122894186574, 0.101273113455689, 0.120334234079468, 0.0303812689755499, 0.0299896501195402},
-    {-0.0185713191445567, -0.0561005440374291, -0.056723422104895, 0.597532333802715, 0.222072393823573, 0.219209849244196, 0.016802743364071, 0.065761515220835, 0.00504071266550261, 0.00497573716598929},
-    {-0.0586399952744005, -0.12386321264862, 0.230182647427123, -0.03218753374648, 0.0928673941832035, 0.0312813527469399, 0.607386932104929, 0.00938420039924669, 0.182212090917773, 0.0613761238902859},
-    {-0.0513370646747661, -0.118642598591026, 0.0860094490830938, -0.113289477381595, 0.398876298584894, 0.134357061573334, 0.445182725400454, 0.0403062361483534, 0.13355189410245, 0.0449854757548079},
-    {-0.0391997300710068, -0.102069833084256, -0.0642304995808229, -0.0858635974275114, 0.661734234526899, 0.222897844792828, 0.242579075860235, 0.0668678896663356, 0.0727721297397927, 0.024512485577508},
-    {-0.0243769453534136, -0.0709852770155237, -0.124962882172976, 0.170424436369033, 0.645264321612071, 0.217350137116399, 0.0871369434274908, 0.0652036137952371, 0.0261405107994057, 0.00880514142227651},
-    {-0.0102482264730672, -0.0324570586983408, -0.082126158551913, 0.597532333802715, 0.35263081891668, 0.118779784153457, 0.0144573386556573, 0.0356331552184663, 0.0043371066552656, 0.00146090632108002},
-    {-0.0209884113390655, -0.0624662889902573, 0.644527340422526, -0.03218753374648, 0.120375266907318, 0.010121343760768, 0.254737039458918, 0.00303633666130378, 0.0764194389779762, 0.00642546788699245},
-    {-0.0180873896108673, -0.0547979943904275, 0.365205425929728, -0.113289477381595, 0.517025822975488, 0.0434723529340782, 0.186708872865861, 0.0130414203970153, 0.0560114357414458, 0.00470953053927457},
-    {-0.0134881345751056, -0.0419674243417795, 0.0549952189160882, -0.0858635974275114, 0.857743837904439, 0.0721204651516608, 0.101737249112632, 0.0216356659299618, 0.0305205066246514, 0.00256621270496323},
-    {-0.00817643359622858, -0.0261798960980541, -0.112316360033967, 0.170424436369033, 0.836395439141882, 0.0703254578534909, 0.0365450848922505, 0.0210971755283345, 0.0109632854758786, 0.000921810467379901},
-    {-0.00336386041082355, -0.0110346752071629, -0.0982128569779484, 0.597532333802715, 0.457082158061876, 0.0384321943162945, 0.00606338308075567, 0.0115294059104325, 0.00181897510595279, 0.000152942317908342},
-    {-0.0397031660797491, 0.677651385532497, -0.0354790412346856, -0.03218753374648, 0.00531592754484438, 0.12220234950981, 0.135823609448279, 0.00601467027473575, 0.00668509426891421, 0.153676704481834},
-    {-0.0344566541637982, 0.387856517182057, -0.0307383325090586, -0.113289477381595, 0.0228325293423221, 0.524873356031632, 0.0995515731929938, 0.0258337109326267, 0.00489982304341049, 0.112636954329409},
-    {-0.0259706778394854, 0.0651520171918798, -0.0231086697816145, -0.0858635974275114, 0.0378790777498121, 0.870762864851529, 0.0542454305787948, 0.0428580263847204, 0.00266990266677576, 0.0613756256250995},
-    {-0.0159280095028661, -0.110672538127309, -0.0141333119882805, 0.170424436369033, 0.036936304836938, 0.849090435339365, 0.0194855265186504, 0.0417913323474039, 0.000959056987115348, 0.0220467672199497},
-    {-0.00661888574963571, -0.0991479726822842, -0.00585919230167206, 0.597532333802715, 0.0201853395363087, 0.464019852825596, 0.0032329439693778, 0.0228385659266992, 0.000159122079653129, 0.00365789259324308},
-    {-0.0336820137710778, 0.351159931970128, -0.118077197088165, -0.03218753374648, 0.026441315299429, 0.102067955322096, 0.564272815830671, 0.00502367670786549, 0.0277729106341421, 0.107208138841391},
-    {-0.0291609440100797, 0.166485956767395, -0.1100914948925, -0.113289477381595, 0.113568535750516, 0.438393782673502, 0.413582342231706, 0.0215772778825632, 0.0203560850503691, 0.0785779359281241},
-    {-0.0218995359044539, -0.0313856207168029, -0.0916202401200295, -0.0858635974275114, 0.188409760965562, 0.727293587580909, 0.225360097430628, 0.0357966204395903, 0.0110919854206135, 0.0428169423314951},
-    {-0.0133783318084251, -0.123259167721811, -0.0619213666662117, 0.170424436369033, 0.183720427705323, 0.709191966981616, 0.080951706122999, 0.034905677836769, 0.00398435727676454, 0.0153802939039443},
-    {-0.00554072800987505, -0.0879258080236823, -0.0277535590855747, 0.597532333802715, 0.100401467590206, 0.387566669517808, 0.01343111410773, 0.0190756211805888, 0.000661065217685206, 0.00255182370239895},
-    {-0.0241572747358242, 0.0177253911135256, -0.0652595091978644, -0.03218753374648, 0.0584840672683638, 0.0715283313162981, 0.874646011568391, 0.00352054874472815, 0.0430491507552746, 0.0526508169135876},
-    {-0.0208412114214238, -0.0507072246191906, -0.0999143296911785, -0.113289477381595, 0.251195895861737, 0.307222532626626, 0.641069596017233, 0.0151211678182183, 0.0315527668548808, 0.0385902839346929},
-    {-0.0155679467426813, -0.113199283239695, -0.124407329288456, -0.0858635974275114, 0.416733018367064, 0.509680991772005, 0.349317395512301, 0.0250859588469928, 0.0171930324062, 0.0210277597937819},
-    {-0.00945478319693848, -0.119140564162676, -0.108854935406145, 0.170424436369033, 0.406360944257666, 0.49699553421089, 0.125478465209964, 0.024461594055151, 0.00617591722127439, 0.00755339144178018},
-    {-0.00389606166055691, -0.0670532863962544, -0.056723422104895, 0.597532333802715, 0.222072393823573, 0.271603335806442, 0.0208187778246103, 0.013368028658589, 0.0010246782049633, 0.00125322204081482},
-    {-0.0134113789015497, -0.123174301249333, 0.230182647427123, -0.03218753374648, 0.0928673941832035, 0.0387579289156042, 0.752558872029367, 0.00190762423058235, 0.0370401509933354, 0.0154585961181475},
-    {-0.0115286565516395, -0.124795870133571, 0.0860094490830938, -0.113289477381595, 0.398876298584894, 0.166469828971132, 0.551586133921708, 0.00819346875055494, 0.0271484855811958, 0.0113303391742266},
-    {-0.00856402179742457, -0.114366932369083, -0.0642304995808229, -0.0858635974275114, 0.661734234526899, 0.276172801534836, 0.300558056253616, 0.0135929329243277, 0.0147931493464114, 0.00617387658875262},
-    {-0.00516925988494049, -0.083605542162086, -0.124962882172976, 0.170424436369033, 0.645264321612071, 0.269299132691067, 0.107963600123275, 0.013254618220569, 0.0053138541036216, 0.00221772110036569},
-    {-0.00211875374858132, -0.0394935786210076, -0.082126158551913, 0.597532333802715, 0.35263081891668, 0.147169416491455, 0.0179127964336388, 0.00724352288046848, 0.000881648877284022, 0.000367953519260972},
-    {-0.00442262762728068, -0.074224965614645, 0.644527340422526, -0.03218753374648, 0.120375266907318, 0.0125404526199275, 0.315621902524215, 0.000617227802144259, 0.0155345759126795, 0.00161836079959531},
-    {-0.00379122127793318, -0.0655708056648835, 0.365205425929728, -0.113289477381595, 0.517025822975488, 0.0538627078708381, 0.23133428023363, 0.00265106546025538, 0.0113860283736764, 0.00118617348079642},
-    {-0.00280421494922354, -0.0507314745513394, 0.0549952189160882, -0.0858635974275114, 0.857743837904439, 0.0893580237504861, 0.126053534227744, 0.0043981073311365, 0.00620422150953936, 0.000646343288641096},
-    {-0.001684502510099, -0.031982189992167, -0.112316360033967, 0.170424436369033, 0.836395439141882, 0.0871339906075375, 0.0452797490545588, 0.00428864277428789, 0.00222862131357036, 0.000232173275363283},
-    {-0.000687522410446992, -0.0135965919524168, -0.0982128569779484, 0.597532333802715, 0.457082158061876, 0.0476178977115159, 0.0075125961569867, 0.00234370251521104, 0.000369762029721762, 3.85210627857485e-05}};
-    
-    // Array of non-zero columns
-    static const unsigned int nzc0[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
-    // Array of non-zero columns
-    static const unsigned int nzc4[10] = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19};
-    static const double FE1_C0_D001[125][7] = \
-    {{-2.53401086900984, -0.86168424032714, 0.153733097585334, 0.173940273731973, 3.39569510933698, -0.153733097585335, -0.173940273731971},
-    {-2.0255498358363, -0.306078716913217, 0.131614521121219, 0.148914359955701, 2.33162855274952, -0.131614521121219, -0.1489143599557},
-    {-1.23337591087837, 0.559545548262077, 0.0971541428643073, 0.10992439799525, 0.673830362616288, -0.097154142864307, -0.109924397995249},
-    {-0.338555305646693, 1.53733389052355, 0.0582285287322854, 0.0658822750974736, -1.19877858487685, -0.0582285287322848, -0.065882275097473},
-    {0.454770511952704, 2.40421685178806, 0.0237180419639913, 0.0268356182006482, -2.85898736374077, -0.0237180419639906, -0.0268356182006476},
-    {-1.95173754786883, -0.86168424032714, 0.764665295175825, 0.145281397282487, 2.81342178819597, -0.764665295175825, -0.145281397282486},
-    {-1.52705194873624, -0.306078716913217, 0.654647946495179, 0.124378821681794, 1.83313066564946, -0.654647946495179, -0.124378821681793},
-    {-0.865398771818851, 0.559545548262077, 0.483242727153488, 0.0918129527655822, 0.305853223556774, -0.483242727153488, -0.0918129527655815},
-    {-0.118011263129872, 1.53733389052355, 0.289627515545325, 0.0550273308012554, -1.41932262739368, -0.289627515545325, -0.0550273308012548},
-    {0.544604017438855, 2.40421685178806, 0.117973057488944, 0.0224141081618458, -2.94882086922692, -0.117973057488943, -0.0224141081618453},
-    {-1.06855188405066, -0.86168424032714, 1.6913204223926, 0.101811933883884, 1.9302361243778, -1.6913204223926, -0.101811933883883},
-    {-0.77093592668034, -0.306078716913217, 1.44797919870299, 0.0871635915298887, 1.07701464359356, -1.44797919870299, -0.0871635915298881},
-    {-0.307255161197394, 0.559545548262077, 1.0688575754173, 0.0643417151232234, -0.252290387064684, -1.0688575754173, -0.0643417151232229},
-    {0.216507474925436, 1.53733389052355, 0.640610911753232, 0.0385626726486572, -1.75384136544898, -0.640610911753231, -0.0385626726486566},
-    {0.680862474241284, 2.40421685178806, 0.260938011286713, 0.0157076111665065, -3.08507932602935, -0.260938011286712, -0.0157076111665059},
-    {-0.120853589128906, -0.86168424032714, 2.6856634241203, 0.0551672270779314, 0.982537829456046, -2.6856634241203, -0.0551672270779307},
-    {0.0404108764001508, -0.306078716913217, 2.29925963250797, 0.0472299608053964, 0.265667840513066, -2.29925963250797, -0.0472299608053958},
-    {0.291658260721922, 0.559545548262078, 1.69724888193056, 0.0348638305292845, -0.851203808984, -1.69724888193056, -0.034863830529284},
-    {0.575461260818928, 1.53733389052355, 1.01723202298603, 0.0208953473093509, -2.11279515134248, -1.01723202298603, -0.0208953473093502},
-    {0.827073981595321, 2.40421685178806, 0.414345894247555, 0.00851123555970183, -3.23129083338339, -0.414345894247554, -0.0085112355597012},
-    {0.637338430571104, -0.861684240327141, 3.48117285237853, 0.0178498185197156, 0.224345809756035, -3.48117285237853, -0.0178498185197148},
-    {0.689516899489004, -0.306078716913217, 2.9803139668845, 0.0152816495177237, -0.383438182575788, -2.9803139668845, -0.0152816495177229},
-    {0.770810095671614, 0.559545548262077, 2.1999840629478, 0.0112804844617394, -1.33035564393369, -2.1999840629478, -0.0112804844617387},
-    {0.862636934093748, 1.53733389052355, 1.31854217888416, 0.00676086468604747, -2.3999708246173, -1.31854217888415, -0.00676086468604671},
-    {0.94404833794709, 2.40421685178807, 0.537077604585377, 0.00275388157364889, -3.34826518973516, -0.537077604585376, -0.00275388157364832},
-    {-1.85228451823978, -0.86168424032714, 0.153733097585334, 0.855666624502025, 2.71396875856692, -0.153733097585334, -0.855666624502024},
-    {-1.44190787062765, -0.306078716913217, 0.131614521121219, 0.732556325164345, 1.74798658754087, -0.131614521121219, -0.732556325164345},
-    {-0.802547804781613, 0.559545548262077, 0.0971541428643073, 0.540752504092003, 0.243002256519535, -0.0971541428643072, -0.540752504092002},
-    {-0.0803420579669869, 1.53733389052355, 0.0582285287322856, 0.32409552277718, -1.45699183255656, -0.058228528732285, -0.32409552277718},
-    {0.559947695327595, 2.40421685178806, 0.0237180419639915, 0.132012801575539, -2.96416454711566, -0.0237180419639908, -0.132012801575539},
-    {-1.38233429996559, -0.86168424032714, 0.764665295175825, 0.714684645185728, 2.24401854029273, -0.764665295175825, -0.714684645185728},
-    {-1.03957243407901, -0.306078716913217, 0.654647946495179, 0.611858336339029, 1.34565115099223, -0.654647946495179, -0.611858336339028},
-    {-0.505555085826084, 0.559545548262077, 0.483242727153489, 0.45165663875835, -0.0539904624359933, -0.483242727153488, -0.451656638758349},
-    {0.0976580618337187, 1.53733389052355, 0.289627515545326, 0.270696655764846, -1.63499195235727, -0.289627515545325, -0.270696655764845},
-    {0.632451919681933, 2.40421685178806, 0.117973057488944, 0.110262010404924, -3.03666877147, -0.117973057488943, -0.110262010404923},
-    {-0.669519062828044, -0.86168424032714, 1.6913204223926, 0.500844755106496, 1.53120330315518, -1.6913204223926, -0.500844755106495},
-    {-0.429314541944297, -0.306078716913217, 1.44797919870299, 0.428784976265932, 0.735393258857514, -1.44797919870299, -0.428784976265932},
-    {-0.0550798500280451, 0.559545548262077, 1.06885757541731, 0.316517026292572, -0.504465698234032, -1.0688575754173, -0.316517026292572},
-    {0.367646653544982, 1.53733389052355, 0.640610911753232, 0.189701851268203, -1.90498054406853, -0.640610911753231, -0.189701851268203},
-    {0.742425516601204, 2.40421685178806, 0.260938011286713, 0.0772706535264272, -3.14664236838927, -0.260938011286712, -0.0772706535264267},
-    {0.0953640331101715, -0.86168424032714, 2.6856634241203, 0.271384849317009, 0.766320207216968, -2.6856634241203, -0.271384849317009},
-    {0.225519868906913, -0.306078716913217, 2.29925963250797, 0.232338953312159, 0.0805588480063039, -2.29925963250797, -0.232338953312158},
-    {0.428300519875882, 0.559545548262077, 1.69724888193056, 0.171506089683245, -0.98784606813796, -1.69724888193056, -0.171506089683244},
-    {0.657356664129762, 1.53733389052355, 1.01723202298603, 0.102790750620185, -2.19469055465331, -1.01723202298603, -0.102790750620184},
-    {0.860432176532974, 2.40421685178806, 0.414345894247555, 0.0418694304973552, -3.26464902832104, -0.414345894247554, -0.0418694304973546},
-    {0.707297453747672, -0.861684240327141, 3.48117285237853, 0.0878088416962831, 0.154386786579467, -3.48117285237853, -0.0878088416962823},
-    {0.749410464883283, -0.306078716913217, 2.9803139668845, 0.0751752149120021, -0.443331747970066, -2.9803139668845, -0.0751752149120014},
-    {0.815021843428605, 0.559545548262077, 2.1999840629478, 0.0554922322187304, -1.37456739169068, -2.1999840629478, -0.0554922322187298},
-    {0.889134877965972, 1.53733389052355, 1.31854217888416, 0.0332588085582721, -2.42646876848952, -1.31854217888415, -0.0332588085582713},
-    {0.954841661398734, 2.40421685178807, 0.537077604585377, 0.0135472050252931, -3.3590585131868, -0.537077604585376, -0.0135472050252925},
-    {-0.853975571370904, -0.86168424032714, 0.153733097585333, 1.8539755713709, 1.71565981169804, -0.153733097585333, -1.8539755713709},
-    {-0.587232097896, -0.306078716913217, 0.131614521121218, 1.587232097896, 0.893310814809216, -0.131614521121218, -1.587232097896},
-    {-0.171650154436808, 0.559545548262077, 0.0971541428643073, 1.17165015443681, -0.387895393825269, -0.0971541428643073, -1.17165015443681},
-    {0.297781209627916, 1.53733389052355, 0.0582285287322859, 0.702218790372083, -1.83511510015146, -0.0582285287322854, -0.702218790372083},
-    {0.713967446876027, 2.40421685178806, 0.0237180419639917, 0.286032553123971, -3.11818429866409, -0.023718041963991, -0.286032553123971},
-    {-0.548509472575658, -0.86168424032714, 0.764665295175825, 1.54850947257566, 1.4101937129028, -0.764665295175825, -1.54850947257566},
-    {-0.325715385209019, -0.306078716913217, 0.654647946495179, 1.32571538520902, 0.631794102122236, -0.654647946495179, -1.32571538520902},
-    {0.0213941377077832, 0.559545548262077, 0.483242727153489, 0.978605862292217, -0.58093968596986, -0.483242727153489, -0.978605862292217},
-    {0.413480703034436, 1.53733389052355, 0.289627515545326, 0.586519296965564, -1.95081459355798, -0.289627515545326, -0.586519296965563},
-    {0.761094954638504, 2.40421685178806, 0.117973057488944, 0.238905045361495, -3.16531180642657, -0.117973057488944, -0.238905045361495},
-    {-0.0851819089672699, -0.86168424032714, 1.6913204223926, 1.08518190896727, 0.94686614929441, -1.6913204223926, -1.08518190896727},
-    {0.0709502408948852, -0.306078716913217, 1.44797919870299, 0.929049759105114, 0.235128476018332, -1.44797919870299, -0.929049759105114},
-    {0.314201561839691, 0.559545548262077, 1.06885757541731, 0.685798438160309, -0.873747110101769, -1.06885757541731, -0.685798438160308},
-    {0.588972401138389, 1.53733389052355, 0.640610911753232, 0.41102759886161, -2.12630629166194, -0.640610911753232, -0.41102759886161},
-    {0.832577431537388, 2.40421685178806, 0.260938011286713, 0.167422568462611, -3.23679428332545, -0.260938011286712, -0.16742256846261},
-    {0.411989591896581, -0.86168424032714, 2.6856634241203, 0.588010408103419, 0.449694648430559, -2.6856634241203, -0.588010408103418},
-    {0.496590457797377, -0.306078716913217, 2.29925963250797, 0.503409542202622, -0.19051174088416, -2.29925963250797, -0.503409542202622},
-    {0.628397215096318, 0.559545548262078, 1.69724888193056, 0.371602784903681, -1.1879427633584, -1.69724888193056, -0.37160278490368},
-    {0.777282956754788, 1.53733389052355, 1.01723202298603, 0.222717043245211, -2.31461684727834, -1.01723202298603, -0.22271704324521},
-    {0.909281373017809, 2.40421685178806, 0.414345894247555, 0.0907186269821898, -3.31349822480587, -0.414345894247555, -0.0907186269821892},
-    {0.809744306025694, -0.861684240327141, 3.48117285237853, 0.190255693974305, 0.0519399343014455, -3.48117285237853, -0.190255693974305},
-    {0.83711762498564, -0.306078716913217, 2.9803139668845, 0.162882375014359, -0.531038908072423, -2.9803139668845, -0.162882375014358},
-    {0.879764805604936, 0.559545548262077, 2.1999840629478, 0.120235194395062, -1.43931035386701, -2.1999840629478, -0.120235194395062},
-    {0.92793803470385, 1.53733389052355, 1.31854217888416, 0.0720619652961492, -2.4652719252274, -1.31854217888415, -0.0720619652961484},
-    {0.97064722818672, 2.40421685178807, 0.537077604585377, 0.0293527718132788, -3.37486407997479, -0.537077604585376, -0.0293527718132783},
-    {0.144333375497976, -0.86168424032714, 0.153733097585332, 2.85228451823978, 0.717350864829163, -0.153733097585332, -2.85228451823978},
-    {0.267443674835655, -0.306078716913217, 0.131614521121218, 2.44190787062765, 0.0386350420775617, -0.131614521121218, -2.44190787062765},
-    {0.459247495907997, 0.559545548262077, 0.0971541428643074, 1.80254780478161, -1.01879304417007, -0.0971541428643074, -1.80254780478161},
-    {0.675904477222819, 1.53733389052355, 0.0582285287322862, 1.08034205796699, -2.21323836774637, -0.0582285287322857, -1.08034205796699},
-    {0.86798719842446, 2.40421685178806, 0.0237180419639919, 0.440052304672404, -3.27220405021253, -0.0237180419639913, -0.440052304672404},
-    {0.285315354814272, -0.86168424032714, 0.764665295175825, 2.38233429996559, 0.576368885512868, -0.764665295175825, -2.38233429996559},
-    {0.388141663660971, -0.306078716913217, 0.654647946495179, 2.03957243407901, -0.0820629467477537, -0.654647946495179, -2.03957243407901},
-    {0.54834336124165, 0.559545548262077, 0.483242727153489, 1.50555508582608, -1.10788890950373, -0.483242727153489, -1.50555508582608},
-    {0.729303344235153, 1.53733389052355, 0.289627515545326, 0.902341938166281, -2.2666372347587, -0.289627515545326, -0.902341938166281},
-    {0.889737989595075, 2.40421685178806, 0.117973057488944, 0.367548080318067, -3.29395484138314, -0.117973057488944, -0.367548080318066},
-    {0.499155244893504, -0.86168424032714, 1.6913204223926, 1.66951906282804, 0.362528995433636, -1.6913204223926, -1.66951906282804},
-    {0.571215023734067, -0.306078716913217, 1.44797919870299, 1.4293145419443, -0.26513630682085, -1.44797919870299, -1.4293145419443},
-    {0.683482973707427, 0.559545548262077, 1.06885757541731, 1.05507985002804, -1.2430285219695, -1.06885757541731, -1.05507985002804},
-    {0.810298148731796, 1.53733389052355, 0.640610911753232, 0.632353346455017, -2.34763203925534, -0.640610911753232, -0.632353346455017},
-    {0.922729346473571, 2.40421685178806, 0.260938011286713, 0.257574483398795, -3.32694619826164, -0.260938011286712, -0.257574483398794},
-    {0.72861515068299, -0.86168424032714, 2.6856634241203, 0.904635966889828, 0.13306908964415, -2.6856634241203, -0.904635966889828},
-    {0.76766104668784, -0.306078716913217, 2.29925963250797, 0.774480131093086, -0.461582329774624, -2.29925963250797, -0.774480131093086},
-    {0.828493910316754, 0.559545548262078, 1.69724888193056, 0.571699480124117, -1.38803945857883, -1.69724888193056, -0.571699480124116},
-    {0.897209249379814, 1.53733389052355, 1.01723202298603, 0.342643335870237, -2.43454313990336, -1.01723202298603, -0.342643335870237},
-    {0.958130569502644, 2.40421685178806, 0.414345894247555, 0.139567823467025, -3.36234742129071, -0.414345894247555, -0.139567823467024},
-    {0.912191158303716, -0.861684240327141, 3.48117285237853, 0.292702546252328, -0.0505069179765767, -3.48117285237853, -0.292702546252327},
-    {0.924824785087997, -0.306078716913217, 2.9803139668845, 0.250589535116716, -0.61874606817478, -2.9803139668845, -0.250589535116716},
-    {0.944507767781268, 0.559545548262077, 2.1999840629478, 0.184978156571394, -1.50405331604335, -2.1999840629478, -0.184978156571393},
-    {0.966741191441727, 1.53733389052355, 1.31854217888416, 0.110865122034026, -2.50407508196527, -1.31854217888415, -0.110865122034026},
-    {0.986452794974706, 2.40421685178807, 0.537077604585377, 0.0451583386012648, -3.39066964676277, -0.537077604585376, -0.0451583386012643},
-    {0.826059726268027, -0.86168424032714, 0.153733097585331, 3.53401086900984, 0.0356245140591109, -0.153733097585331, -3.53401086900983},
-    {0.8510856400443, -0.306078716913217, 0.131614521121218, 3.0255498358363, -0.545006923131083, -0.131614521121218, -3.0255498358363},
-    {0.890075602004749, 0.559545548262077, 0.0971541428643075, 2.23337591087837, -1.44962115026683, -0.0971541428643075, -2.23337591087836},
-    {0.934117724902526, 1.53733389052355, 0.0582285287322864, 1.33855530564669, -2.47145161542607, -0.058228528732286, -1.33855530564669},
-    {0.973164381799351, 2.40421685178806, 0.023718041963992, 0.545229488047295, -3.37738123358742, -0.0237180419639914, -0.545229488047295},
-    {0.854718602717513, -0.86168424032714, 0.764665295175825, 2.95173754786883, 0.00696563760962579, -0.764665295175825, -2.95173754786883},
-    {0.875621178318205, -0.306078716913217, 0.654647946495179, 2.52705194873624, -0.569542461404989, -0.654647946495179, -2.52705194873624},
-    {0.908187047234417, 0.559545548262077, 0.483242727153489, 1.86539877181885, -1.46773259549649, -0.483242727153489, -1.86539877181885},
-    {0.944972669198744, 1.53733389052355, 0.289627515545326, 1.11801126312987, -2.48230655972229, -0.289627515545326, -1.11801126312987},
-    {0.977585891838153, 2.40421685178806, 0.117973057488945, 0.455395982561145, -3.38180274362622, -0.117973057488944, -0.455395982561144},
-    {0.898188066116116, -0.86168424032714, 1.6913204223926, 2.06855188405066, -0.0365038257889762, -1.6913204223926, -2.06855188405065},
-    {0.91283640847011, -0.306078716913217, 1.44797919870299, 1.77093592668034, -0.606757691556893, -1.44797919870299, -1.77093592668034},
-    {0.935658284876775, 0.559545548262077, 1.06885757541731, 1.30725516119739, -1.49520383313885, -1.06885757541731, -1.30725516119739},
-    {0.961437327351342, 1.53733389052355, 0.640610911753233, 0.783492525074564, -2.49877121787489, -0.640610911753232, -0.783492525074563},
-    {0.984292388833492, 2.40421685178806, 0.260938011286713, 0.319137525758715, -3.38850924062156, -0.260938011286713, -0.319137525758715},
-    {0.944832772922068, -0.86168424032714, 2.6856634241203, 1.12085358912891, -0.083148532594928, -2.6856634241203, -1.12085358912891},
-    {0.952770039194602, -0.306078716913217, 2.29925963250797, 0.959589123599848, -0.646691322281386, -2.29925963250797, -0.959589123599848},
-    {0.965136169470714, 0.559545548262077, 1.69724888193056, 0.708341739278077, -1.52468171773279, -1.69724888193056, -0.708341739278077},
-    {0.979104652690648, 1.53733389052355, 1.01723202298603, 0.424538739181071, -2.5164385432142, -1.01723202298603, -0.42453873918107},
-    {0.991488764440297, 2.40421685178806, 0.414345894247555, 0.172926018404678, -3.39570561622836, -0.414345894247555, -0.172926018404678},
-    {0.982150181480283, -0.861684240327141, 3.48117285237853, 0.362661569428895, -0.120465941153144, -3.48117285237853, -0.362661569428894},
-    {0.984718350482275, -0.306078716913217, 2.9803139668845, 0.310483100510995, -0.678639633569059, -2.9803139668845, -0.310483100510994},
-    {0.988719515538259, 0.559545548262077, 2.1999840629478, 0.229189904328385, -1.54826506380034, -2.1999840629478, -0.229189904328384},
-    {0.993239135313951, 1.53733389052355, 1.31854217888416, 0.137363065906251, -2.5305730258375, -1.31854217888415, -0.13736306590625},
-    {0.997246118426349, 2.40421685178807, 0.537077604585377, 0.0559516620529087, -3.40146297021442, -0.537077604585376, -0.0559516620529083}};
-    
-    // Array of non-zero columns
-    static const unsigned int nzc1[7] = {0, 3, 4, 5, 7, 8, 9};
-    static const double FE1_C0_D010[125][7] = \
-    {{-2.53401086900984, -0.846266902414667, 0.138315759672862, 0.173940273731974, -0.138315759672862, 3.3802777714245, -0.173940273731973},
-    {-2.0255498358363, -0.868385478878781, 0.693921283086784, 0.148914359955701, -0.693921283086783, 2.89393531471508, -0.1489143599557},
-    {-1.23337591087837, -0.902845857135692, 1.55954554826208, 0.109924397995249, -1.55954554826208, 2.13622176801406, -0.109924397995249},
-    {-0.338555305646693, -0.941771471267714, 2.53733389052355, 0.0658822750974729, -2.53733389052355, 1.28032677691441, -0.0658822750974728},
-    {0.454770511952705, -0.976281958036009, 3.40421685178806, 0.0268356182006483, -3.40421685178806, 0.521511446083304, -0.0268356182006486},
-    {-1.95173754786883, -0.235334704824175, 0.138315759672861, 0.145281397282487, -0.138315759672861, 2.187072252693, -0.145281397282487},
-    {-1.52705194873624, -0.345352053504821, 0.693921283086783, 0.124378821681794, -0.693921283086783, 1.87240400224106, -0.124378821681793},
-    {-0.865398771818851, -0.516757272846511, 1.55954554826208, 0.0918129527655814, -1.55954554826208, 1.38215604466536, -0.0918129527655814},
-    {-0.118011263129871, -0.710372484454674, 2.53733389052355, 0.0550273308012546, -2.53733389052355, 0.828383747584545, -0.0550273308012547},
-    {0.544604017438855, -0.882026942511056, 3.40421685178806, 0.0224141081618461, -3.40421685178806, 0.337422925072202, -0.0224141081618462},
-    {-1.06855188405066, 0.6913204223926, 0.138315759672859, 0.101811933883883, -0.13831575967286, 0.377231461658056, -0.101811933883884},
-    {-0.77093592668034, 0.447979198702987, 0.693921283086782, 0.087163591529888, -0.693921283086782, 0.322956727977352, -0.0871635915298885},
-    {-0.307255161197393, 0.068857575417305, 1.55954554826208, 0.0643417151232226, -1.55954554826208, 0.238397585780088, -0.0643417151232226},
-    {0.216507474925436, -0.359389088246769, 2.53733389052355, 0.0385626726486567, -2.53733389052355, 0.142881613321332, -0.0385626726486567},
-    {0.680862474241284, -0.739061988713288, 3.40421685178806, 0.0157076111665069, -3.40421685178806, 0.058199514472004, -0.015707611166507},
-    {-0.120853589128906, 1.6856634241203, 0.138315759672859, 0.0551672270779302, -0.138315759672859, -1.5648098349914, -0.0551672270779314},
-    {0.0404108764001513, 1.29925963250797, 0.693921283086782, 0.0472299608053953, -0.693921283086782, -1.33967050890812, -0.047229960805396},
-    {0.291658260721923, 0.69724888193056, 1.55954554826208, 0.0348638305292839, -1.55954554826208, -0.988907142652483, -0.034863830529284},
-    {0.575461260818929, 0.0172320229860304, 2.53733389052355, 0.0208953473093506, -2.53733389052355, -0.59269328380496, -0.0208953473093506},
-    {0.827073981595321, -0.585654105752446, 3.40421685178807, 0.00851123555970239, -3.40421685178807, -0.241419875842875, -0.00851123555970248},
-    {0.637338430571105, 2.48117285237853, 0.138315759672859, 0.0178498185197144, -0.138315759672859, -3.11851128294963, -0.0178498185197154},
-    {0.689516899489005, 1.9803139668845, 0.693921283086782, 0.0152816495177227, -0.693921283086782, -2.6698308663735, -0.0152816495177232},
-    {0.770810095671614, 1.1999840629478, 1.55954554826208, 0.0112804844617389, -1.55954554826208, -1.97079415861941, -0.011280484461739},
-    {0.862636934093749, 0.318542178884154, 2.53733389052355, 0.00676086468604743, -2.53733389052355, -1.1811791129779, -0.00676086468604731},
-    {0.94404833794709, -0.462922395414624, 3.40421685178807, 0.00275388157364971, -3.40421685178807, -0.481125942532466, -0.00275388157364974},
-    {-1.85228451823978, -0.846266902414667, 0.138315759672862, 0.855666624502025, -0.138315759672862, 2.69855142065445, -0.855666624502025},
-    {-1.44190787062765, -0.868385478878781, 0.693921283086783, 0.732556325164345, -0.693921283086783, 2.31029334950644, -0.732556325164345},
-    {-0.802547804781612, -0.902845857135692, 1.55954554826208, 0.540752504092002, -1.55954554826208, 1.7053936619173, -0.540752504092002},
-    {-0.0803420579669867, -0.941771471267714, 2.53733389052355, 0.32409552277718, -2.53733389052355, 1.0221135292347, -0.32409552277718},
-    {0.559947695327596, -0.976281958036009, 3.40421685178806, 0.13201280157554, -3.40421685178806, 0.416334262708413, -0.13201280157554},
-    {-1.38233429996559, -0.235334704824175, 0.138315759672861, 0.714684645185728, -0.138315759672861, 1.61766900478976, -0.714684645185729},
-    {-1.03957243407901, -0.345352053504821, 0.693921283086783, 0.611858336339028, -0.693921283086783, 1.38492448758383, -0.611858336339029},
-    {-0.505555085826084, -0.516757272846511, 1.55954554826208, 0.451656638758349, -1.55954554826208, 1.02231235867259, -0.451656638758349},
-    {0.097658061833719, -0.710372484454674, 2.53733389052355, 0.270696655764845, -2.53733389052355, 0.612714422620955, -0.270696655764845},
-    {0.632451919681933, -0.882026942511056, 3.40421685178806, 0.110262010404924, -3.40421685178806, 0.249575022829124, -0.110262010404924},
-    {-0.669519062828044, 0.6913204223926, 0.13831575967286, 0.500844755106495, -0.13831575967286, -0.0218013595645561, -0.500844755106496},
-    {-0.429314541944297, 0.447979198702988, 0.693921283086782, 0.428784976265931, -0.693921283086782, -0.0186646567586911, -0.428784976265932},
-    {-0.0550798500280447, 0.0688575754173051, 1.55954554826208, 0.316517026292572, -1.55954554826208, -0.0137777253892607, -0.316517026292571},
-    {0.367646653544982, -0.359389088246769, 2.53733389052355, 0.189701851268203, -2.53733389052355, -0.00825756529821425, -0.189701851268203},
-    {0.742425516601205, -0.739061988713288, 3.40421685178806, 0.0772706535264277, -3.40421685178806, -0.00336352788791668, -0.0772706535264278},
-    {0.0953640331101717, 1.6856634241203, 0.138315759672859, 0.271384849317008, -0.138315759672859, -1.78102745723047, -0.271384849317009},
-    {0.225519868906913, 1.29925963250797, 0.693921283086782, 0.232338953312158, -0.693921283086782, -1.52477950141488, -0.232338953312158},
-    {0.428300519875883, 0.69724888193056, 1.55954554826208, 0.171506089683245, -1.55954554826208, -1.12554940180644, -0.171506089683245},
-    {0.657356664129763, 0.0172320229860304, 2.53733389052355, 0.102790750620184, -2.53733389052355, -0.674588687115793, -0.102790750620184},
-    {0.860432176532975, -0.585654105752446, 3.40421685178807, 0.0418694304973558, -3.40421685178807, -0.274778070780529, -0.0418694304973559},
-    {0.707297453747672, 2.48117285237853, 0.138315759672859, 0.087808841696282, -0.138315759672859, -3.1884703061262, -0.0878088416962829},
-    {0.749410464883284, 1.9803139668845, 0.693921283086782, 0.0751752149120012, -0.693921283086783, -2.72972443176778, -0.0751752149120016},
-    {0.815021843428605, 1.1999840629478, 1.55954554826208, 0.05549223221873, -1.55954554826208, -2.0150059063764, -0.0554922322187299},
-    {0.889134877965973, 0.318542178884154, 2.53733389052355, 0.0332588085582721, -2.53733389052355, -1.20767705685013, -0.033258808558272},
-    {0.954841661398734, -0.462922395414624, 3.40421685178807, 0.0135472050252939, -3.40421685178807, -0.49191926598411, -0.013547205025294},
-    {-0.853975571370904, -0.846266902414667, 0.138315759672861, 1.8539755713709, -0.138315759672861, 1.70024247378557, -1.8539755713709},
-    {-0.587232097895999, -0.868385478878781, 0.693921283086783, 1.587232097896, -0.693921283086783, 1.45561757677478, -1.587232097896},
-    {-0.171650154436808, -0.902845857135692, 1.55954554826208, 1.17165015443681, -1.55954554826208, 1.0744960115725, -1.17165015443681},
-    {0.297781209627916, -0.941771471267714, 2.53733389052355, 0.702218790372083, -2.53733389052355, 0.643990261639798, -0.702218790372083},
-    {0.713967446876028, -0.976281958036009, 3.40421685178806, 0.286032553123972, -3.40421685178806, 0.262314511159981, -0.286032553123972},
-    {-0.548509472575657, -0.235334704824175, 0.13831575967286, 1.54850947257566, -0.13831575967286, 0.783844177399832, -1.54850947257566},
-    {-0.325715385209019, -0.345352053504821, 0.693921283086783, 1.32571538520902, -0.693921283086783, 0.67106743871384, -1.32571538520902},
-    {0.0213941377077833, -0.516757272846511, 1.55954554826208, 0.978605862292217, -1.55954554826208, 0.495363135138727, -0.978605862292217},
-    {0.413480703034436, -0.710372484454674, 2.53733389052355, 0.586519296965563, -2.53733389052355, 0.296891781420238, -0.586519296965563},
-    {0.761094954638504, -0.882026942511056, 3.40421685178806, 0.238905045361496, -3.40421685178806, 0.120931987872552, -0.238905045361496},
-    {-0.08518190896727, 0.6913204223926, 0.13831575967286, 1.08518190896727, -0.13831575967286, -0.60613851342533, -1.08518190896727},
-    {0.0709502408948853, 0.447979198702988, 0.693921283086783, 0.929049759105114, -0.693921283086783, -0.518929439597874, -0.929049759105114},
-    {0.314201561839691, 0.0688575754173052, 1.55954554826208, 0.685798438160308, -1.55954554826208, -0.383059137256997, -0.685798438160308},
-    {0.588972401138389, -0.359389088246769, 2.53733389052355, 0.41102759886161, -2.53733389052355, -0.229583312891621, -0.41102759886161},
-    {0.832577431537388, -0.739061988713288, 3.40421685178806, 0.167422568462611, -3.40421685178806, -0.0935154428241002, -0.167422568462612},
-    {0.411989591896581, 1.6856634241203, 0.138315759672859, 0.588010408103418, -0.138315759672859, -2.09765301601688, -0.588010408103419},
-    {0.496590457797377, 1.29925963250797, 0.693921283086782, 0.503409542202622, -0.693921283086782, -1.79585009030535, -0.503409542202622},
-    {0.628397215096319, 0.69724888193056, 1.55954554826208, 0.37160278490368, -1.55954554826208, -1.32564609702688, -0.37160278490368},
-    {0.777282956754789, 0.0172320229860305, 2.53733389052355, 0.222717043245211, -2.53733389052355, -0.79451497974082, -0.222717043245211},
-    {0.909281373017809, -0.585654105752446, 3.40421685178807, 0.0907186269821904, -3.40421685178807, -0.323627267265363, -0.0907186269821905},
-    {0.809744306025694, 2.48117285237853, 0.138315759672859, 0.190255693974304, -0.138315759672859, -3.29091715840422, -0.190255693974305},
-    {0.83711762498564, 1.9803139668845, 0.693921283086782, 0.162882375014358, -0.693921283086783, -2.81743159187014, -0.162882375014359},
-    {0.879764805604937, 1.1999840629478, 1.55954554826208, 0.120235194395062, -1.55954554826208, -2.07974886855273, -0.120235194395062},
-    {0.92793803470385, 0.318542178884154, 2.53733389052355, 0.0720619652961492, -2.53733389052355, -1.246480213588, -0.0720619652961491},
-    {0.97064722818672, -0.462922395414624, 3.40421685178807, 0.0293527718132797, -3.40421685178807, -0.507724832772096, -0.0293527718132797},
-    {0.144333375497976, -0.846266902414667, 0.13831575967286, 2.85228451823978, -0.13831575967286, 0.701933526916691, -2.85228451823978},
-    {0.267443674835655, -0.868385478878781, 0.693921283086782, 2.44190787062765, -0.693921283086783, 0.600941804043126, -2.44190787062765},
-    {0.459247495907997, -0.902845857135692, 1.55954554826208, 1.80254780478161, -1.55954554826208, 0.443598361227695, -1.80254780478161},
-    {0.675904477222819, -0.941771471267714, 2.53733389052355, 1.08034205796699, -2.53733389052355, 0.265866994044895, -1.08034205796699},
-    {0.86798719842446, -0.976281958036009, 3.40421685178806, 0.440052304672404, -3.40421685178806, 0.108294759611549, -0.440052304672405},
-    {0.285315354814272, -0.235334704824175, 0.13831575967286, 2.38233429996559, -0.13831575967286, -0.0499806499900974, -2.38233429996559},
-    {0.388141663660971, -0.345352053504821, 0.693921283086783, 2.03957243407901, -0.693921283086783, -0.0427896101561506, -2.03957243407901},
-    {0.54834336124165, -0.516757272846511, 1.55954554826208, 1.50555508582608, -1.55954554826208, -0.0315860883951393, -1.50555508582608},
-    {0.729303344235153, -0.710372484454674, 2.53733389052355, 0.902341938166281, -2.53733389052355, -0.0189308597804795, -0.902341938166281},
-    {0.889737989595075, -0.882026942511056, 3.40421685178807, 0.367548080318067, -3.40421685178807, -0.00771104708401874, -0.367548080318067},
-    {0.499155244893504, 0.691320422392601, 0.13831575967286, 1.66951906282804, -0.13831575967286, -1.1904756672861, -1.66951906282804},
-    {0.571215023734067, 0.447979198702988, 0.693921283086783, 1.4293145419443, -0.693921283086783, -1.01919422243706, -1.4293145419443},
-    {0.683482973707427, 0.0688575754173054, 1.55954554826208, 1.05507985002804, -1.55954554826208, -0.752340549124733, -1.05507985002804},
-    {0.810298148731796, -0.359389088246769, 2.53733389052355, 0.632353346455017, -2.53733389052355, -0.450909060485028, -0.632353346455017},
-    {0.922729346473572, -0.739061988713288, 3.40421685178806, 0.257574483398795, -3.40421685178806, -0.183667357760284, -0.257574483398796},
-    {0.72861515068299, 1.6856634241203, 0.138315759672859, 0.904635966889828, -0.13831575967286, -2.41427857480329, -0.904635966889828},
-    {0.767661046687841, 1.29925963250797, 0.693921283086783, 0.774480131093086, -0.693921283086783, -2.06692067919581, -0.774480131093086},
-    {0.828493910316754, 0.69724888193056, 1.55954554826208, 0.571699480124116, -1.55954554826208, -1.52574279224731, -0.571699480124116},
-    {0.897209249379815, 0.0172320229860305, 2.53733389052355, 0.342643335870237, -2.53733389052355, -0.914441272365846, -0.342643335870237},
-    {0.958130569502644, -0.585654105752446, 3.40421685178807, 0.139567823467025, -3.40421685178807, -0.372476463750198, -0.139567823467025},
-    {0.912191158303716, 2.48117285237853, 0.138315759672859, 0.292702546252327, -0.138315759672859, -3.39336401068225, -0.292702546252327},
-    {0.924824785087997, 1.9803139668845, 0.693921283086783, 0.250589535116716, -0.693921283086783, -2.9051387519725, -0.250589535116716},
-    {0.944507767781269, 1.1999840629478, 1.55954554826208, 0.184978156571394, -1.55954554826208, -2.14449183072907, -0.184978156571394},
-    {0.966741191441727, 0.318542178884154, 2.53733389052355, 0.110865122034026, -2.53733389052355, -1.28528337032588, -0.110865122034026},
-    {0.986452794974706, -0.462922395414624, 3.40421685178807, 0.0451583386012656, -3.40421685178807, -0.523530399560082, -0.0451583386012656},
-    {0.826059726268028, -0.846266902414667, 0.138315759672859, 3.53401086900983, -0.138315759672859, 0.0202071761466383, -3.53401086900983},
-    {0.8510856400443, -0.868385478878782, 0.693921283086782, 3.0255498358363, -0.693921283086782, 0.0172998388344806, -3.0255498358363},
-    {0.89007560200475, -0.902845857135692, 1.55954554826208, 2.23337591087836, -1.55954554826208, 0.012770255130942, -2.23337591087836},
-    {0.934117724902525, -0.941771471267714, 2.53733389052355, 1.33855530564669, -2.53733389052355, 0.00765374636518801, -1.33855530564669},
-    {0.973164381799351, -0.976281958036009, 3.40421685178806, 0.545229488047295, -3.40421685178806, 0.00311757623665807, -0.545229488047296},
-    {0.854718602717513, -0.235334704824175, 0.138315759672859, 2.95173754786883, -0.13831575967286, -0.61938389789334, -2.95173754786883},
-    {0.875621178318206, -0.345352053504821, 0.693921283086783, 2.52705194873624, -0.693921283086783, -0.530269124813386, -2.52705194873624},
-    {0.908187047234417, -0.516757272846511, 1.55954554826208, 1.86539877181885, -1.55954554826208, -0.391429774387907, -1.86539877181885},
-    {0.944972669198744, -0.710372484454674, 2.53733389052355, 1.11801126312987, -2.53733389052355, -0.23460018474407, -1.11801126312987},
-    {0.977585891838153, -0.882026942511056, 3.40421685178807, 0.455395982561145, -3.40421685178807, -0.0955589493270969, -0.455395982561146},
-    {0.898188066116116, 0.691320422392601, 0.13831575967286, 2.06855188405065, -0.13831575967286, -1.58950848850872, -2.06855188405066},
-    {0.91283640847011, 0.447979198702988, 0.693921283086783, 1.77093592668034, -0.693921283086783, -1.3608156071731, -1.77093592668034},
-    {0.935658284876775, 0.0688575754173054, 1.55954554826208, 1.30725516119739, -1.55954554826208, -1.00451586029408, -1.30725516119739},
-    {0.961437327351342, -0.359389088246768, 2.53733389052355, 0.783492525074564, -2.53733389052355, -0.602048239104574, -0.783492525074564},
-    {0.984292388833492, -0.739061988713288, 3.40421685178807, 0.319137525758716, -3.40421685178807, -0.245230400120204, -0.319137525758716},
-    {0.944832772922068, 1.6856634241203, 0.138315759672859, 1.12085358912891, -0.13831575967286, -2.63049619704237, -1.12085358912891},
-    {0.952770039194603, 1.29925963250797, 0.693921283086783, 0.959589123599848, -0.693921283086783, -2.25202967170258, -0.959589123599848},
-    {0.965136169470714, 0.69724888193056, 1.55954554826208, 0.708341739278077, -1.55954554826208, -1.66238505140128, -0.708341739278077},
-    {0.979104652690649, 0.0172320229860305, 2.53733389052355, 0.424538739181071, -2.53733389052355, -0.996336675676679, -0.424538739181071},
-    {0.991488764440297, -0.585654105752446, 3.40421685178807, 0.172926018404679, -3.40421685178807, -0.405834658687851, -0.172926018404679},
-    {0.982150181480284, 2.48117285237853, 0.138315759672859, 0.362661569428894, -0.13831575967286, -3.46332303385881, -0.362661569428895},
-    {0.984718350482276, 1.9803139668845, 0.693921283086783, 0.310483100510994, -0.693921283086783, -2.96503231736678, -0.310483100510994},
-    {0.98871951553826, 1.1999840629478, 1.55954554826208, 0.229189904328385, -1.55954554826208, -2.18870357848606, -0.229189904328385},
-    {0.993239135313952, 0.318542178884154, 2.53733389052355, 0.137363065906251, -2.53733389052355, -1.31178131419811, -0.137363065906251},
-    {0.99724611842635, -0.462922395414624, 3.40421685178807, 0.0559516620529096, -3.40421685178807, -0.534323723011726, -0.0559516620529098}};
-    
-    // Array of non-zero columns
-    static const unsigned int nzc2[7] = {0, 2, 4, 6, 7, 8, 9};
-    static const double FE1_C0_D100[125][7] = \
-    {{-2.53401086900984, -0.82605972626803, 0.138315759672862, 0.153733097585335, -0.138315759672862, -0.153733097585335, 3.36007059527787},
-    {-2.0255498358363, -0.8510856400443, 0.693921283086783, 0.131614521121219, -0.693921283086783, -0.13161452112122, 2.8766354758806},
-    {-1.23337591087837, -0.89007560200475, 1.55954554826208, 0.0971541428643071, -1.55954554826208, -0.0971541428643071, 2.12345151288312},
-    {-0.338555305646693, -0.934117724902525, 2.53733389052355, 0.0582285287322848, -2.53733389052355, -0.0582285287322848, 1.27267303054922},
-    {0.454770511952704, -0.973164381799351, 3.40421685178806, 0.0237180419639906, -3.40421685178806, -0.0237180419639906, 0.518393869846646},
-    {-1.95173754786883, -0.854718602717514, 0.138315759672861, 0.764665295175825, -0.138315759672861, -0.764665295175826, 2.80645615058634},
-    {-1.52705194873624, -0.875621178318207, 0.693921283086783, 0.654647946495179, -0.693921283086783, -0.654647946495179, 2.40267312705445},
-    {-0.865398771818852, -0.908187047234418, 1.55954554826208, 0.483242727153488, -1.55954554826208, -0.483242727153488, 1.77358581905327},
-    {-0.118011263129872, -0.944972669198744, 2.53733389052355, 0.289627515545325, -2.53733389052355, -0.289627515545325, 1.06298393232862},
-    {0.544604017438855, -0.977585891838153, 3.40421685178807, 0.117973057488943, -3.40421685178807, -0.117973057488943, 0.432981874399299},
-    {-1.06855188405066, -0.898188066116116, 0.13831575967286, 1.6913204223926, -0.13831575967286, -1.6913204223926, 1.96673995016677},
-    {-0.77093592668034, -0.912836408470111, 0.693921283086782, 1.44797919870299, -0.693921283086782, -1.44797919870299, 1.68377233515045},
-    {-0.307255161197394, -0.935658284876776, 1.55954554826208, 1.0688575754173, -1.55954554826208, -1.0688575754173, 1.24291344607417},
-    {0.216507474925436, -0.961437327351342, 2.53733389052355, 0.640610911753231, -2.53733389052355, -0.640610911753231, 0.744929852425906},
-    {0.680862474241284, -0.984292388833493, 3.40421685178807, 0.260938011286712, -3.40421685178807, -0.260938011286712, 0.303429914592209},
-    {-0.120853589128906, -0.944832772922068, 0.138315759672859, 2.6856634241203, -0.138315759672859, -2.6856634241203, 1.06568636205097},
-    {0.0404108764001512, -0.952770039194603, 0.693921283086782, 2.29925963250797, -0.693921283086782, -2.29925963250797, 0.912359162794452},
-    {0.291658260721922, -0.965136169470715, 1.55954554826208, 1.69724888193056, -1.55954554826208, -1.69724888193056, 0.673477908748793},
-    {0.575461260818929, -0.979104652690649, 2.53733389052355, 1.01723202298603, -2.53733389052355, -1.01723202298603, 0.40364339187172},
-    {0.827073981595321, -0.991488764440298, 3.40421685178807, 0.414345894247555, -3.40421685178807, -0.414345894247555, 0.164414782844977},
-    {0.637338430571105, -0.982150181480284, 0.138315759672859, 3.48117285237853, -0.138315759672859, -3.48117285237853, 0.344811750909179},
-    {0.689516899489005, -0.984718350482277, 0.693921283086783, 2.9803139668845, -0.693921283086783, -2.9803139668845, 0.295201450993271},
-    {0.770810095671615, -0.988719515538262, 1.55954554826208, 2.1999840629478, -1.55954554826208, -2.1999840629478, 0.217909419866647},
-    {0.862636934093749, -0.993239135313953, 2.53733389052355, 1.31854217888416, -2.53733389052355, -1.31854217888416, 0.130602201220204},
-    {0.94404833794709, -0.997246118426351, 3.40421685178807, 0.537077604585377, -3.40421685178807, -0.537077604585377, 0.0531977804792609},
-    {-1.85228451823978, -0.144333375497977, 0.138315759672862, 0.153733097585335, -0.138315759672862, -0.153733097585335, 1.99661789373776},
-    {-1.44190787062765, -0.267443674835656, 0.693921283086783, 0.131614521121219, -0.693921283086783, -0.131614521121219, 1.70935154546331},
-    {-0.802547804781613, -0.459247495907997, 1.55954554826208, 0.0971541428643072, -1.55954554826208, -0.0971541428643073, 1.26179530068961},
-    {-0.0803420579669868, -0.675904477222819, 2.53733389052355, 0.0582285287322851, -2.53733389052355, -0.0582285287322851, 0.756246535189806},
-    {0.559947695327596, -0.86798719842446, 3.40421685178806, 0.0237180419639908, -3.40421685178806, -0.0237180419639908, 0.308039503096864},
-    {-1.38233429996559, -0.285315354814272, 0.138315759672861, 0.764665295175825, -0.138315759672861, -0.764665295175825, 1.66764965477986},
-    {-1.03957243407901, -0.388141663660972, 0.693921283086783, 0.654647946495179, -0.693921283086783, -0.654647946495179, 1.42771409773998},
-    {-0.505555085826084, -0.54834336124165, 1.55954554826208, 0.483242727153488, -1.55954554826208, -0.483242727153488, 1.05389844706773},
-    {0.0976580618337188, -0.729303344235153, 2.53733389052355, 0.289627515545325, -2.53733389052355, -0.289627515545325, 0.631645282401435},
-    {0.632451919681933, -0.889737989595075, 3.40421685178807, 0.117973057488944, -3.40421685178807, -0.117973057488944, 0.257286069913143},
-    {-0.669519062828044, -0.499155244893504, 0.13831575967286, 1.6913204223926, -0.13831575967286, -1.6913204223926, 1.16867430772155},
-    {-0.429314541944297, -0.571215023734068, 0.693921283086782, 1.44797919870299, -0.693921283086782, -1.44797919870299, 1.00052956567836},
-    {-0.0550798500280449, -0.683482973707428, 1.55954554826208, 1.0688575754173, -1.55954554826208, -1.06885757541731, 0.738562823735472},
-    {0.367646653544982, -0.810298148731796, 2.53733389052355, 0.640610911753231, -2.53733389052355, -0.640610911753232, 0.442651495186814},
-    {0.742425516601204, -0.922729346473572, 3.40421685178807, 0.260938011286712, -3.40421685178807, -0.260938011286712, 0.180303829872368},
-    {0.0953640331101717, -0.72861515068299, 0.138315759672859, 2.6856634241203, -0.138315759672859, -2.6856634241203, 0.633251117572818},
-    {0.225519868906913, -0.767661046687841, 0.693921283086782, 2.29925963250797, -0.693921283086782, -2.29925963250797, 0.542141177780928},
-    {0.428300519875883, -0.828493910316755, 1.55954554826208, 1.69724888193056, -1.55954554826208, -1.69724888193056, 0.400193390440872},
-    {0.657356664129763, -0.897209249379815, 2.53733389052355, 1.01723202298603, -2.53733389052355, -1.01723202298603, 0.239852585250053},
-    {0.860432176532975, -0.958130569502645, 3.40421685178807, 0.414345894247555, -3.40421685178807, -0.414345894247555, 0.09769839296967},
-    {0.707297453747673, -0.912191158303717, 0.138315759672859, 3.48117285237853, -0.138315759672859, -3.48117285237853, 0.204893704556044},
-    {0.749410464883284, -0.924824785087998, 0.693921283086783, 2.9803139668845, -0.693921283086783, -2.9803139668845, 0.175414320204714},
-    {0.815021843428606, -0.944507767781271, 1.55954554826208, 2.1999840629478, -1.55954554826208, -2.1999840629478, 0.129485924352665},
-    {0.889134877965973, -0.966741191441729, 2.53733389052355, 1.31854217888416, -2.53733389052355, -1.31854217888416, 0.0776063134757552},
-    {0.954841661398734, -0.986452794974707, 3.40421685178807, 0.537077604585377, -3.40421685178807, -0.537077604585377, 0.0316111335759726},
-    {-0.853975571370903, 0.853975571370903, 0.138315759672861, 0.153733097585334, -0.138315759672861, -0.153733097585334, 0},
-    {-0.587232097895999, 0.587232097895999, 0.693921283086783, 0.131614521121219, -0.693921283086783, -0.131614521121219, 0},
-    {-0.171650154436808, 0.171650154436808, 1.55954554826208, 0.0971541428643074, -1.55954554826208, -0.0971541428643074, 0},
-    {0.297781209627916, -0.297781209627916, 2.53733389052355, 0.0582285287322856, -2.53733389052355, -0.0582285287322856, 0},
-    {0.713967446876028, -0.713967446876028, 3.40421685178807, 0.0237180419639911, -3.40421685178807, -0.0237180419639911, 0},
-    {-0.548509472575657, 0.548509472575658, 0.13831575967286, 0.764665295175825, -0.13831575967286, -0.764665295175825, 0},
-    {-0.325715385209019, 0.325715385209019, 0.693921283086783, 0.654647946495179, -0.693921283086783, -0.654647946495179, 0},
-    {0.0213941377077832, -0.0213941377077827, 1.55954554826208, 0.483242727153488, -1.55954554826208, -0.483242727153489, 0},
-    {0.413480703034436, -0.413480703034436, 2.53733389052355, 0.289627515545326, -2.53733389052355, -0.289627515545326, 0},
-    {0.761094954638504, -0.761094954638504, 3.40421685178807, 0.117973057488944, -3.40421685178807, -0.117973057488944, 0},
-    {-0.0851819089672702, 0.0851819089672698, 0.13831575967286, 1.6913204223926, -0.13831575967286, -1.6913204223926, 0},
-    {0.0709502408948851, -0.0709502408948855, 0.693921283086783, 1.44797919870299, -0.693921283086783, -1.44797919870299, 0},
-    {0.314201561839691, -0.314201561839691, 1.55954554826208, 1.06885757541731, -1.55954554826208, -1.06885757541731, 0},
-    {0.588972401138389, -0.58897240113839, 2.53733389052355, 0.640610911753232, -2.53733389052355, -0.640610911753232, 0},
-    {0.832577431537388, -0.832577431537389, 3.40421685178807, 0.260938011286713, -3.40421685178807, -0.260938011286713, 0},
-    {0.411989591896581, -0.411989591896581, 0.13831575967286, 2.6856634241203, -0.13831575967286, -2.6856634241203, 0},
-    {0.496590457797377, -0.496590457797378, 0.693921283086782, 2.29925963250797, -0.693921283086782, -2.29925963250797, 0},
-    {0.628397215096318, -0.62839721509632, 1.55954554826208, 1.69724888193056, -1.55954554826208, -1.69724888193056, 0},
-    {0.777282956754789, -0.777282956754789, 2.53733389052355, 1.01723202298603, -2.53733389052355, -1.01723202298603, 0},
-    {0.909281373017809, -0.90928137301781, 3.40421685178807, 0.414345894247555, -3.40421685178807, -0.414345894247555, 0},
-    {0.809744306025695, -0.809744306025695, 0.13831575967286, 3.48117285237853, -0.13831575967286, -3.48117285237853, 0},
-    {0.837117624985641, -0.837117624985642, 0.693921283086783, 2.9803139668845, -0.693921283086783, -2.9803139668845, 0},
-    {0.879764805604937, -0.879764805604939, 1.55954554826208, 2.1999840629478, -1.55954554826208, -2.1999840629478, 0},
-    {0.92793803470385, -0.927938034703852, 2.53733389052355, 1.31854217888416, -2.53733389052355, -1.31854217888416, 0},
-    {0.97064722818672, -0.970647228186721, 3.40421685178807, 0.537077604585377, -3.40421685178807, -0.537077604585377, 0},
-    {0.144333375497977, 1.85228451823978, 0.13831575967286, 0.153733097585332, -0.13831575967286, -0.153733097585333, -1.99661789373776},
-    {0.267443674835656, 1.44190787062765, 0.693921283086783, 0.131614521121218, -0.693921283086783, -0.131614521121218, -1.70935154546331},
-    {0.459247495907997, 0.802547804781612, 1.55954554826208, 0.0971541428643074, -1.55954554826208, -0.0971541428643075, -1.26179530068961},
-    {0.675904477222819, 0.0803420579669871, 2.53733389052355, 0.058228528732286, -2.53733389052355, -0.058228528732286, -0.756246535189806},
-    {0.86798719842446, -0.559947695327595, 3.40421685178807, 0.0237180419639914, -3.40421685178807, -0.0237180419639914, -0.308039503096864},
-    {0.285315354814272, 1.38233429996559, 0.13831575967286, 0.764665295175824, -0.13831575967286, -0.764665295175825, -1.66764965477986},
-    {0.388141663660971, 1.03957243407901, 0.693921283086783, 0.654647946495179, -0.693921283086783, -0.654647946495179, -1.42771409773998},
-    {0.54834336124165, 0.505555085826084, 1.55954554826208, 0.483242727153489, -1.55954554826208, -0.483242727153489, -1.05389844706773},
-    {0.729303344235153, -0.0976580618337189, 2.53733389052355, 0.289627515545326, -2.53733389052355, -0.289627515545326, -0.631645282401434},
-    {0.889737989595075, -0.632451919681933, 3.40421685178807, 0.117973057488944, -3.40421685178807, -0.117973057488944, -0.257286069913142},
-    {0.499155244893504, 0.669519062828043, 0.13831575967286, 1.6913204223926, -0.13831575967286, -1.6913204223926, -1.16867430772155},
-    {0.571215023734067, 0.429314541944296, 0.693921283086783, 1.44797919870299, -0.693921283086783, -1.44797919870299, -1.00052956567836},
-    {0.683482973707427, 0.0550798500280444, 1.55954554826208, 1.06885757541731, -1.55954554826208, -1.06885757541731, -0.738562823735472},
-    {0.810298148731796, -0.367646653544983, 2.53733389052355, 0.640610911753232, -2.53733389052355, -0.640610911753233, -0.442651495186813},
-    {0.922729346473572, -0.742425516601205, 3.40421685178807, 0.260938011286713, -3.40421685178807, -0.260938011286713, -0.180303829872367},
-    {0.72861515068299, -0.0953640331101723, 0.13831575967286, 2.6856634241203, -0.13831575967286, -2.6856634241203, -0.633251117572818},
-    {0.767661046687841, -0.225519868906914, 0.693921283086783, 2.29925963250797, -0.693921283086783, -2.29925963250797, -0.542141177780927},
-    {0.828493910316754, -0.428300519875884, 1.55954554826208, 1.69724888193056, -1.55954554826208, -1.69724888193056, -0.40019339044087},
-    {0.897209249379815, -0.657356664129763, 2.53733389052355, 1.01723202298603, -2.53733389052355, -1.01723202298603, -0.239852585250051},
-    {0.958130569502644, -0.860432176532975, 3.40421685178807, 0.414345894247555, -3.40421685178807, -0.414345894247555, -0.0976983929696685},
-    {0.912191158303717, -0.707297453747673, 0.13831575967286, 3.48117285237853, -0.13831575967286, -3.48117285237853, -0.204893704556044},
-    {0.924824785087998, -0.749410464883284, 0.693921283086783, 2.9803139668845, -0.693921283086783, -2.9803139668845, -0.175414320204714},
-    {0.944507767781269, -0.815021843428607, 1.55954554826208, 2.1999840629478, -1.55954554826208, -2.1999840629478, -0.129485924352662},
-    {0.966741191441727, -0.889134877965975, 2.53733389052355, 1.31854217888416, -2.53733389052355, -1.31854217888416, -0.0776063134757529},
-    {0.986452794974706, -0.954841661398735, 3.40421685178807, 0.537077604585377, -3.40421685178807, -0.537077604585377, -0.0316111335759707},
-    {0.826059726268029, 2.53401086900983, 0.138315759672859, 0.153733097585331, -0.138315759672859, -0.153733097585332, -3.36007059527786},
-    {0.851085640044301, 2.0255498358363, 0.693921283086782, 0.131614521121218, -0.693921283086782, -0.131614521121218, -2.8766354758806},
-    {0.89007560200475, 1.23337591087837, 1.55954554826208, 0.0971541428643074, -1.55954554826208, -0.0971541428643075, -2.12345151288312},
-    {0.934117724902526, 0.338555305646693, 2.53733389052355, 0.0582285287322862, -2.53733389052355, -0.0582285287322862, -1.27267303054922},
-    {0.973164381799351, -0.454770511952705, 3.40421685178807, 0.0237180419639916, -3.40421685178807, -0.0237180419639916, -0.518393869846646},
-    {0.854718602717514, 1.95173754786883, 0.13831575967286, 0.764665295175824, -0.13831575967286, -0.764665295175824, -2.80645615058634},
-    {0.875621178318206, 1.52705194873624, 0.693921283086783, 0.654647946495179, -0.693921283086783, -0.654647946495179, -2.40267312705445},
-    {0.908187047234417, 0.865398771818851, 1.55954554826208, 0.483242727153489, -1.55954554826208, -0.483242727153489, -1.77358581905327},
-    {0.944972669198744, 0.118011263129871, 2.53733389052355, 0.289627515545326, -2.53733389052355, -0.289627515545326, -1.06298393232862},
-    {0.977585891838153, -0.544604017438855, 3.40421685178807, 0.117973057488944, -3.40421685178807, -0.117973057488944, -0.432981874399298},
-    {0.898188066116116, 1.06855188405065, 0.13831575967286, 1.6913204223926, -0.13831575967286, -1.6913204223926, -1.96673995016677},
-    {0.91283640847011, 0.77093592668034, 0.693921283086783, 1.44797919870299, -0.693921283086783, -1.44797919870299, -1.68377233515045},
-    {0.935658284876776, 0.307255161197392, 1.55954554826208, 1.06885757541731, -1.55954554826208, -1.06885757541731, -1.24291344607417},
-    {0.961437327351342, -0.216507474925437, 2.53733389052355, 0.640610911753233, -2.53733389052355, -0.640610911753233, -0.744929852425905},
-    {0.984292388833492, -0.680862474241285, 3.40421685178807, 0.260938011286713, -3.40421685178807, -0.260938011286713, -0.303429914592208},
-    {0.944832772922068, 0.120853589128905, 0.13831575967286, 2.6856634241203, -0.13831575967286, -2.6856634241203, -1.06568636205097},
-    {0.952770039194603, -0.0404108764001523, 0.693921283086783, 2.29925963250797, -0.693921283086783, -2.29925963250797, -0.912359162794451},
-    {0.965136169470714, -0.291658260721924, 1.55954554826208, 1.69724888193056, -1.55954554826208, -1.69724888193056, -0.673477908748791},
-    {0.979104652690648, -0.57546126081893, 2.53733389052355, 1.01723202298603, -2.53733389052355, -1.01723202298603, -0.403643391871719},
-    {0.991488764440297, -0.827073981595322, 3.40421685178807, 0.414345894247555, -3.40421685178807, -0.414345894247555, -0.164414782844975},
-    {0.982150181480284, -0.637338430571106, 0.13831575967286, 3.48117285237853, -0.13831575967286, -3.48117285237853, -0.344811750909179},
-    {0.984718350482276, -0.689516899489006, 0.693921283086783, 2.9803139668845, -0.693921283086783, -2.9803139668845, -0.29520145099327},
-    {0.98871951553826, -0.770810095671616, 1.55954554826208, 2.1999840629478, -1.55954554826208, -2.1999840629478, -0.217909419866644},
-    {0.993239135313952, -0.86263693409375, 2.53733389052355, 1.31854217888416, -2.53733389052355, -1.31854217888416, -0.130602201220202},
-    {0.99724611842635, -0.944048337947091, 3.40421685178807, 0.537077604585377, -3.40421685178807, -0.537077604585377, -0.0531977804792586}};
-    
-    // Array of non-zero columns
-    static const unsigned int nzc3[7] = {0, 1, 5, 6, 7, 8, 9};
-    
-    // Number of operations to compute geometry constants: 43
-    const double G0 = det*(Jinv_10*Jinv_20 + Jinv_11*Jinv_21 + Jinv_12*Jinv_22);
-    const double G1 = det*(Jinv_10*Jinv_10 + Jinv_11*Jinv_11 + Jinv_12*Jinv_12);
-    const double G2 = -Jinv_12*det;
-    const double G3 = det*(Jinv_00*Jinv_10 + Jinv_01*Jinv_11 + Jinv_02*Jinv_12);
-    const double G4 = -0.5*det*w[1][0]*w[2][0];
-    const double G5 = det*(Jinv_20*Jinv_20 + Jinv_21*Jinv_21 + Jinv_22*Jinv_22);
-    const double G6 = -Jinv_22*det;
-    const double G7 = det*(Jinv_00*Jinv_20 + Jinv_01*Jinv_21 + Jinv_02*Jinv_22);
-    const double G8 = -Jinv_02*det;
-    const double G9 = det*(Jinv_00*Jinv_00 + Jinv_01*Jinv_01 + Jinv_02*Jinv_02);
-    const double G10 = 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: 25043
-    
-    // Loop quadrature points for integral
-    // Number of operations to compute element tensor for following IP loop = 25000
-    for (unsigned int ip = 0; ip < 125; ip++)
-    {
-      
-      // Function declarations
-      double F0 = 0;
-      double F1 = 0;
-      double F2 = 0;
-      double F3 = 0;
-      double F4 = 0;
-      
-      // Total number of operations to compute function values = 40
-      for (unsigned int r = 0; r < 10; r++)
-      {
-        F0 += FE1_C0[ip][r]*w[0][nzc4[r]];
-        F1 += FE1_C0[ip][r]*w[0][nzc0[r]];
-      }// end loop over 'r'
-      
-      // Total number of operations to compute function values = 42
-      for (unsigned int r = 0; r < 7; r++)
-      {
-        F2 += FE1_C0_D100[ip][r]*w[0][nzc3[r]];
-        F3 += FE1_C0_D010[ip][r]*w[0][nzc2[r]];
-        F4 += FE1_C0_D001[ip][r]*w[0][nzc1[r]];
-      }// end loop over 'r'
-      
-      // Number of operations to compute ip constants: 36
-      // Number of operations: 10
-      const double Gip0 = F0*F0*F0*W125[ip]*(G2 + F2*G3 + F3*G1 + F4*G0);
-      
-      // Number of operations: 4
-      const double Gip1 = W125[ip]*(F0*det + F1*G4);
-      
-      // Number of operations: 10
-      const double Gip2 = F0*F0*F0*W125[ip]*(G6 + F2*G7 + F3*G0 + F4*G5);
-      
-      // Number of operations: 10
-      const double Gip3 = F0*F0*F0*W125[ip]*(G8 + F2*G9 + F3*G3 + F4*G7);
-      
-      // Number of operations: 2
-      const double Gip4 = F1*G10*W125[ip];
-      
-      
-      // Number of operations for primary indices: 40
-      for (unsigned int j = 0; j < 10; j++)
-      {
-        // Number of operations to compute entry: 2
-        A[nzc4[j]] += FE1_C0[ip][j]*Gip1;
-        // Number of operations to compute entry: 2
-        A[nzc0[j]] += FE1_C0[ip][j]*Gip4;
-      }// end loop over 'j'
-      
-      // Number of operations for primary indices: 42
-      for (unsigned int j = 0; j < 7; j++)
-      {
-        // Number of operations to compute entry: 2
-        A[nzc2[j]] += FE1_C0_D010[ip][j]*Gip0;
-        // Number of operations to compute entry: 2
-        A[nzc1[j]] += FE1_C0_D001[ip][j]*Gip2;
-        // Number of operations to compute entry: 2
-        A[nzc3[j]] += FE1_C0_D100[ip][j]*Gip3;
-      }// end loop over 'j'
-    }// end loop over 'ip'
-}
-
-/// Constructor
-solitarywave3d_1_cell_integral_0::solitarywave3d_1_cell_integral_0() : ufc::cell_integral()
-{
-    // Do nothing
-}
-
-/// Destructor
-solitarywave3d_1_cell_integral_0::~solitarywave3d_1_cell_integral_0()
-{
-    // Do nothing
-}
-
-/// Tabulate the tensor for the contribution from a local cell
-void solitarywave3d_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 < 20; j++)
-      A[j] = 0;
-    
-    // Add all contributions to element tensor
-    integral_0_quadrature.tabulate_tensor(A, w, c);
-}
-
-/// Constructor
-solitarywave3d_1_exterior_facet_integral_0_quadrature::solitarywave3d_1_exterior_facet_integral_0_quadrature() : ufc::exterior_facet_integral()
-{
-    // Do nothing
-}
-
-/// Destructor
-solitarywave3d_1_exterior_facet_integral_0_quadrature::~solitarywave3d_1_exterior_facet_integral_0_quadrature()
-{
-    // Do nothing
-}
-
-/// Tabulate the tensor for the contribution from a local exterior facet
-void solitarywave3d_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
-    
-    // Compute sub determinants
-    
-    
-    
-    // Compute determinant of Jacobian
-    
-    // Compute inverse of Jacobian
-    
-    // Vertices on faces
-    static unsigned int face_vertices[4][3] = {{1, 2, 3}, {0, 2, 3}, {0, 1, 3}, {0, 1, 2}};
-    
-    // Get vertices
-    const unsigned int v0 = face_vertices[facet][0];
-    const unsigned int v1 = face_vertices[facet][1];
-    const unsigned int v2 = face_vertices[facet][2];
-    
-    // Compute scale factor (area of face scaled by area of reference triangle)
-    const double a0 = (x[v0][1]*x[v1][2] + x[v0][2]*x[v2][1] + x[v1][1]*x[v2][2])
-                  - (x[v2][1]*x[v1][2] + x[v2][2]*x[v0][1] + x[v1][1]*x[v0][2]);
-    const double a1 = (x[v0][2]*x[v1][0] + x[v0][0]*x[v2][2] + x[v1][2]*x[v2][0])
-                  - (x[v2][2]*x[v1][0] + x[v2][0]*x[v0][2] + x[v1][2]*x[v0][0]);
-    const double a2 = (x[v0][0]*x[v1][1] + x[v0][1]*x[v2][0] + x[v1][0]*x[v2][1])
-                  - (x[v2][0]*x[v1][1] + x[v2][1]*x[v0][0] + x[v1][0]*x[v0][1]);
-    const double det = std::sqrt(a0*a0 + a1*a1 + a2*a2);
-    
-    const bool direction = a0*(x[facet][0] - x[v0][0]) + a1*(x[facet][1] - x[v0][1])  + a2*(x[facet][2] - x[v0][2]) < 0;
-    // Compute facet normals from the facet scale factor constants
-    const double n2 = direction ? a2 / det : -a2 / det;
-    
-    
-    // Array of quadrature weights
-    static const double W25[25] = {0.0114650803515925, 0.0198040831320473, 0.0173415064313656, 0.0087554991821638, 0.00186555216687783, 0.0231612219294983, 0.0400072873861603, 0.0350325045033716, 0.0176874521104834, 0.0037687016953276, 0.0275289856644697, 0.0475518970579538, 0.0416389652151948, 0.021022967487322, 0.00447940679728133, 0.0231612219294983, 0.0400072873861603, 0.0350325045033716, 0.0176874521104834, 0.0037687016953276, 0.0114650803515925, 0.0198040831320473, 0.0173415064313656, 0.0087554991821638, 0.00186555216687783};
-    // Quadrature points on the UFC reference element: (0.0450425935698037, 0.0398098570514687), (0.0376212523451112, 0.198013417873608), (0.0263646449444709, 0.437974810247386), (0.0142857943955714, 0.695464273353636), (0.00462228846504642, 0.901464914201174), (0.221578609552379, 0.0398098570514687), (0.185070710267389, 0.198013417873608), (0.129695936782254, 0.437974810247386), (0.0702762920082817, 0.695464273353636), (0.022738483063764, 0.901464914201174), (0.480095071474266, 0.0398098570514687), (0.400993291063196, 0.198013417873608), (0.281012594876307, 0.437974810247386), (0.152267863323182, 0.695464273353636), (0.0492675428994132, 0.901464914201174), (0.738611533396152, 0.0398098570514687), (0.616915871859002, 0.198013417873608), (0.43232925297036, 0.437974810247386), (0.234259434638082, 0.695464273353636), (0.0757966027350624, 0.901464914201174), (0.915147549378728, 0.0398098570514687), (0.764365329781281, 0.198013417873608), (0.535660544808143, 0.437974810247386), (0.290249932250792, 0.695464273353636), (0.09391279733378, 0.901464914201174)
-    
-    // Value of basis functions at quadrature points.
-    static const double FE0_f0_C0[25][6] = \
-    {{0.759842524889053, -0.0409849230988147, -0.036640207614552, 0.00717255684496518, 0.145727572487076, 0.164882476492272},
-    {0.404143384962011, -0.0347905350890821, -0.119594790557632, 0.0297980510461638, 0.605418365816316, 0.115025523822223},
-    {0.0382038937201701, -0.0249744559383749, -0.0543309414249184, 0.0461882014671774, 0.938423301877432, 0.0564900002985142},
-    {-0.121759885907613, -0.0138776265525463, 0.271876837668966, 0.0397410384743819, 0.807433832894958, 0.0165858034218534},
-    {-0.0762735703276686, -0.00457955736373825, 0.723813068870285, 0.0166673234982245, 0.338636367163553, 0.00173636815934473},
-    {0.352482461135478, -0.123384449130048, -0.036640207614552, 0.0352840510877737, 0.117616078244268, 0.65464206627708},
-    {0.144254514044104, -0.116568374669637, -0.119594790557632, 0.146585935553368, 0.488630481309112, 0.456692234320685},
-    {-0.0585120870225411, -0.0960538647466012, -0.0543309414249184, 0.227214213208259, 0.75739729013635, 0.224285389849452},
-    {-0.124504469204174, -0.0603987775714152, 0.271876837668966, 0.19549860142211, 0.65167626994723, 0.0658515377372834},
-    {-0.0643063527627086, -0.0217044058396819, 0.723813068870285, 0.0819917787365634, 0.273311911925214, 0.00689399907032827},
-    {-0.0191125161665051, -0.0191125161665051, -0.036640207614552, 0.0764500646660208, 0.0764500646660208, 0.921965110615521},
-    {-0.0794020521078099, -0.07940205210781, -0.119594790557632, 0.31760820843124, 0.31760820843124, 0.643182477910772},
-    {-0.123076437918076, -0.123076437918076, -0.0543309414249184, 0.492305751672305, 0.492305751672305, 0.315872313916461},
-    {-0.105896858921167, -0.105896858921168, 0.271876837668966, 0.42358743568467, 0.42358743568467, 0.0927420088040289},
-    {-0.0444129613327221, -0.0444129613327222, 0.723813068870285, 0.177651845330889, 0.177651845330888, 0.0097091631333821},
-    {-0.123384449130048, 0.352482461135478, -0.036640207614552, 0.117616078244268, 0.0352840510877739, 0.65464206627708},
-    {-0.116568374669637, 0.144254514044103, -0.119594790557632, 0.488630481309112, 0.146585935553368, 0.456692234320685},
-    {-0.0960538647466012, -0.0585120870225412, -0.0543309414249184, 0.75739729013635, 0.227214213208259, 0.224285389849452},
-    {-0.0603987775714152, -0.124504469204174, 0.271876837668966, 0.65167626994723, 0.195498601422111, 0.0658515377372834},
-    {-0.0217044058396818, -0.0643063527627087, 0.723813068870285, 0.273311911925214, 0.0819917787365635, 0.00689399907032831},
-    {-0.0409849230988147, 0.759842524889053, -0.036640207614552, 0.145727572487076, 0.00717255684496533, 0.164882476492272},
-    {-0.0347905350890821, 0.404143384962011, -0.119594790557632, 0.605418365816316, 0.029798051046164, 0.115025523822223},
-    {-0.024974455938375, 0.0382038937201699, -0.0543309414249184, 0.938423301877431, 0.0461882014671778, 0.0564900002985144},
-    {-0.0138776265525463, -0.121759885907613, 0.271876837668966, 0.807433832894958, 0.0397410384743823, 0.0165858034218534},
-    {-0.00457955736373818, -0.0762735703276687, 0.723813068870285, 0.338636367163553, 0.0166673234982247, 0.00173636815934472}};
-    
-    // Array of non-zero columns
-    static const unsigned int nzc1[6] = {11, 12, 13, 14, 15, 16};
-    // Array of non-zero columns
-    static const unsigned int nzc0[6] = {1, 2, 3, 4, 5, 6};
-    // Array of non-zero columns
-    static const unsigned int nzc5[6] = {10, 11, 13, 15, 17, 19};
-    // Array of non-zero columns
-    static const unsigned int nzc4[6] = {0, 1, 3, 5, 7, 9};
-    // Array of non-zero columns
-    static const unsigned int nzc2[6] = {0, 2, 3, 4, 7, 8};
-    // Array of non-zero columns
-    static const unsigned int nzc3[6] = {10, 12, 13, 14, 17, 18};
-    // Array of non-zero columns
-    static const unsigned int nzc6[6] = {0, 1, 2, 6, 8, 9};
-    // Array of non-zero columns
-    static const unsigned int nzc7[6] = {10, 11, 12, 16, 18, 19};
-    
     // Number of operations to compute geometry constants: 1
     // Should be added to total operation count.
     const double G0 = det*n2;



More information about the CIG-COMMITS mailing list