← Back to team overview

fenics team mailing list archive

Re: Patch for changed Python interface of Expressions

 

Patch applied

--
Anders


On Mon, Sep 06, 2010 at 08:44:59AM -0700, Johan Hake wrote:
> I also draged in some changes done in the C++ source code of la/eigenvalue.
>
> Johan

> # Bazaar merge directive format 2 (Bazaar 0.90)
> # revision_id: hake.dev@xxxxxxxxx-20100906154049-idue489k83pizp0n
> # target_branch: bzr+ssh://bazaar.launchpad.net/~fenics-core/fenics-\
> #   doc/main/
> # testament_sha1: 624bff4ed92bd2ceeef59bda34f7782bf777a0e4
> # timestamp: 2010-09-06 08:42:44 -0700
> # base_revision_id: k.b.oelgaard@xxxxxxxxx-20100902125002-\
> #   ciqdciv4nc1e145w
> #
> # Begin patch
> === modified file 'source/demos/la/eigenvalue/cpp/StiffnessMatrix.h'
> --- source/demos/la/eigenvalue/cpp/StiffnessMatrix.h	2010-09-01 15:13:40 +0000
> +++ source/demos/la/eigenvalue/cpp/StiffnessMatrix.h	2010-09-06 15:40:49 +0000
> @@ -1,5 +1,5 @@
> -// This code conforms with the UFC specification version 1.4
> -// and was automatically generated by FFC version 0.9.2+.
> +// This code conforms with the UFC specification version 1.4.2
> +// and was automatically generated by FFC version 0.9.4+.
>  //
>  // This code was generated with the option '-l dolfin' and
>  // contains DOLFIN-specific wrappers that depend on DOLFIN.
> @@ -9,12 +9,13 @@
>  //   cache_dir:                      ''
>  //   convert_exceptions_to_warnings: False
>  //   cpp_optimize:                   False
> +//   cpp_optimize_flags:             '-O2'
>  //   epsilon:                        1e-14
>  //   form_postfix:                   True
>  //   format:                         'dolfin'
> -//   log_level:                      10
> +//   log_level:                      20
>  //   log_prefix:                     ''
> -//   optimize:                       True
> +//   optimize:                       False
>  //   output_dir:                     '.'
>  //   precision:                      15
>  //   quadrature_degree:              'auto'
> @@ -51,19 +52,19 @@
>    /// Return a string identifying the finite element
>    virtual const char* signature() const
>    {
> -    return "FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)";
> +    return "FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1)";
>    }
>
>    /// Return the cell shape
>    virtual ufc::shape cell_shape() const
>    {
> -    return ufc::triangle;
> +    return ufc::tetrahedron;
>    }
>
>    /// Return the dimension of the finite element function space
>    virtual unsigned int space_dimension() const
>    {
> -    return 3;
> +    return 4;
>    }
>
>    /// Return the rank of the value space
> @@ -90,21 +91,40 @@
>      // 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*J_11 - J_01*J_10;
> +    double detJ = J_00*d_00 + J_10*d_10 + J_20*d_20;
>
>      // Compute inverse of Jacobian
>
>      // Compute constants
> -    const double C0 = x[1][0] + x[2][0];
> -    const double C1 = x[1][1] + x[2][1];
> +    const double C0 = x[3][0] + x[2][0] + x[1][0] - x[0][0];
> +    const double C1 = x[3][1] + x[2][1] + x[1][1] - x[0][1];
> +    const double C2 = x[3][2] + x[2][2] + x[1][2] - x[0][2];
>
>      // Get coordinates and map to the reference (FIAT) element
> -    double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ;
> -    double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ;
> +    double X = (d_00*(2.0*coordinates[0] - C0) + d_10*(2.0*coordinates[1] - C1) + d_20*(2.0*coordinates[2] - C2)) / detJ;
> +    double Y = (d_01*(2.0*coordinates[0] - C0) + d_11*(2.0*coordinates[1] - C1) + d_21*(2.0*coordinates[2] - C2)) / detJ;
> +    double Z = (d_02*(2.0*coordinates[0] - C0) + d_12*(2.0*coordinates[1] - C1) + d_22*(2.0*coordinates[2] - C2)) / detJ;
> +
>
>      // Reset values.
>      *values = 0.000000000000000;
> @@ -114,37 +134,49 @@
>        {
>
>        // Array of basisvalues.
> -      double basisvalues[3] = {0.000000000000000, 0.000000000000000, 0.000000000000000};
> +      double basisvalues[4] = {0.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000};
>
>        // Declare helper variables.
>        unsigned int rr = 0;
>        unsigned int ss = 0;
> -      double tmp0 = (1.000000000000000 + Y + 2.000000000000000*X)/2.000000000000000;
> +      double tmp0 = 0.500000000000000*(2.000000000000000 + Y + Z + 2.000000000000000*X);
>
>        // Compute basisvalues.
>        basisvalues[0] = 1.000000000000000;
>        basisvalues[1] = tmp0;
>        for (unsigned int r = 0; r < 1; r++)
>        {
> -        rr = (r + 1)*(r + 1 + 1)/2 + 1;
> -        ss = r*(r + 1)/2;
> -        basisvalues[rr] = basisvalues[ss]*(0.500000000000000 + r + Y*(1.500000000000000 + r));
> +        rr = (r + 1)*(r + 1 + 1)*(r + 1 + 2)/6 + 1*(1 + 1)/2;
> +        ss = r*(r + 1)*(r + 2)/6;
> +        basisvalues[rr] = basisvalues[ss]*(r*(1.000000000000000 + Y) + (2.000000000000000 + Z + 3.000000000000000*Y)/2.000000000000000);
> +      }// end loop over 'r'
> +      for (unsigned int r = 0; r < 1; r++)
> +      {
> +        for (unsigned int s = 0; s < 1 - r; s++)
> +        {
> +          rr = (r + s + 1)*(r + s + 1 + 1)*(r + s + 1 + 2)/6 + (s + 1)*(s + 1 + 1)/2 + 1;
> +          ss = (r + s)*(r + s + 1)*(r + s + 2)/6 + s*(s + 1)/2;
> +          basisvalues[rr] = basisvalues[ss]*(1.000000000000000 + r + s + Z*(2.000000000000000 + r + s));
> +        }// end loop over 's'
>        }// end loop over 'r'
>        for (unsigned int r = 0; r < 2; r++)
>        {
>          for (unsigned int s = 0; s < 2 - r; s++)
>          {
> -          rr = (r + s)*(r + s + 1)/2 + s;
> -          basisvalues[rr] *= std::sqrt((0.500000000000000 + r)*(1.000000000000000 + r + s));
> +          for (unsigned int t = 0; t < 2 - r - s; t++)
> +          {
> +            rr = (r + s + t)*(r + s + t + 1)*(r + s + t + 2)/6 + (s + t)*(s + t + 1)/2 + t;
> +            basisvalues[rr] *= std::sqrt((0.500000000000000 + r)*(1.000000000000000 + r + s)*(1.500000000000000 + r + s + t));
> +          }// end loop over 't'
>          }// end loop over 's'
>        }// end loop over 'r'
>
>        // Table(s) of coefficients.
> -      static const double coefficients0[3] = \
> -      {0.471404520791032, -0.288675134594813, -0.166666666666667};
> +      static const double coefficients0[4] = \
> +      {0.288675134594813, -0.182574185835055, -0.105409255338946, -0.074535599249993};
>
>        // Compute value(s).
> -      for (unsigned int r = 0; r < 3; r++)
> +      for (unsigned int r = 0; r < 4; r++)
>        {
>          *values += coefficients0[r]*basisvalues[r];
>        }// end loop over 'r'
> @@ -154,37 +186,49 @@
>        {
>
>        // Array of basisvalues.
> -      double basisvalues[3] = {0.000000000000000, 0.000000000000000, 0.000000000000000};
> +      double basisvalues[4] = {0.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000};
>
>        // Declare helper variables.
>        unsigned int rr = 0;
>        unsigned int ss = 0;
> -      double tmp0 = (1.000000000000000 + Y + 2.000000000000000*X)/2.000000000000000;
> +      double tmp0 = 0.500000000000000*(2.000000000000000 + Y + Z + 2.000000000000000*X);
>
>        // Compute basisvalues.
>        basisvalues[0] = 1.000000000000000;
>        basisvalues[1] = tmp0;
>        for (unsigned int r = 0; r < 1; r++)
>        {
> -        rr = (r + 1)*(r + 1 + 1)/2 + 1;
> -        ss = r*(r + 1)/2;
> -        basisvalues[rr] = basisvalues[ss]*(0.500000000000000 + r + Y*(1.500000000000000 + r));
> +        rr = (r + 1)*(r + 1 + 1)*(r + 1 + 2)/6 + 1*(1 + 1)/2;
> +        ss = r*(r + 1)*(r + 2)/6;
> +        basisvalues[rr] = basisvalues[ss]*(r*(1.000000000000000 + Y) + (2.000000000000000 + Z + 3.000000000000000*Y)/2.000000000000000);
> +      }// end loop over 'r'
> +      for (unsigned int r = 0; r < 1; r++)
> +      {
> +        for (unsigned int s = 0; s < 1 - r; s++)
> +        {
> +          rr = (r + s + 1)*(r + s + 1 + 1)*(r + s + 1 + 2)/6 + (s + 1)*(s + 1 + 1)/2 + 1;
> +          ss = (r + s)*(r + s + 1)*(r + s + 2)/6 + s*(s + 1)/2;
> +          basisvalues[rr] = basisvalues[ss]*(1.000000000000000 + r + s + Z*(2.000000000000000 + r + s));
> +        }// end loop over 's'
>        }// end loop over 'r'
>        for (unsigned int r = 0; r < 2; r++)
>        {
>          for (unsigned int s = 0; s < 2 - r; s++)
>          {
> -          rr = (r + s)*(r + s + 1)/2 + s;
> -          basisvalues[rr] *= std::sqrt((0.500000000000000 + r)*(1.000000000000000 + r + s));
> +          for (unsigned int t = 0; t < 2 - r - s; t++)
> +          {
> +            rr = (r + s + t)*(r + s + t + 1)*(r + s + t + 2)/6 + (s + t)*(s + t + 1)/2 + t;
> +            basisvalues[rr] *= std::sqrt((0.500000000000000 + r)*(1.000000000000000 + r + s)*(1.500000000000000 + r + s + t));
> +          }// end loop over 't'
>          }// end loop over 's'
>        }// end loop over 'r'
>
>        // Table(s) of coefficients.
> -      static const double coefficients0[3] = \
> -      {0.471404520791032, 0.288675134594813, -0.166666666666667};
> +      static const double coefficients0[4] = \
> +      {0.288675134594813, 0.182574185835055, -0.105409255338946, -0.074535599249993};
>
>        // Compute value(s).
> -      for (unsigned int r = 0; r < 3; r++)
> +      for (unsigned int r = 0; r < 4; r++)
>        {
>          *values += coefficients0[r]*basisvalues[r];
>        }// end loop over 'r'
> @@ -194,37 +238,101 @@
>        {
>
>        // Array of basisvalues.
> -      double basisvalues[3] = {0.000000000000000, 0.000000000000000, 0.000000000000000};
> -
> -      // Declare helper variables.
> -      unsigned int rr = 0;
> -      unsigned int ss = 0;
> -      double tmp0 = (1.000000000000000 + Y + 2.000000000000000*X)/2.000000000000000;
> -
> -      // Compute basisvalues.
> -      basisvalues[0] = 1.000000000000000;
> -      basisvalues[1] = tmp0;
> -      for (unsigned int r = 0; r < 1; r++)
> -      {
> -        rr = (r + 1)*(r + 1 + 1)/2 + 1;
> -        ss = r*(r + 1)/2;
> -        basisvalues[rr] = basisvalues[ss]*(0.500000000000000 + r + Y*(1.500000000000000 + r));
> -      }// end loop over 'r'
> -      for (unsigned int r = 0; r < 2; r++)
> -      {
> -        for (unsigned int s = 0; s < 2 - r; s++)
> -        {
> -          rr = (r + s)*(r + s + 1)/2 + s;
> -          basisvalues[rr] *= std::sqrt((0.500000000000000 + r)*(1.000000000000000 + r + s));
> -        }// end loop over 's'
> -      }// end loop over 'r'
> -
> -      // Table(s) of coefficients.
> -      static const double coefficients0[3] = \
> -      {0.471404520791032, 0.000000000000000, 0.333333333333333};
> -
> -      // Compute value(s).
> -      for (unsigned int r = 0; r < 3; r++)
> +      double basisvalues[4] = {0.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000};
> +
> +      // Declare helper variables.
> +      unsigned int rr = 0;
> +      unsigned int ss = 0;
> +      double tmp0 = 0.500000000000000*(2.000000000000000 + Y + Z + 2.000000000000000*X);
> +
> +      // Compute basisvalues.
> +      basisvalues[0] = 1.000000000000000;
> +      basisvalues[1] = tmp0;
> +      for (unsigned int r = 0; r < 1; r++)
> +      {
> +        rr = (r + 1)*(r + 1 + 1)*(r + 1 + 2)/6 + 1*(1 + 1)/2;
> +        ss = r*(r + 1)*(r + 2)/6;
> +        basisvalues[rr] = basisvalues[ss]*(r*(1.000000000000000 + Y) + (2.000000000000000 + Z + 3.000000000000000*Y)/2.000000000000000);
> +      }// end loop over 'r'
> +      for (unsigned int r = 0; r < 1; r++)
> +      {
> +        for (unsigned int s = 0; s < 1 - r; s++)
> +        {
> +          rr = (r + s + 1)*(r + s + 1 + 1)*(r + s + 1 + 2)/6 + (s + 1)*(s + 1 + 1)/2 + 1;
> +          ss = (r + s)*(r + s + 1)*(r + s + 2)/6 + s*(s + 1)/2;
> +          basisvalues[rr] = basisvalues[ss]*(1.000000000000000 + r + s + Z*(2.000000000000000 + r + s));
> +        }// end loop over 's'
> +      }// end loop over 'r'
> +      for (unsigned int r = 0; r < 2; r++)
> +      {
> +        for (unsigned int s = 0; s < 2 - r; s++)
> +        {
> +          for (unsigned int t = 0; t < 2 - r - s; t++)
> +          {
> +            rr = (r + s + t)*(r + s + t + 1)*(r + s + t + 2)/6 + (s + t)*(s + t + 1)/2 + t;
> +            basisvalues[rr] *= std::sqrt((0.500000000000000 + r)*(1.000000000000000 + r + s)*(1.500000000000000 + r + s + t));
> +          }// end loop over 't'
> +        }// end loop over 's'
> +      }// end loop over 'r'
> +
> +      // Table(s) of coefficients.
> +      static const double coefficients0[4] = \
> +      {0.288675134594813, 0.000000000000000, 0.210818510677892, -0.074535599249993};
> +
> +      // Compute value(s).
> +      for (unsigned int r = 0; r < 4; r++)
> +      {
> +        *values += coefficients0[r]*basisvalues[r];
> +      }// end loop over 'r'
> +        break;
> +      }
> +    case 3:
> +      {
> +
> +      // Array of basisvalues.
> +      double basisvalues[4] = {0.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000};
> +
> +      // Declare helper variables.
> +      unsigned int rr = 0;
> +      unsigned int ss = 0;
> +      double tmp0 = 0.500000000000000*(2.000000000000000 + Y + Z + 2.000000000000000*X);
> +
> +      // Compute basisvalues.
> +      basisvalues[0] = 1.000000000000000;
> +      basisvalues[1] = tmp0;
> +      for (unsigned int r = 0; r < 1; r++)
> +      {
> +        rr = (r + 1)*(r + 1 + 1)*(r + 1 + 2)/6 + 1*(1 + 1)/2;
> +        ss = r*(r + 1)*(r + 2)/6;
> +        basisvalues[rr] = basisvalues[ss]*(r*(1.000000000000000 + Y) + (2.000000000000000 + Z + 3.000000000000000*Y)/2.000000000000000);
> +      }// end loop over 'r'
> +      for (unsigned int r = 0; r < 1; r++)
> +      {
> +        for (unsigned int s = 0; s < 1 - r; s++)
> +        {
> +          rr = (r + s + 1)*(r + s + 1 + 1)*(r + s + 1 + 2)/6 + (s + 1)*(s + 1 + 1)/2 + 1;
> +          ss = (r + s)*(r + s + 1)*(r + s + 2)/6 + s*(s + 1)/2;
> +          basisvalues[rr] = basisvalues[ss]*(1.000000000000000 + r + s + Z*(2.000000000000000 + r + s));
> +        }// end loop over 's'
> +      }// end loop over 'r'
> +      for (unsigned int r = 0; r < 2; r++)
> +      {
> +        for (unsigned int s = 0; s < 2 - r; s++)
> +        {
> +          for (unsigned int t = 0; t < 2 - r - s; t++)
> +          {
> +            rr = (r + s + t)*(r + s + t + 1)*(r + s + t + 2)/6 + (s + t)*(s + t + 1)/2 + t;
> +            basisvalues[rr] *= std::sqrt((0.500000000000000 + r)*(1.000000000000000 + r + s)*(1.500000000000000 + r + s + t));
> +          }// end loop over 't'
> +        }// end loop over 's'
> +      }// end loop over 'r'
> +
> +      // Table(s) of coefficients.
> +      static const double coefficients0[4] = \
> +      {0.288675134594813, 0.000000000000000, 0.000000000000000, 0.223606797749979};
> +
> +      // Compute value(s).
> +      for (unsigned int r = 0; r < 4; r++)
>        {
>          *values += coefficients0[r]*basisvalues[r];
>        }// end loop over 'r'
> @@ -243,7 +351,7 @@
>      double dof_values = 0.000000000000000;
>
>      // Loop dofs and call evaluate_basis.
> -    for (unsigned int r = 0; r < 3; r++)
> +    for (unsigned int r = 0; r < 4; r++)
>      {
>        evaluate_basis(r, &dof_values, coordinates, c);
>        values[r] = dof_values;
> @@ -263,31 +371,55 @@
>      // 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*J_11 - J_01*J_10;
> +    double detJ = J_00*d_00 + J_10*d_10 + J_20*d_20;
>
>      // Compute inverse of Jacobian
> -    const double K_00 =  J_11 / detJ;
> -    const double K_01 = -J_01 / detJ;
> -    const double K_10 = -J_10 / detJ;
> -    const double K_11 =  J_00 / detJ;
> +    const double K_00 = d_00 / detJ;
> +    const double K_01 = d_10 / detJ;
> +    const double K_02 = d_20 / detJ;
> +    const double K_10 = d_01 / detJ;
> +    const double K_11 = d_11 / detJ;
> +    const double K_12 = d_21 / detJ;
> +    const double K_20 = d_02 / detJ;
> +    const double K_21 = d_12 / detJ;
> +    const double K_22 = d_22 / detJ;
>
>      // Compute constants
> -    const double C0 = x[1][0] + x[2][0];
> -    const double C1 = x[1][1] + x[2][1];
> +    const double C0 = x[3][0] + x[2][0] + x[1][0] - x[0][0];
> +    const double C1 = x[3][1] + x[2][1] + x[1][1] - x[0][1];
> +    const double C2 = x[3][2] + x[2][2] + x[1][2] - x[0][2];
>
>      // Get coordinates and map to the reference (FIAT) element
> -    double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ;
> -    double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ;
> +    double X = (d_00*(2.0*coordinates[0] - C0) + d_10*(2.0*coordinates[1] - C1) + d_20*(2.0*coordinates[2] - C2)) / detJ;
> +    double Y = (d_01*(2.0*coordinates[0] - C0) + d_11*(2.0*coordinates[1] - C1) + d_21*(2.0*coordinates[2] - C2)) / detJ;
> +    double Z = (d_02*(2.0*coordinates[0] - C0) + d_12*(2.0*coordinates[1] - C1) + d_22*(2.0*coordinates[2] - C2)) / detJ;
> +
>
>      // Compute number of derivatives.
>      unsigned int num_derivatives = 1;
>      for (unsigned int r = 0; r < n; r++)
>      {
> -      num_derivatives *= 2;
> +      num_derivatives *= 3;
>      }// end loop over 'r'
>
>      // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
> @@ -306,7 +438,7 @@
>        {
>          for (unsigned int col = n-1; col+1 > 0; col--)
>          {
> -          if (combinations[row][col] + 1 > 1)
> +          if (combinations[row][col] + 1 > 2)
>              combinations[row][col] = 0;
>            else
>            {
> @@ -318,7 +450,7 @@
>      }
>
>      // Compute inverse of Jacobian
> -    const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}};
> +    const double Jinv[3][3] = {{K_00, K_01, K_02}, {K_10, K_11, K_12}, {K_20, K_21, K_22}};
>
>      // Declare transformation matrix
>      // Declare pointer to two dimensional array and initialise
> @@ -353,45 +485,65 @@
>        {
>
>        // Array of basisvalues.
> -      double basisvalues[3] = {0.000000000000000, 0.000000000000000, 0.000000000000000};
> +      double basisvalues[4] = {0.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000};
>
>        // Declare helper variables.
>        unsigned int rr = 0;
>        unsigned int ss = 0;
> -      double tmp0 = (1.000000000000000 + Y + 2.000000000000000*X)/2.000000000000000;
> +      double tmp0 = 0.500000000000000*(2.000000000000000 + Y + Z + 2.000000000000000*X);
>
>        // Compute basisvalues.
>        basisvalues[0] = 1.000000000000000;
>        basisvalues[1] = tmp0;
>        for (unsigned int r = 0; r < 1; r++)
>        {
> -        rr = (r + 1)*(r + 1 + 1)/2 + 1;
> -        ss = r*(r + 1)/2;
> -        basisvalues[rr] = basisvalues[ss]*(0.500000000000000 + r + Y*(1.500000000000000 + r));
> +        rr = (r + 1)*(r + 1 + 1)*(r + 1 + 2)/6 + 1*(1 + 1)/2;
> +        ss = r*(r + 1)*(r + 2)/6;
> +        basisvalues[rr] = basisvalues[ss]*(r*(1.000000000000000 + Y) + (2.000000000000000 + Z + 3.000000000000000*Y)/2.000000000000000);
> +      }// end loop over 'r'
> +      for (unsigned int r = 0; r < 1; r++)
> +      {
> +        for (unsigned int s = 0; s < 1 - r; s++)
> +        {
> +          rr = (r + s + 1)*(r + s + 1 + 1)*(r + s + 1 + 2)/6 + (s + 1)*(s + 1 + 1)/2 + 1;
> +          ss = (r + s)*(r + s + 1)*(r + s + 2)/6 + s*(s + 1)/2;
> +          basisvalues[rr] = basisvalues[ss]*(1.000000000000000 + r + s + Z*(2.000000000000000 + r + s));
> +        }// end loop over 's'
>        }// end loop over 'r'
>        for (unsigned int r = 0; r < 2; r++)
>        {
>          for (unsigned int s = 0; s < 2 - r; s++)
>          {
> -          rr = (r + s)*(r + s + 1)/2 + s;
> -          basisvalues[rr] *= std::sqrt((0.500000000000000 + r)*(1.000000000000000 + r + s));
> +          for (unsigned int t = 0; t < 2 - r - s; t++)
> +          {
> +            rr = (r + s + t)*(r + s + t + 1)*(r + s + t + 2)/6 + (s + t)*(s + t + 1)/2 + t;
> +            basisvalues[rr] *= std::sqrt((0.500000000000000 + r)*(1.000000000000000 + r + s)*(1.500000000000000 + r + s + t));
> +          }// end loop over 't'
>          }// end loop over 's'
>        }// end loop over 'r'
>
>        // Table(s) of coefficients.
> -      static const double coefficients0[3] = \
> -      {0.471404520791032, -0.288675134594813, -0.166666666666667};
> +      static const double coefficients0[4] = \
> +      {0.288675134594813, -0.182574185835055, -0.105409255338946, -0.074535599249993};
>
>        // Tables of derivatives of the polynomial base (transpose).
> -      static const double dmats0[3][3] = \
> -      {{0.000000000000000, 0.000000000000000, 0.000000000000000},
> -      {4.898979485566356, 0.000000000000000, 0.000000000000000},
> -      {0.000000000000000, 0.000000000000000, 0.000000000000000}};
> -
> -      static const double dmats1[3][3] = \
> -      {{0.000000000000000, 0.000000000000000, 0.000000000000000},
> -      {2.449489742783178, 0.000000000000000, 0.000000000000000},
> -      {4.242640687119285, 0.000000000000000, 0.000000000000000}};
> +      static const double dmats0[4][4] = \
> +      {{0.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000},
> +      {6.324555320336760, 0.000000000000000, 0.000000000000000, 0.000000000000000},
> +      {0.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000},
> +      {0.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000}};
> +
> +      static const double dmats1[4][4] = \
> +      {{0.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000},
> +      {3.162277660168380, 0.000000000000000, 0.000000000000000, 0.000000000000000},
> +      {5.477225575051662, 0.000000000000000, 0.000000000000000, 0.000000000000000},
> +      {0.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000}};
> +
> +      static const double dmats2[4][4] = \
> +      {{0.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000},
> +      {3.162277660168380, 0.000000000000000, 0.000000000000000, 0.000000000000000},
> +      {1.825741858350554, 0.000000000000000, 0.000000000000000, 0.000000000000000},
> +      {5.163977794943223, 0.000000000000000, 0.000000000000000, 0.000000000000000}};
>
>        // Compute reference derivatives.
>        // Declare pointer to array of derivatives on FIAT element.
> @@ -402,24 +554,26 @@
>        }// end loop over 'r'
>
>        // Declare derivative matrix (of polynomial basis).
> -      double dmats[3][3] = \
> -      {{1.000000000000000, 0.000000000000000, 0.000000000000000},
> -      {0.000000000000000, 1.000000000000000, 0.000000000000000},
> -      {0.000000000000000, 0.000000000000000, 1.000000000000000}};
> +      double dmats[4][4] = \
> +      {{1.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000},
> +      {0.000000000000000, 1.000000000000000, 0.000000000000000, 0.000000000000000},
> +      {0.000000000000000, 0.000000000000000, 1.000000000000000, 0.000000000000000},
> +      {0.000000000000000, 0.000000000000000, 0.000000000000000, 1.000000000000000}};
>
>        // Declare (auxiliary) derivative matrix (of polynomial basis).
> -      double dmats_old[3][3] = \
> -      {{1.000000000000000, 0.000000000000000, 0.000000000000000},
> -      {0.000000000000000, 1.000000000000000, 0.000000000000000},
> -      {0.000000000000000, 0.000000000000000, 1.000000000000000}};
> +      double dmats_old[4][4] = \
> +      {{1.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000},
> +      {0.000000000000000, 1.000000000000000, 0.000000000000000, 0.000000000000000},
> +      {0.000000000000000, 0.000000000000000, 1.000000000000000, 0.000000000000000},
> +      {0.000000000000000, 0.000000000000000, 0.000000000000000, 1.000000000000000}};
>
>        // Loop possible derivatives.
>        for (unsigned int r = 0; r < num_derivatives; r++)
>        {
>          // Resetting dmats values to compute next derivative.
> -        for (unsigned int t = 0; t < 3; t++)
> +        for (unsigned int t = 0; t < 4; t++)
>          {
> -          for (unsigned int u = 0; u < 3; u++)
> +          for (unsigned int u = 0; u < 4; u++)
>            {
>              dmats[t][u] = 0.000000000000000;
>              if (t == u)
> @@ -434,9 +588,9 @@
>          for (unsigned int s = 0; s < n; s++)
>          {
>            // Updating dmats_old with new values and resetting dmats.
> -          for (unsigned int t = 0; t < 3; t++)
> +          for (unsigned int t = 0; t < 4; t++)
>            {
> -            for (unsigned int u = 0; u < 3; u++)
> +            for (unsigned int u = 0; u < 4; u++)
>              {
>                dmats_old[t][u] = dmats[t][u];
>                dmats[t][u] = 0.000000000000000;
> @@ -446,11 +600,11 @@
>            // Update dmats using an inner product.
>            if (combinations[r][s] == 0)
>            {
> -          for (unsigned int t = 0; t < 3; t++)
> +          for (unsigned int t = 0; t < 4; t++)
>            {
> -            for (unsigned int u = 0; u < 3; u++)
> +            for (unsigned int u = 0; u < 4; u++)
>              {
> -              for (unsigned int tu = 0; tu < 3; tu++)
> +              for (unsigned int tu = 0; tu < 4; tu++)
>                {
>                  dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
>                }// end loop over 'tu'
> @@ -460,11 +614,11 @@
>
>            if (combinations[r][s] == 1)
>            {
> -          for (unsigned int t = 0; t < 3; t++)
> +          for (unsigned int t = 0; t < 4; t++)
>            {
> -            for (unsigned int u = 0; u < 3; u++)
> +            for (unsigned int u = 0; u < 4; u++)
>              {
> -              for (unsigned int tu = 0; tu < 3; tu++)
> +              for (unsigned int tu = 0; tu < 4; tu++)
>                {
>                  dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
>                }// end loop over 'tu'
> @@ -472,10 +626,24 @@
>            }// end loop over 't'
>            }
>
> +          if (combinations[r][s] == 2)
> +          {
> +          for (unsigned int t = 0; t < 4; t++)
> +          {
> +            for (unsigned int u = 0; u < 4; u++)
> +            {
> +              for (unsigned int tu = 0; tu < 4; tu++)
> +              {
> +                dmats[t][u] += dmats2[t][tu]*dmats_old[tu][u];
> +              }// end loop over 'tu'
> +            }// end loop over 'u'
> +          }// end loop over 't'
> +          }
> +
>          }// end loop over 's'
> -        for (unsigned int s = 0; s < 3; s++)
> +        for (unsigned int s = 0; s < 4; s++)
>          {
> -          for (unsigned int t = 0; t < 3; t++)
> +          for (unsigned int t = 0; t < 4; t++)
>            {
>              derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
>            }// end loop over 't'
> @@ -511,45 +679,65 @@
>        {
>
>        // Array of basisvalues.
> -      double basisvalues[3] = {0.000000000000000, 0.000000000000000, 0.000000000000000};
> +      double basisvalues[4] = {0.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000};
>
>        // Declare helper variables.
>        unsigned int rr = 0;
>        unsigned int ss = 0;
> -      double tmp0 = (1.000000000000000 + Y + 2.000000000000000*X)/2.000000000000000;
> +      double tmp0 = 0.500000000000000*(2.000000000000000 + Y + Z + 2.000000000000000*X);
>
>        // Compute basisvalues.
>        basisvalues[0] = 1.000000000000000;
>        basisvalues[1] = tmp0;
>        for (unsigned int r = 0; r < 1; r++)
>        {
> -        rr = (r + 1)*(r + 1 + 1)/2 + 1;
> -        ss = r*(r + 1)/2;
> -        basisvalues[rr] = basisvalues[ss]*(0.500000000000000 + r + Y*(1.500000000000000 + r));
> +        rr = (r + 1)*(r + 1 + 1)*(r + 1 + 2)/6 + 1*(1 + 1)/2;
> +        ss = r*(r + 1)*(r + 2)/6;
> +        basisvalues[rr] = basisvalues[ss]*(r*(1.000000000000000 + Y) + (2.000000000000000 + Z + 3.000000000000000*Y)/2.000000000000000);
> +      }// end loop over 'r'
> +      for (unsigned int r = 0; r < 1; r++)
> +      {
> +        for (unsigned int s = 0; s < 1 - r; s++)
> +        {
> +          rr = (r + s + 1)*(r + s + 1 + 1)*(r + s + 1 + 2)/6 + (s + 1)*(s + 1 + 1)/2 + 1;
> +          ss = (r + s)*(r + s + 1)*(r + s + 2)/6 + s*(s + 1)/2;
> +          basisvalues[rr] = basisvalues[ss]*(1.000000000000000 + r + s + Z*(2.000000000000000 + r + s));
> +        }// end loop over 's'
>        }// end loop over 'r'
>        for (unsigned int r = 0; r < 2; r++)
>        {
>          for (unsigned int s = 0; s < 2 - r; s++)
>          {
> -          rr = (r + s)*(r + s + 1)/2 + s;
> -          basisvalues[rr] *= std::sqrt((0.500000000000000 + r)*(1.000000000000000 + r + s));
> +          for (unsigned int t = 0; t < 2 - r - s; t++)
> +          {
> +            rr = (r + s + t)*(r + s + t + 1)*(r + s + t + 2)/6 + (s + t)*(s + t + 1)/2 + t;
> +            basisvalues[rr] *= std::sqrt((0.500000000000000 + r)*(1.000000000000000 + r + s)*(1.500000000000000 + r + s + t));
> +          }// end loop over 't'
>          }// end loop over 's'
>        }// end loop over 'r'
>
>        // Table(s) of coefficients.
> -      static const double coefficients0[3] = \
> -      {0.471404520791032, 0.288675134594813, -0.166666666666667};
> +      static const double coefficients0[4] = \
> +      {0.288675134594813, 0.182574185835055, -0.105409255338946, -0.074535599249993};
>
>        // Tables of derivatives of the polynomial base (transpose).
> -      static const double dmats0[3][3] = \
> -      {{0.000000000000000, 0.000000000000000, 0.000000000000000},
> -      {4.898979485566356, 0.000000000000000, 0.000000000000000},
> -      {0.000000000000000, 0.000000000000000, 0.000000000000000}};
> -
> -      static const double dmats1[3][3] = \
> -      {{0.000000000000000, 0.000000000000000, 0.000000000000000},
> -      {2.449489742783178, 0.000000000000000, 0.000000000000000},
> -      {4.242640687119285, 0.000000000000000, 0.000000000000000}};
> +      static const double dmats0[4][4] = \
> +      {{0.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000},
> +      {6.324555320336760, 0.000000000000000, 0.000000000000000, 0.000000000000000},
> +      {0.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000},
> +      {0.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000}};
> +
> +      static const double dmats1[4][4] = \
> +      {{0.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000},
> +      {3.162277660168380, 0.000000000000000, 0.000000000000000, 0.000000000000000},
> +      {5.477225575051662, 0.000000000000000, 0.000000000000000, 0.000000000000000},
> +      {0.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000}};
> +
> +      static const double dmats2[4][4] = \
> +      {{0.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000},
> +      {3.162277660168380, 0.000000000000000, 0.000000000000000, 0.000000000000000},
> +      {1.825741858350554, 0.000000000000000, 0.000000000000000, 0.000000000000000},
> +      {5.163977794943223, 0.000000000000000, 0.000000000000000, 0.000000000000000}};
>
>        // Compute reference derivatives.
>        // Declare pointer to array of derivatives on FIAT element.
> @@ -560,24 +748,26 @@
>        }// end loop over 'r'
>
>        // Declare derivative matrix (of polynomial basis).
> -      double dmats[3][3] = \
> -      {{1.000000000000000, 0.000000000000000, 0.000000000000000},
> -      {0.000000000000000, 1.000000000000000, 0.000000000000000},
> -      {0.000000000000000, 0.000000000000000, 1.000000000000000}};
> +      double dmats[4][4] = \
> +      {{1.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000},
> +      {0.000000000000000, 1.000000000000000, 0.000000000000000, 0.000000000000000},
> +      {0.000000000000000, 0.000000000000000, 1.000000000000000, 0.000000000000000},
> +      {0.000000000000000, 0.000000000000000, 0.000000000000000, 1.000000000000000}};
>
>        // Declare (auxiliary) derivative matrix (of polynomial basis).
> -      double dmats_old[3][3] = \
> -      {{1.000000000000000, 0.000000000000000, 0.000000000000000},
> -      {0.000000000000000, 1.000000000000000, 0.000000000000000},
> -      {0.000000000000000, 0.000000000000000, 1.000000000000000}};
> +      double dmats_old[4][4] = \
> +      {{1.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000},
> +      {0.000000000000000, 1.000000000000000, 0.000000000000000, 0.000000000000000},
> +      {0.000000000000000, 0.000000000000000, 1.000000000000000, 0.000000000000000},
> +      {0.000000000000000, 0.000000000000000, 0.000000000000000, 1.000000000000000}};
>
>        // Loop possible derivatives.
>        for (unsigned int r = 0; r < num_derivatives; r++)
>        {
>          // Resetting dmats values to compute next derivative.
> -        for (unsigned int t = 0; t < 3; t++)
> +        for (unsigned int t = 0; t < 4; t++)
>          {
> -          for (unsigned int u = 0; u < 3; u++)
> +          for (unsigned int u = 0; u < 4; u++)
>            {
>              dmats[t][u] = 0.000000000000000;
>              if (t == u)
> @@ -592,9 +782,9 @@
>          for (unsigned int s = 0; s < n; s++)
>          {
>            // Updating dmats_old with new values and resetting dmats.
> -          for (unsigned int t = 0; t < 3; t++)
> +          for (unsigned int t = 0; t < 4; t++)
>            {
> -            for (unsigned int u = 0; u < 3; u++)
> +            for (unsigned int u = 0; u < 4; u++)
>              {
>                dmats_old[t][u] = dmats[t][u];
>                dmats[t][u] = 0.000000000000000;
> @@ -604,11 +794,11 @@
>            // Update dmats using an inner product.
>            if (combinations[r][s] == 0)
>            {
> -          for (unsigned int t = 0; t < 3; t++)
> +          for (unsigned int t = 0; t < 4; t++)
>            {
> -            for (unsigned int u = 0; u < 3; u++)
> +            for (unsigned int u = 0; u < 4; u++)
>              {
> -              for (unsigned int tu = 0; tu < 3; tu++)
> +              for (unsigned int tu = 0; tu < 4; tu++)
>                {
>                  dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
>                }// end loop over 'tu'
> @@ -618,11 +808,11 @@
>
>            if (combinations[r][s] == 1)
>            {
> -          for (unsigned int t = 0; t < 3; t++)
> +          for (unsigned int t = 0; t < 4; t++)
>            {
> -            for (unsigned int u = 0; u < 3; u++)
> +            for (unsigned int u = 0; u < 4; u++)
>              {
> -              for (unsigned int tu = 0; tu < 3; tu++)
> +              for (unsigned int tu = 0; tu < 4; tu++)
>                {
>                  dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
>                }// end loop over 'tu'
> @@ -630,10 +820,24 @@
>            }// end loop over 't'
>            }
>
> +          if (combinations[r][s] == 2)
> +          {
> +          for (unsigned int t = 0; t < 4; t++)
> +          {
> +            for (unsigned int u = 0; u < 4; u++)
> +            {
> +              for (unsigned int tu = 0; tu < 4; tu++)
> +              {
> +                dmats[t][u] += dmats2[t][tu]*dmats_old[tu][u];
> +              }// end loop over 'tu'
> +            }// end loop over 'u'
> +          }// end loop over 't'
> +          }
> +
>          }// end loop over 's'
> -        for (unsigned int s = 0; s < 3; s++)
> +        for (unsigned int s = 0; s < 4; s++)
>          {
> -          for (unsigned int t = 0; t < 3; t++)
> +          for (unsigned int t = 0; t < 4; t++)
>            {
>              derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
>            }// end loop over 't'
> @@ -669,129 +873,359 @@
>        {
>
>        // Array of basisvalues.
> -      double basisvalues[3] = {0.000000000000000, 0.000000000000000, 0.000000000000000};
> -
> -      // Declare helper variables.
> -      unsigned int rr = 0;
> -      unsigned int ss = 0;
> -      double tmp0 = (1.000000000000000 + Y + 2.000000000000000*X)/2.000000000000000;
> -
> -      // Compute basisvalues.
> -      basisvalues[0] = 1.000000000000000;
> -      basisvalues[1] = tmp0;
> -      for (unsigned int r = 0; r < 1; r++)
> -      {
> -        rr = (r + 1)*(r + 1 + 1)/2 + 1;
> -        ss = r*(r + 1)/2;
> -        basisvalues[rr] = basisvalues[ss]*(0.500000000000000 + r + Y*(1.500000000000000 + r));
> -      }// end loop over 'r'
> -      for (unsigned int r = 0; r < 2; r++)
> -      {
> -        for (unsigned int s = 0; s < 2 - r; s++)
> -        {
> -          rr = (r + s)*(r + s + 1)/2 + s;
> -          basisvalues[rr] *= std::sqrt((0.500000000000000 + r)*(1.000000000000000 + r + s));
> -        }// end loop over 's'
> -      }// end loop over 'r'
> -
> -      // Table(s) of coefficients.
> -      static const double coefficients0[3] = \
> -      {0.471404520791032, 0.000000000000000, 0.333333333333333};
> -
> -      // Tables of derivatives of the polynomial base (transpose).
> -      static const double dmats0[3][3] = \
> -      {{0.000000000000000, 0.000000000000000, 0.000000000000000},
> -      {4.898979485566356, 0.000000000000000, 0.000000000000000},
> -      {0.000000000000000, 0.000000000000000, 0.000000000000000}};
> -
> -      static const double dmats1[3][3] = \
> -      {{0.000000000000000, 0.000000000000000, 0.000000000000000},
> -      {2.449489742783178, 0.000000000000000, 0.000000000000000},
> -      {4.242640687119285, 0.000000000000000, 0.000000000000000}};
> -
> -      // Compute reference derivatives.
> -      // Declare pointer to array of derivatives on FIAT element.
> -      double *derivatives = new double[num_derivatives];
> -      for (unsigned int r = 0; r < num_derivatives; r++)
> -      {
> -        derivatives[r] = 0.000000000000000;
> -      }// end loop over 'r'
> -
> -      // Declare derivative matrix (of polynomial basis).
> -      double dmats[3][3] = \
> -      {{1.000000000000000, 0.000000000000000, 0.000000000000000},
> -      {0.000000000000000, 1.000000000000000, 0.000000000000000},
> -      {0.000000000000000, 0.000000000000000, 1.000000000000000}};
> -
> -      // Declare (auxiliary) derivative matrix (of polynomial basis).
> -      double dmats_old[3][3] = \
> -      {{1.000000000000000, 0.000000000000000, 0.000000000000000},
> -      {0.000000000000000, 1.000000000000000, 0.000000000000000},
> -      {0.000000000000000, 0.000000000000000, 1.000000000000000}};
> -
> -      // Loop possible derivatives.
> -      for (unsigned int r = 0; r < num_derivatives; r++)
> -      {
> -        // Resetting dmats values to compute next derivative.
> -        for (unsigned int t = 0; t < 3; t++)
> -        {
> -          for (unsigned int u = 0; u < 3; u++)
> -          {
> -            dmats[t][u] = 0.000000000000000;
> -            if (t == u)
> -            {
> -            dmats[t][u] = 1.000000000000000;
> -            }
> -
> -          }// end loop over 'u'
> -        }// end loop over 't'
> -
> -        // Looping derivative order to generate dmats.
> -        for (unsigned int s = 0; s < n; s++)
> -        {
> -          // Updating dmats_old with new values and resetting dmats.
> -          for (unsigned int t = 0; t < 3; t++)
> -          {
> -            for (unsigned int u = 0; u < 3; u++)
> -            {
> -              dmats_old[t][u] = dmats[t][u];
> -              dmats[t][u] = 0.000000000000000;
> -            }// end loop over 'u'
> -          }// end loop over 't'
> -
> -          // Update dmats using an inner product.
> -          if (combinations[r][s] == 0)
> -          {
> -          for (unsigned int t = 0; t < 3; t++)
> -          {
> -            for (unsigned int u = 0; u < 3; u++)
> -            {
> -              for (unsigned int tu = 0; tu < 3; tu++)
> -              {
> -                dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
> -              }// end loop over 'tu'
> -            }// end loop over 'u'
> -          }// end loop over 't'
> -          }
> -
> -          if (combinations[r][s] == 1)
> -          {
> -          for (unsigned int t = 0; t < 3; t++)
> -          {
> -            for (unsigned int u = 0; u < 3; u++)
> -            {
> -              for (unsigned int tu = 0; tu < 3; tu++)
> -              {
> -                dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
> -              }// end loop over 'tu'
> -            }// end loop over 'u'
> -          }// end loop over 't'
> -          }
> -
> -        }// end loop over 's'
> -        for (unsigned int s = 0; s < 3; s++)
> -        {
> -          for (unsigned int t = 0; t < 3; t++)
> +      double basisvalues[4] = {0.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000};
> +
> +      // Declare helper variables.
> +      unsigned int rr = 0;
> +      unsigned int ss = 0;
> +      double tmp0 = 0.500000000000000*(2.000000000000000 + Y + Z + 2.000000000000000*X);
> +
> +      // Compute basisvalues.
> +      basisvalues[0] = 1.000000000000000;
> +      basisvalues[1] = tmp0;
> +      for (unsigned int r = 0; r < 1; r++)
> +      {
> +        rr = (r + 1)*(r + 1 + 1)*(r + 1 + 2)/6 + 1*(1 + 1)/2;
> +        ss = r*(r + 1)*(r + 2)/6;
> +        basisvalues[rr] = basisvalues[ss]*(r*(1.000000000000000 + Y) + (2.000000000000000 + Z + 3.000000000000000*Y)/2.000000000000000);
> +      }// end loop over 'r'
> +      for (unsigned int r = 0; r < 1; r++)
> +      {
> +        for (unsigned int s = 0; s < 1 - r; s++)
> +        {
> +          rr = (r + s + 1)*(r + s + 1 + 1)*(r + s + 1 + 2)/6 + (s + 1)*(s + 1 + 1)/2 + 1;
> +          ss = (r + s)*(r + s + 1)*(r + s + 2)/6 + s*(s + 1)/2;
> +          basisvalues[rr] = basisvalues[ss]*(1.000000000000000 + r + s + Z*(2.000000000000000 + r + s));
> +        }// end loop over 's'
> +      }// end loop over 'r'
> +      for (unsigned int r = 0; r < 2; r++)
> +      {
> +        for (unsigned int s = 0; s < 2 - r; s++)
> +        {
> +          for (unsigned int t = 0; t < 2 - r - s; t++)
> +          {
> +            rr = (r + s + t)*(r + s + t + 1)*(r + s + t + 2)/6 + (s + t)*(s + t + 1)/2 + t;
> +            basisvalues[rr] *= std::sqrt((0.500000000000000 + r)*(1.000000000000000 + r + s)*(1.500000000000000 + r + s + t));
> +          }// end loop over 't'
> +        }// end loop over 's'
> +      }// end loop over 'r'
> +
> +      // Table(s) of coefficients.
> +      static const double coefficients0[4] = \
> +      {0.288675134594813, 0.000000000000000, 0.210818510677892, -0.074535599249993};
> +
> +      // Tables of derivatives of the polynomial base (transpose).
> +      static const double dmats0[4][4] = \
> +      {{0.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000},
> +      {6.324555320336760, 0.000000000000000, 0.000000000000000, 0.000000000000000},
> +      {0.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000},
> +      {0.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000}};
> +
> +      static const double dmats1[4][4] = \
> +      {{0.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000},
> +      {3.162277660168380, 0.000000000000000, 0.000000000000000, 0.000000000000000},
> +      {5.477225575051662, 0.000000000000000, 0.000000000000000, 0.000000000000000},
> +      {0.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000}};
> +
> +      static const double dmats2[4][4] = \
> +      {{0.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000},
> +      {3.162277660168380, 0.000000000000000, 0.000000000000000, 0.000000000000000},
> +      {1.825741858350554, 0.000000000000000, 0.000000000000000, 0.000000000000000},
> +      {5.163977794943223, 0.000000000000000, 0.000000000000000, 0.000000000000000}};
> +
> +      // Compute reference derivatives.
> +      // Declare pointer to array of derivatives on FIAT element.
> +      double *derivatives = new double[num_derivatives];
> +      for (unsigned int r = 0; r < num_derivatives; r++)
> +      {
> +        derivatives[r] = 0.000000000000000;
> +      }// end loop over 'r'
> +
> +      // Declare derivative matrix (of polynomial basis).
> +      double dmats[4][4] = \
> +      {{1.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000},
> +      {0.000000000000000, 1.000000000000000, 0.000000000000000, 0.000000000000000},
> +      {0.000000000000000, 0.000000000000000, 1.000000000000000, 0.000000000000000},
> +      {0.000000000000000, 0.000000000000000, 0.000000000000000, 1.000000000000000}};
> +
> +      // Declare (auxiliary) derivative matrix (of polynomial basis).
> +      double dmats_old[4][4] = \
> +      {{1.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000},
> +      {0.000000000000000, 1.000000000000000, 0.000000000000000, 0.000000000000000},
> +      {0.000000000000000, 0.000000000000000, 1.000000000000000, 0.000000000000000},
> +      {0.000000000000000, 0.000000000000000, 0.000000000000000, 1.000000000000000}};
> +
> +      // Loop possible derivatives.
> +      for (unsigned int r = 0; r < num_derivatives; r++)
> +      {
> +        // Resetting dmats values to compute next derivative.
> +        for (unsigned int t = 0; t < 4; t++)
> +        {
> +          for (unsigned int u = 0; u < 4; u++)
> +          {
> +            dmats[t][u] = 0.000000000000000;
> +            if (t == u)
> +            {
> +            dmats[t][u] = 1.000000000000000;
> +            }
> +
> +          }// end loop over 'u'
> +        }// end loop over 't'
> +
> +        // Looping derivative order to generate dmats.
> +        for (unsigned int s = 0; s < n; s++)
> +        {
> +          // Updating dmats_old with new values and resetting dmats.
> +          for (unsigned int t = 0; t < 4; t++)
> +          {
> +            for (unsigned int u = 0; u < 4; u++)
> +            {
> +              dmats_old[t][u] = dmats[t][u];
> +              dmats[t][u] = 0.000000000000000;
> +            }// end loop over 'u'
> +          }// end loop over 't'
> +
> +          // Update dmats using an inner product.
> +          if (combinations[r][s] == 0)
> +          {
> +          for (unsigned int t = 0; t < 4; t++)
> +          {
> +            for (unsigned int u = 0; u < 4; u++)
> +            {
> +              for (unsigned int tu = 0; tu < 4; tu++)
> +              {
> +                dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
> +              }// end loop over 'tu'
> +            }// end loop over 'u'
> +          }// end loop over 't'
> +          }
> +
> +          if (combinations[r][s] == 1)
> +          {
> +          for (unsigned int t = 0; t < 4; t++)
> +          {
> +            for (unsigned int u = 0; u < 4; u++)
> +            {
> +              for (unsigned int tu = 0; tu < 4; tu++)
> +              {
> +                dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
> +              }// end loop over 'tu'
> +            }// end loop over 'u'
> +          }// end loop over 't'
> +          }
> +
> +          if (combinations[r][s] == 2)
> +          {
> +          for (unsigned int t = 0; t < 4; t++)
> +          {
> +            for (unsigned int u = 0; u < 4; u++)
> +            {
> +              for (unsigned int tu = 0; tu < 4; tu++)
> +              {
> +                dmats[t][u] += dmats2[t][tu]*dmats_old[tu][u];
> +              }// end loop over 'tu'
> +            }// end loop over 'u'
> +          }// end loop over 't'
> +          }
> +
> +        }// end loop over 's'
> +        for (unsigned int s = 0; s < 4; s++)
> +        {
> +          for (unsigned int t = 0; t < 4; t++)
> +          {
> +            derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
> +          }// end loop over 't'
> +        }// end loop over 's'
> +      }// end loop over 'r'
> +
> +      // Transform derivatives back to physical element
> +      for (unsigned int r = 0; r < num_derivatives; r++)
> +      {
> +        for (unsigned int s = 0; s < num_derivatives; s++)
> +        {
> +          values[r] += transform[r][s]*derivatives[s];
> +        }// end loop over 's'
> +      }// end loop over 'r'
> +
> +      // Delete pointer to array of derivatives on FIAT element
> +      delete [] derivatives;
> +
> +      // Delete pointer to array of combinations of derivatives and transform
> +      for (unsigned int r = 0; r < num_derivatives; r++)
> +      {
> +        delete [] combinations[r];
> +      }// end loop over 'r'
> +      delete [] combinations;
> +      for (unsigned int r = 0; r < num_derivatives; r++)
> +      {
> +        delete [] transform[r];
> +      }// end loop over 'r'
> +      delete [] transform;
> +        break;
> +      }
> +    case 3:
> +      {
> +
> +      // Array of basisvalues.
> +      double basisvalues[4] = {0.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000};
> +
> +      // Declare helper variables.
> +      unsigned int rr = 0;
> +      unsigned int ss = 0;
> +      double tmp0 = 0.500000000000000*(2.000000000000000 + Y + Z + 2.000000000000000*X);
> +
> +      // Compute basisvalues.
> +      basisvalues[0] = 1.000000000000000;
> +      basisvalues[1] = tmp0;
> +      for (unsigned int r = 0; r < 1; r++)
> +      {
> +        rr = (r + 1)*(r + 1 + 1)*(r + 1 + 2)/6 + 1*(1 + 1)/2;
> +        ss = r*(r + 1)*(r + 2)/6;
> +        basisvalues[rr] = basisvalues[ss]*(r*(1.000000000000000 + Y) + (2.000000000000000 + Z + 3.000000000000000*Y)/2.000000000000000);
> +      }// end loop over 'r'
> +      for (unsigned int r = 0; r < 1; r++)
> +      {
> +        for (unsigned int s = 0; s < 1 - r; s++)
> +        {
> +          rr = (r + s + 1)*(r + s + 1 + 1)*(r + s + 1 + 2)/6 + (s + 1)*(s + 1 + 1)/2 + 1;
> +          ss = (r + s)*(r + s + 1)*(r + s + 2)/6 + s*(s + 1)/2;
> +          basisvalues[rr] = basisvalues[ss]*(1.000000000000000 + r + s + Z*(2.000000000000000 + r + s));
> +        }// end loop over 's'
> +      }// end loop over 'r'
> +      for (unsigned int r = 0; r < 2; r++)
> +      {
> +        for (unsigned int s = 0; s < 2 - r; s++)
> +        {
> +          for (unsigned int t = 0; t < 2 - r - s; t++)
> +          {
> +            rr = (r + s + t)*(r + s + t + 1)*(r + s + t + 2)/6 + (s + t)*(s + t + 1)/2 + t;
> +            basisvalues[rr] *= std::sqrt((0.500000000000000 + r)*(1.000000000000000 + r + s)*(1.500000000000000 + r + s + t));
> +          }// end loop over 't'
> +        }// end loop over 's'
> +      }// end loop over 'r'
> +
> +      // Table(s) of coefficients.
> +      static const double coefficients0[4] = \
> +      {0.288675134594813, 0.000000000000000, 0.000000000000000, 0.223606797749979};
> +
> +      // Tables of derivatives of the polynomial base (transpose).
> +      static const double dmats0[4][4] = \
> +      {{0.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000},
> +      {6.324555320336760, 0.000000000000000, 0.000000000000000, 0.000000000000000},
> +      {0.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000},
> +      {0.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000}};
> +
> +      static const double dmats1[4][4] = \
> +      {{0.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000},
> +      {3.162277660168380, 0.000000000000000, 0.000000000000000, 0.000000000000000},
> +      {5.477225575051662, 0.000000000000000, 0.000000000000000, 0.000000000000000},
> +      {0.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000}};
> +
> +      static const double dmats2[4][4] = \
> +      {{0.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000},
> +      {3.162277660168380, 0.000000000000000, 0.000000000000000, 0.000000000000000},
> +      {1.825741858350554, 0.000000000000000, 0.000000000000000, 0.000000000000000},
> +      {5.163977794943223, 0.000000000000000, 0.000000000000000, 0.000000000000000}};
> +
> +      // Compute reference derivatives.
> +      // Declare pointer to array of derivatives on FIAT element.
> +      double *derivatives = new double[num_derivatives];
> +      for (unsigned int r = 0; r < num_derivatives; r++)
> +      {
> +        derivatives[r] = 0.000000000000000;
> +      }// end loop over 'r'
> +
> +      // Declare derivative matrix (of polynomial basis).
> +      double dmats[4][4] = \
> +      {{1.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000},
> +      {0.000000000000000, 1.000000000000000, 0.000000000000000, 0.000000000000000},
> +      {0.000000000000000, 0.000000000000000, 1.000000000000000, 0.000000000000000},
> +      {0.000000000000000, 0.000000000000000, 0.000000000000000, 1.000000000000000}};
> +
> +      // Declare (auxiliary) derivative matrix (of polynomial basis).
> +      double dmats_old[4][4] = \
> +      {{1.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000},
> +      {0.000000000000000, 1.000000000000000, 0.000000000000000, 0.000000000000000},
> +      {0.000000000000000, 0.000000000000000, 1.000000000000000, 0.000000000000000},
> +      {0.000000000000000, 0.000000000000000, 0.000000000000000, 1.000000000000000}};
> +
> +      // Loop possible derivatives.
> +      for (unsigned int r = 0; r < num_derivatives; r++)
> +      {
> +        // Resetting dmats values to compute next derivative.
> +        for (unsigned int t = 0; t < 4; t++)
> +        {
> +          for (unsigned int u = 0; u < 4; u++)
> +          {
> +            dmats[t][u] = 0.000000000000000;
> +            if (t == u)
> +            {
> +            dmats[t][u] = 1.000000000000000;
> +            }
> +
> +          }// end loop over 'u'
> +        }// end loop over 't'
> +
> +        // Looping derivative order to generate dmats.
> +        for (unsigned int s = 0; s < n; s++)
> +        {
> +          // Updating dmats_old with new values and resetting dmats.
> +          for (unsigned int t = 0; t < 4; t++)
> +          {
> +            for (unsigned int u = 0; u < 4; u++)
> +            {
> +              dmats_old[t][u] = dmats[t][u];
> +              dmats[t][u] = 0.000000000000000;
> +            }// end loop over 'u'
> +          }// end loop over 't'
> +
> +          // Update dmats using an inner product.
> +          if (combinations[r][s] == 0)
> +          {
> +          for (unsigned int t = 0; t < 4; t++)
> +          {
> +            for (unsigned int u = 0; u < 4; u++)
> +            {
> +              for (unsigned int tu = 0; tu < 4; tu++)
> +              {
> +                dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
> +              }// end loop over 'tu'
> +            }// end loop over 'u'
> +          }// end loop over 't'
> +          }
> +
> +          if (combinations[r][s] == 1)
> +          {
> +          for (unsigned int t = 0; t < 4; t++)
> +          {
> +            for (unsigned int u = 0; u < 4; u++)
> +            {
> +              for (unsigned int tu = 0; tu < 4; tu++)
> +              {
> +                dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
> +              }// end loop over 'tu'
> +            }// end loop over 'u'
> +          }// end loop over 't'
> +          }
> +
> +          if (combinations[r][s] == 2)
> +          {
> +          for (unsigned int t = 0; t < 4; t++)
> +          {
> +            for (unsigned int u = 0; u < 4; u++)
> +            {
> +              for (unsigned int tu = 0; tu < 4; tu++)
> +              {
> +                dmats[t][u] += dmats2[t][tu]*dmats_old[tu][u];
> +              }// end loop over 'tu'
> +            }// end loop over 'u'
> +          }// end loop over 't'
> +          }
> +
> +        }// end loop over 's'
> +        for (unsigned int s = 0; s < 4; s++)
> +        {
> +          for (unsigned int t = 0; t < 4; t++)
>            {
>              derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
>            }// end loop over 't'
> @@ -837,7 +1271,7 @@
>      unsigned int num_derivatives = 1;
>      for (unsigned int r = 0; r < n; r++)
>      {
> -      num_derivatives *= 2;
> +      num_derivatives *= 3;
>      }// end loop over 'r'
>
>      // Helper variable to hold values of a single dof.
> @@ -848,7 +1282,7 @@
>      }// end loop over 'r'
>
>      // Loop dofs and call evaluate_basis_derivatives.
> -    for (unsigned int r = 0; r < 3; r++)
> +    for (unsigned int r = 0; r < 4; r++)
>      {
>        evaluate_basis_derivatives(r, n, dof_values, coordinates, c);
>        for (unsigned int s = 0; s < num_derivatives; s++)
> @@ -870,7 +1304,7 @@
>      double vals[1];
>
>      // Declare variable for physical coordinates.
> -    double y[2];
> +    double y[3];
>      const double * const * x = c.coordinates;
>      switch (i)
>      {
> @@ -878,6 +1312,7 @@
>        {
>          y[0] = x[0][0];
>        y[1] = x[0][1];
> +      y[2] = x[0][2];
>        f.evaluate(vals, y, c);
>        return vals[0];
>          break;
> @@ -886,6 +1321,7 @@
>        {
>          y[0] = x[1][0];
>        y[1] = x[1][1];
> +      y[2] = x[1][2];
>        f.evaluate(vals, y, c);
>        return vals[0];
>          break;
> @@ -894,6 +1330,16 @@
>        {
>          y[0] = x[2][0];
>        y[1] = x[2][1];
> +      y[2] = x[2][2];
> +      f.evaluate(vals, y, c);
> +      return vals[0];
> +        break;
> +      }
> +    case 3:
> +      {
> +        y[0] = x[3][0];
> +      y[1] = x[3][1];
> +      y[2] = x[3][2];
>        f.evaluate(vals, y, c);
>        return vals[0];
>          break;
> @@ -912,20 +1358,28 @@
>      double vals[1];
>
>      // Declare variable for physical coordinates.
> -    double y[2];
> +    double y[3];
>      const double * const * x = c.coordinates;
>      y[0] = x[0][0];
>      y[1] = x[0][1];
> +    y[2] = x[0][2];
>      f.evaluate(vals, y, c);
>      values[0] = vals[0];
>      y[0] = x[1][0];
>      y[1] = x[1][1];
> +    y[2] = x[1][2];
>      f.evaluate(vals, y, c);
>      values[1] = vals[0];
>      y[0] = x[2][0];
>      y[1] = x[2][1];
> +    y[2] = x[2][2];
>      f.evaluate(vals, y, c);
>      values[2] = vals[0];
> +    y[0] = x[3][0];
> +    y[1] = x[3][1];
> +    y[2] = x[3][2];
> +    f.evaluate(vals, y, c);
> +    values[3] = vals[0];
>    }
>
>    /// Interpolate vertex values from dof values
> @@ -937,6 +1391,7 @@
>      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)
> @@ -978,7 +1433,7 @@
>    /// Return a string identifying the dof map
>    virtual const char* signature() const
>    {
> -    return "FFC dofmap for FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)";
> +    return "FFC dofmap for FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1)";
>    }
>
>    /// Return true iff mesh entities of topological dimension d are needed
> @@ -1001,6 +1456,11 @@
>          return false;
>          break;
>        }
> +    case 3:
> +      {
> +        return false;
> +        break;
> +      }
>      }
>
>      return false;
> @@ -1035,25 +1495,25 @@
>    /// Return the dimension of the local finite element function space for a cell
>    virtual unsigned int local_dimension(const ufc::cell& c) const
>    {
> -    return 3;
> +    return 4;
>    }
>
>    /// Return the maximum dimension of the local finite element function space
>    virtual unsigned int max_local_dimension() const
>    {
> -    return 3;
> +    return 4;
>    }
>
>    // Return the geometric dimension of the coordinates this dof map provides
>    virtual unsigned int geometric_dimension() const
>    {
> -    return 2;
> +    return 3;
>    }
>
>    /// Return the number of dofs on each cell facet
>    virtual unsigned int num_facet_dofs() const
>    {
> -    return 2;
> +    return 3;
>    }
>
>    /// Return the number of dofs associated with each cell entity of dimension d
> @@ -1076,6 +1536,11 @@
>          return 0;
>          break;
>        }
> +    case 3:
> +      {
> +        return 0;
> +        break;
> +      }
>      }
>
>      return 0;
> @@ -1089,6 +1554,7 @@
>      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];
>    }
>
>    /// Tabulate the local-to-local mapping from facet dofs to cell dofs
> @@ -1101,18 +1567,28 @@
>        {
>          dofs[0] = 1;
>        dofs[1] = 2;
> +      dofs[2] = 3;
>          break;
>        }
>      case 1:
>        {
>          dofs[0] = 0;
>        dofs[1] = 2;
> +      dofs[2] = 3;
>          break;
>        }
>      case 2:
>        {
>          dofs[0] = 0;
>        dofs[1] = 1;
> +      dofs[2] = 3;
> +        break;
> +      }
> +    case 3:
> +      {
> +        dofs[0] = 0;
> +      dofs[1] = 1;
> +      dofs[2] = 2;
>          break;
>        }
>      }
> @@ -1123,18 +1599,18 @@
>    virtual void tabulate_entity_dofs(unsigned int* dofs,
>                                      unsigned int d, unsigned int i) const
>    {
> -    if (d > 2)
> +    if (d > 3)
>      {
> -    throw std::runtime_error("d is larger than dimension (2)");
> +    throw std::runtime_error("d is larger than dimension (3)");
>      }
>
>      switch (d)
>      {
>      case 0:
>        {
> -        if (i > 2)
> +        if (i > 3)
>        {
> -      throw std::runtime_error("i is larger than number of entities (2)");
> +      throw std::runtime_error("i is larger than number of entities (3)");
>        }
>
>        switch (i)
> @@ -1154,6 +1630,11 @@
>            dofs[0] = 2;
>            break;
>          }
> +      case 3:
> +        {
> +          dofs[0] = 3;
> +          break;
> +        }
>        }
>
>          break;
> @@ -1168,6 +1649,11 @@
>
>          break;
>        }
> +    case 3:
> +      {
> +
> +        break;
> +      }
>      }
>
>    }
> @@ -1180,10 +1666,16 @@
>
>      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];
>    }
>
>    /// Return the number of sub dof maps (for a mixed element)
> @@ -1225,10 +1717,10 @@
>                                 const double * const * w,
>                                 const ufc::cell& c) const
>    {
> -    // Number of operations (multiply-add pairs) for Jacobian data:      11
> -    // Number of operations (multiply-add pairs) for geometry tensor:    8
> -    // Number of operations (multiply-add pairs) for tensor contraction: 11
> -    // Total number of operations (multiply-add pairs):                  30
> +    // Number of operations (multiply-add pairs) for Jacobian data:      32
> +    // Number of operations (multiply-add pairs) for geometry tensor:    27
> +    // Number of operations (multiply-add pairs) for tensor contraction: 28
> +    // Total number of operations (multiply-add pairs):                  87
>
>      // Extract vertex coordinates
>      const double * const * x = c.coordinates;
> @@ -1236,37 +1728,70 @@
>      // 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*J_11 - J_01*J_10;
> +    double detJ = J_00*d_00 + J_10*d_10 + J_20*d_20;
>
>      // Compute inverse of Jacobian
> -    const double K_00 =  J_11 / detJ;
> -    const double K_01 = -J_01 / detJ;
> -    const double K_10 = -J_10 / detJ;
> -    const double K_11 =  J_00 / detJ;
> +    const double K_00 = d_00 / detJ;
> +    const double K_01 = d_10 / detJ;
> +    const double K_02 = d_20 / detJ;
> +    const double K_10 = d_01 / detJ;
> +    const double K_11 = d_11 / detJ;
> +    const double K_12 = d_21 / detJ;
> +    const double K_20 = d_02 / detJ;
> +    const double K_21 = d_12 / detJ;
> +    const double K_22 = d_22 / detJ;
>
>      // Set scale factor
>      const double det = std::abs(detJ);
>
>      // Compute geometry tensor
> -    const double G0_0_0 = det*(K_00*K_00 + K_01*K_01);
> -    const double G0_0_1 = det*(K_00*K_10 + K_01*K_11);
> -    const double G0_1_0 = det*(K_10*K_00 + K_11*K_01);
> -    const double G0_1_1 = det*(K_10*K_10 + K_11*K_11);
> +    const double G0_0_0 = det*(K_00*K_00 + K_01*K_01 + K_02*K_02);
> +    const double G0_0_1 = det*(K_00*K_10 + K_01*K_11 + K_02*K_12);
> +    const double G0_0_2 = det*(K_00*K_20 + K_01*K_21 + K_02*K_22);
> +    const double G0_1_0 = det*(K_10*K_00 + K_11*K_01 + K_12*K_02);
> +    const double G0_1_1 = det*(K_10*K_10 + K_11*K_11 + K_12*K_12);
> +    const double G0_1_2 = det*(K_10*K_20 + K_11*K_21 + K_12*K_22);
> +    const double G0_2_0 = det*(K_20*K_00 + K_21*K_01 + K_22*K_02);
> +    const double G0_2_1 = det*(K_20*K_10 + K_21*K_11 + K_22*K_12);
> +    const double G0_2_2 = det*(K_20*K_20 + K_21*K_21 + K_22*K_22);
>
>      // Compute element tensor
> -    A[0] = 0.500000000000000*G0_0_0 + 0.500000000000000*G0_0_1 + 0.500000000000000*G0_1_0 + 0.500000000000000*G0_1_1;
> -    A[1] = -0.500000000000000*G0_0_0 - 0.500000000000000*G0_1_0;
> -    A[2] = -0.500000000000000*G0_0_1 - 0.500000000000000*G0_1_1;
> -    A[3] = -0.500000000000000*G0_0_0 - 0.500000000000000*G0_0_1;
> -    A[4] = 0.500000000000000*G0_0_0;
> -    A[5] = 0.500000000000000*G0_0_1;
> -    A[6] = -0.500000000000000*G0_1_0 - 0.500000000000000*G0_1_1;
> -    A[7] = 0.500000000000000*G0_1_0;
> -    A[8] = 0.500000000000000*G0_1_1;
> +    A[0] = 0.166666666666666*G0_0_0 + 0.166666666666666*G0_0_1 + 0.166666666666666*G0_0_2 + 0.166666666666666*G0_1_0 + 0.166666666666666*G0_1_1 + 0.166666666666666*G0_1_2 + 0.166666666666666*G0_2_0 + 0.166666666666666*G0_2_1 + 0.166666666666666*G0_2_2;
> +    A[1] = -0.166666666666666*G0_0_0 - 0.166666666666666*G0_1_0 - 0.166666666666666*G0_2_0;
> +    A[2] = -0.166666666666666*G0_0_1 - 0.166666666666666*G0_1_1 - 0.166666666666666*G0_2_1;
> +    A[3] = -0.166666666666666*G0_0_2 - 0.166666666666666*G0_1_2 - 0.166666666666666*G0_2_2;
> +    A[4] = -0.166666666666666*G0_0_0 - 0.166666666666666*G0_0_1 - 0.166666666666666*G0_0_2;
> +    A[5] = 0.166666666666666*G0_0_0;
> +    A[6] = 0.166666666666666*G0_0_1;
> +    A[7] = 0.166666666666666*G0_0_2;
> +    A[8] = -0.166666666666666*G0_1_0 - 0.166666666666666*G0_1_1 - 0.166666666666666*G0_1_2;
> +    A[9] = 0.166666666666666*G0_1_0;
> +    A[10] = 0.166666666666667*G0_1_1;
> +    A[11] = 0.166666666666666*G0_1_2;
> +    A[12] = -0.166666666666666*G0_2_0 - 0.166666666666666*G0_2_1 - 0.166666666666666*G0_2_2;
> +    A[13] = 0.166666666666666*G0_2_0;
> +    A[14] = 0.166666666666666*G0_2_1;
> +    A[15] = 0.166666666666666*G0_2_2;
>    }
>
>  };
> @@ -1305,7 +1830,7 @@
>    /// Return a string identifying the form
>    virtual const char* signature() const
>    {
> -    return "Form([Integral(IndexSum(Product(Indexed(ComponentTensor(SpatialDerivative(Argument(FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), 0), MultiIndex((Index(0),), {Index(0): 2})), MultiIndex((Index(0),), {Index(0): 2})), MultiIndex((Index(1),), {Index(1): 2})), Indexed(ComponentTensor(SpatialDerivative(Argument(FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), 1), MultiIndex((Index(2),), {Index(2): 2})), MultiIndex((Index(2),), {Index(2): 2})), MultiIndex((Index(1),), {Index(1): 2}))), MultiIndex((Index(1),), {Index(1): 2})), Measure('cell', 0, None))])";
> +    return "Form([Integral(IndexSum(Product(Indexed(ComponentTensor(SpatialDerivative(Argument(FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1), 0), MultiIndex((Index(0),), {Index(0): 3})), MultiIndex((Index(0),), {Index(0): 3})), MultiIndex((Index(1),), {Index(1): 3})), Indexed(ComponentTensor(SpatialDerivative(Argument(FiniteElement('Lagrange', Cell('tetrahedron', 1, Space(3)), 1), 1), MultiIndex((Index(2),), {Index(2): 3})), MultiIndex((Index(2),), {Index(2): 3})), MultiIndex((Index(1),), {Index(1): 3}))), MultiIndex((Index(1),), {Index(1): 3})), Measure('cell', 0, None))])";
>    }
>
>    /// Return the rank of the global tensor (r)
>
> === modified file 'source/demos/la/eigenvalue/cpp/StiffnessMatrix.ufl'
> --- source/demos/la/eigenvalue/cpp/StiffnessMatrix.ufl	2010-09-01 15:13:40 +0000
> +++ source/demos/la/eigenvalue/cpp/StiffnessMatrix.ufl	2010-09-06 15:40:49 +0000
> @@ -2,11 +2,11 @@
>  # Licensed under the GNU LGPL Version 2.1
>  #
>  # First added:  2005-06-05
> -# Last changed: 2006-03-28
> +# Last changed: 2010-09-05
>  #
>  # The bilinear form for a stiffness matrix (Poisson).
>
> -element = FiniteElement("Lagrange", "triangle", 1)
> +element = FiniteElement("Lagrange", "tetrahedron", 1)
>
>  v = TestFunction(element)
>  u = TrialFunction(element)
>
> === modified file 'source/demos/la/eigenvalue/cpp/main.cpp'
> --- source/demos/la/eigenvalue/cpp/main.cpp	2010-09-01 15:17:46 +0000
> +++ source/demos/la/eigenvalue/cpp/main.cpp	2010-09-06 15:40:49 +0000
> @@ -2,9 +2,10 @@
>  // Licensed under the GNU LGPL Version 2.1.
>  //
>  // Modified by Anders Logg, 2008.
> +// Modified by Marie E. Rognes, 2010.
>  //
>  // First added:  2007-03-08
> -// Last changed: 2010-01-02
> +// Last changed: 2010-09-05
>  //
>  // This simple program illustrates the use of the SLEPc eigenvalue solver.
>
> @@ -21,34 +22,36 @@
>    parameters["linear_algebra_backend"] = "PETSc";
>
>    // Create mesh
> -  UnitSquare mesh(64, 64);
> +  Mesh mesh("box_with_dent.xml.gz");
>
> -  // Build stiftness matrix
> +  // Build stiffness matrix
>    Matrix A;
>    StiffnessMatrix::FunctionSpace V(mesh);
>    StiffnessMatrix::BilinearForm a(V, V);
>    assemble(A, a);
>
> -  cout << A << endl;
> -
>    // Get PETSc matrix
>    PETScMatrix& AA(A.down_cast<PETScMatrix>());
>
> -  // Compute the first n eigenvalues
> -  unsigned int n = 10;
> +  // Create eigensolver
>    SLEPcEigenSolver esolver;
> -  esolver.parameters["spectrum"] = "largest magnitude";
> -  esolver.solve(AA, n);
> -
> -  cout << "Solver converted in " << esolver.get_iteration_number() << " iterations" << endl;
> -
> -  // Display eigenvalues
> -  for (unsigned int i = 0; i < n; i++)
> -  {
> -    double lr, lc;
> -    esolver.get_eigenvalue(lr, lc, i);
> -    cout << "Eigenvalue " << i << ": " << lr << endl;
> -  }
> +
> +  // Compute all eigenvalues of A x = \lambda x
> +  esolver.solve(AA);
> +
> +  // Extract largest (first) eigenpair
> +  double r, c;
> +  PETScVector rx(A.size(1));
> +  PETScVector cx(A.size(1));
> +  esolver.get_eigenpair(r, c, rx, cx, 0);
> +
> +  std::cout << "Largest eigenvalue: " << r << std::endl;
> +
> +  // Initialize function with eigenvector
> +  Function u(V, rx);
> +
> +  // Plot eigenfunction
> +  plot(u);
>
>    #else
>
>
> === modified file 'source/demos/pde/biharmonic/python/demo.py'
> --- source/demos/pde/biharmonic/python/demo.py	2010-09-01 20:32:22 +0000
> +++ source/demos/pde/biharmonic/python/demo.py	2010-09-06 15:40:49 +0000
> @@ -52,7 +52,7 @@
>  h = CellSize(mesh)
>  h_avg = (h('+') + h('-'))/2.0
>  n = FacetNormal(mesh)
> -f = Source(V)
> +f = Source()
>
>  # Penalty parameter
>  alpha = Constant(8.0)
>
> === modified file 'source/demos/pde/biharmonic/python/documentation.rst'
> --- source/demos/pde/biharmonic/python/documentation.rst	2010-09-01 22:59:53 +0000
> +++ source/demos/pde/biharmonic/python/documentation.rst	2010-09-06 15:40:49 +0000
> @@ -85,7 +85,7 @@
>      h = CellSize(mesh)
>      h_avg = (h('+') + h('-'))/2.0
>      n = FacetNormal(mesh)
> -    f = Source(V)
> +    f = Source()
>
>      # Penalty parameter
>      alpha = Constant(8.0)
>
> === modified file 'source/demos/pde/cahn-hilliard/python/demo.py'
> --- source/demos/pde/cahn-hilliard/python/demo.py	2010-09-01 20:32:22 +0000
> +++ source/demos/pde/cahn-hilliard/python/demo.py	2010-09-06 15:40:49 +0000
> @@ -18,8 +18,8 @@
>      def eval(self, values, x):
>          values[0] = 0.63 + 0.02*(0.5 - random.random())
>          values[1] = 0.0
> -    def dim(self):
> -        return 2
> +    def value_shape(self):
> +        return (2,)
>
>  # Class for interfacing with the Newton solver
>  class CahnHilliardEquation(NonlinearProblem):
>
> === modified file 'source/demos/pde/cahn-hilliard/python/documentation.rst'
> --- source/demos/pde/cahn-hilliard/python/documentation.rst	2010-09-01 20:10:55 +0000
> +++ source/demos/pde/cahn-hilliard/python/documentation.rst	2010-09-06 15:40:49 +0000
> @@ -34,8 +34,8 @@
>          def eval(self, values, x):
>              values[0] = 0.63 + 0.02*(0.5 - random.random())
>              values[1] = 0.0
> -        def dim(self):
> -            return 2
> +        def value_shape(self):
> +            return (2,)
>
>  It is a subclass of ``Expression``. In the constructor (``__init__``),
>  the random number generator is seeded. If the program is run in
> @@ -43,8 +43,8 @@
>  number to ensure a different sequence of numbers on each process.  The
>  function ``eval`` returns values for a function of dimension two.  For
>  the first component of the function, a randomized value is returned.
> -The function ``dim`` declares that the ``Expression`` is of dimension
> -two.
> +The method ``value_shape`` declares that the ``Expression`` is vector
> +valued with dimension two.
>
>  .. index:: NonlinearProblem
>
>
> === modified file 'source/demos/pde/mixed-poisson/python/demo.py'
> --- source/demos/pde/mixed-poisson/python/demo.py	2010-09-01 15:17:46 +0000
> +++ source/demos/pde/mixed-poisson/python/demo.py	2010-09-06 15:40:49 +0000
> @@ -53,10 +53,9 @@
>          g = sin(5*data.x()[0])
>          values[0] = g*data.normal()[0]
>          values[1] = g*data.normal()[1]
> -    def rank(self):
> -        return 1
> -    def dim(self):
> -        return 2
> +    def value_shape(self):
> +        return (2,)
> +
>  G = BoundarySource()
>
>  # Define essential boundary
>
> === modified file 'source/demos/pde/mixed-poisson/python/documentation.rst'
> --- source/demos/pde/mixed-poisson/python/documentation.rst	2010-08-31 21:08:44 +0000
> +++ source/demos/pde/mixed-poisson/python/documentation.rst	2010-09-06 15:40:49 +0000
> @@ -104,7 +104,7 @@
>  ``Expression`` class. Overloading the ``eval_data`` method (instead of
>  the usual ``eval``) allows us to extract more geometry information
>  such as the facet normals. Since this is a vector-valued expression,
> -the methods ``rank`` and ``dim`` must also be specified.
> +we need to overload the ``value_shape`` method.
>
>  .. index:: Expression
>
> @@ -116,10 +116,9 @@
>              g = sin(5*data.x()[0])
>              values[0] = g*data.normal()[0]
>              values[1] = g*data.normal()[1]
> -        def rank(self):
> -            return 1
> -        def dim(self):
> -            return 2
> +        def value_shape(self):
> +            return (2,)
> +
>      G = BoundarySource()
>
>  Specifying the relevant part of the boundary can be done as for the
>
> === modified file 'source/demos/undocumented/dielectric/python/demo.py'
> --- source/demos/undocumented/dielectric/python/demo.py	2010-09-01 15:13:40 +0000
> +++ source/demos/undocumented/dielectric/python/demo.py	2010-09-06 15:40:49 +0000
> @@ -12,7 +12,7 @@
>  #     u(x,y)      = V  for y = 0
>
>  __author__ = "Kristen Kaasbjerg (cosby@xxxxxxxxx)"
> -__date__ = "2008-02-14 -- 2009-10-07"
> +__date__ = "2008-02-14 -- 2010-09-05"
>  __copyright__ = ""
>  __license__  = "GNU LGPL Version 2.1"
>
> @@ -104,12 +104,12 @@
>  v = TestFunction(V2)
>  u = TrialFunction(V2)
>  f = Constant(0.0)
> -b = Coefficient(V0)
> +b = Coefficient()
>  a = b*dot(grad(v), grad(u))*dx
>  L = v*f*dx
>
>  # Define boundary condition
> -u0 = DirichletFunction(V2)
> +u0 = DirichletFunction()
>  bc = DirichletBC(V2, u0, DirichletBoundary())
>
>  # Solve PDE and plot solution
> @@ -123,7 +123,7 @@
>  # because it is an interpolation of the exact solution
>  # in the finite element space!
>  Pk = FunctionSpace(mesh, "CG", 5)
> -exact = Exact(Pk)
> +exact = Exact()
>
>  e = u - exact
>  L2_norm = e*e*dx
>
> === modified file 'source/demos/undocumented/elasticity/python/demo.py'
> --- source/demos/undocumented/elasticity/python/demo.py	2010-09-01 22:59:53 +0000
> +++ source/demos/undocumented/elasticity/python/demo.py	2010-09-06 15:40:49 +0000
> @@ -3,7 +3,7 @@
>  for a gear clamped at two of its ends and twisted 30 degrees."""
>
>  __author__ = "Kristian B. Oelgaard (k.b.oelgaard@xxxxxxxxxx)"
> -__date__ = "2007-11-14 -- 2009-10-07"
> +__date__ = "2007-11-14 -- 2010-09-05"
>  __copyright__ = "Copyright (C) 2007 Kristian B. Oelgaard"
>  __license__  = "GNU LGPL Version 2.1"
>
> @@ -45,8 +45,8 @@
>          values[1] = y - x[1]
>          values[2] = z - x[2]
>
> -    def dim(self):
> -        return 3
> +    def value_shape(self):
> +        return (3,)
>
>  # Sub domain for rotation at right end
>  def right(x, on_boundary):
>
> === modified file 'source/demos/undocumented/elastodynamics/python/demo.py'
> --- source/demos/undocumented/elastodynamics/python/demo.py	2010-09-01 22:59:53 +0000
> +++ source/demos/undocumented/elastodynamics/python/demo.py	2010-09-06 15:40:49 +0000
> @@ -41,23 +41,22 @@
>          self.t   = t
>          self.dt  = dt
>          self.old = old
> +
>      def eval(self, values, x):
>
>          # 'Shift' time for n-1 values
> -        t_tmp = float(self.t)
> +        t_tmp = self.t
>          if self.old and t > 0.0:
>              t_tmp -= self.dt
>
>          cutoff_t = 10.0*1.0/32.0;
> -        if t_tmp < cutoff_t:
> -            values[0] = 1.0*t_tmp/cutoff_t
> -            values[1] = 0.0
> -        else:
> -            values[0] = 1.0;
> -            values[1] = 0.0;
> -
> -    def dim(self):
> -        return 2
> +        weight = t_tmp/cutoff_t if t_tmp < cutoff_t else 1.0
> +
> +        values[0] = 1.0*weight
> +        values[1] = 0.0
> +
> +    def value_shape(self):
> +        return (2,)
>
>  # Sub domain for clamp at left end
>  def left(x, on_boundary):
> @@ -93,7 +92,7 @@
>  beta    = 0.36
>  gamma   = 0.7
>  dt      = 1.0/32.0
> -t       = Time(0.0)
> +t       = 0.0
>  T       = 10*dt
>
>  # Some useful factors
> @@ -144,11 +143,13 @@
>  problem = VariationalProblem(a, L, bcs=bc, exterior_facet_domains=boundary_subdomains)
>
>  vtk_file = File("elasticity.pvd")
> -while t < T:
> +while t <= T:
>
>      t += dt
>      print "Time: ", t
>
> +    p.t = t
> +    p0.t = t
>      # Solve and update functions
>      u = problem.solve()
>      update(u, u0, v0, a0, beta, gamma, dt)
>
> === modified file 'source/demos/undocumented/periodic/python/demo.py'
> --- source/demos/undocumented/periodic/python/demo.py	2010-09-01 15:13:40 +0000
> +++ source/demos/undocumented/periodic/python/demo.py	2010-09-06 15:40:49 +0000
> @@ -8,7 +8,7 @@
>  # Original implementation: ../cpp/main.cpp by Anders Logg
>  #
>  __author__ = "Kristian B. Oelgaard (k.b.oelgaard@xxxxxxxxxx)"
> -__date__ = "2007-11-15 -- 2009-10-07"
> +__date__ = "2007-11-15 -- 2010-09-05"
>  __copyright__ = "Copyright (C) 2007 Kristian B. Oelgaard"
>  __license__  = "GNU LGPL Version 2.1"
>
> @@ -55,7 +55,7 @@
>  # Define variational problem
>  v = TestFunction(V)
>  u = TrialFunction(V)
> -f = Source(V)
> +f = Source()
>
>  a = dot(grad(v), grad(u))*dx
>  L = v*f*dx
>
> === modified file 'source/demos/undocumented/sym-dirichlet-bc/python/demo.py'
> --- source/demos/undocumented/sym-dirichlet-bc/python/demo.py	2010-09-01 15:13:40 +0000
> +++ source/demos/undocumented/sym-dirichlet-bc/python/demo.py	2010-09-06 15:40:49 +0000
> @@ -4,7 +4,7 @@
>  # Modified by Kristian Oelgaard, 2008
>
>  __author__ = "Kent-Andre Mardal (kent-and@xxxxxxxxx)"
> -__date__ = "2008-08-13 -- 2009-10-07"
> +__date__ = "2008-08-13 -- 2010-09-05"
>  __copyright__ = "Copyright (C) 2008 Kent-Andre Mardal"
>  __license__  = "GNU LGPL Version 2.1"
>
> @@ -37,8 +37,8 @@
>  # Define variational problem
>  v = TestFunction(V)
>  u = TrialFunction(V)
> -f = Source(V)
> -g = Flux(V)
> +f = Source()
> +g = Flux()
>
>  a = inner(grad(v), grad(u))*dx
>  L = v*f*dx + v*g*ds
>
> === modified file 'source/programmers-reference/cpp/mesh/index.rst'
> --- source/programmers-reference/cpp/mesh/index.rst	2010-08-30 13:52:07 +0000
> +++ source/programmers-reference/cpp/mesh/index.rst	2010-09-06 15:40:49 +0000
> @@ -34,7 +34,6 @@
>      MeshPrimitive
>      MeshTopology
>      Point
> -    Point
>      PrimitiveIntersector
>      PrimitiveTraits
>      Rectangle
>
> # Begin bundle
> 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

> _______________________________________________
> Mailing list: https://launchpad.net/~fenics
> Post to     : fenics@xxxxxxxxxxxxxxxxxxx
> Unsubscribe : https://launchpad.net/~fenics
> More help   : https://help.launchpad.net/ListHelp


--
Anders



References